fltk/macros/
image.rs

1#[doc(hidden)]
2#[macro_export]
3/// Implements ImageExt
4macro_rules! impl_image_ext {
5    ($name: ident, $flname: ident) => {
6        #[cfg(not(feature = "single-threaded"))]
7        unsafe impl Sync for $name {}
8        #[cfg(not(feature = "single-threaded"))]
9        unsafe impl Send for $name {}
10
11        impl PartialEq for $name {
12            fn eq(&self, other: &Self) -> bool {
13                self.inner == other.inner
14            }
15        }
16
17        impl Eq for $name {}
18
19        impl Clone for $name {
20            fn clone(&self) -> Self {
21                assert!(!self.was_deleted());
22                $name {
23                    inner: ImageRC::clone(&self.inner),
24                }
25            }
26        }
27
28        paste::paste! {
29            impl Drop for $name {
30                fn drop(&mut self) {
31                    if std::any::type_name::<$name>() != std::any::type_name::<$crate::image::Image>() {
32                        if !self.was_deleted() {
33                            if ImageRC::strong_count(&self.inner) == 1 {
34                                unsafe {
35                                    [<$flname _delete>](*self.inner);
36                                }
37                            }
38                        }
39                    }
40                }
41            }
42
43            unsafe impl ImageExt for $name {
44                fn copy(&self) -> Self {
45                    assert!(!self.was_deleted());
46                    unsafe {
47                        let img = [<$flname _copy>](*self.inner);
48                        assert!(!img.is_null());
49                        $name {
50                            inner: ImageRC::from(img),
51                        }
52                    }
53                }
54
55                fn copy_sized(&self, w: i32, h: i32) -> Self {
56                    assert!(!self.was_deleted());
57                    unsafe {
58                        let img = [<$flname _copy_sized>](*self.inner, w, h);
59                        assert!(!img.is_null());
60                        $name {
61                            inner: ImageRC::from(img),
62                        }
63                    }
64                }
65
66                fn draw(&mut self, arg2: i32, arg3: i32, arg4: i32, arg5: i32) {
67                    assert!(!self.was_deleted());
68                    unsafe { [<$flname _draw>](*self.inner, arg2, arg3, arg4, arg5) }
69                }
70
71                fn draw_ext(&mut self, arg2: i32, arg3: i32, arg4: i32, arg5: i32, cx: i32, cy: i32) {
72                    assert!(!self.was_deleted());
73                    unsafe {
74                        [<$flname _draw_ext>](*self.inner, arg2, arg3, arg4, arg5, cx, cy)
75                    }
76                }
77
78                fn w(&self) -> i32 {
79                    assert!(!self.was_deleted());
80                    unsafe { [<$flname _width>](*self.inner) }
81                }
82
83                fn h(&self) -> i32 {
84                    assert!(!self.was_deleted());
85                    unsafe { [<$flname _height>](*self.inner) }
86                }
87
88                fn as_image_ptr(&self) -> *mut fltk_sys::image::Fl_Image {
89                    assert!(!self.was_deleted());
90                    let ptr = std::rc::Rc::into_raw(self.inner.clone());
91                    unsafe {
92                        *ptr as _
93                    }
94                }
95
96                unsafe fn from_image_ptr(ptr: *mut fltk_sys::image::Fl_Image) -> Self {
97                    assert!(!ptr.is_null());
98                    $name {
99                        inner: ImageRC::from(ptr as *mut $flname),
100                    }
101                }
102
103                fn as_rgb_data(&self) -> Vec<u8> {
104                    assert!(!self.was_deleted());
105                    unsafe {
106                        let ptr = [<$flname _data>](*self.inner);
107                        assert!(!ptr.is_null());
108                        assert!(!(*ptr).is_null());
109                        let cnt = self.data_w() * self.data_h() * self.depth() as i32;
110                        let ret: &[u8] = std::slice::from_raw_parts(*ptr as *const u8, cnt as usize);
111                        ret.to_vec()
112                    }
113                }
114
115                fn as_rgb_image(&self) -> Result<$crate::image::RgbImage, FltkError> {
116                    assert!(!self.was_deleted());
117                    if self.count() != 1 {
118                        Err(FltkError::Internal(FltkErrorKind::ImageFormatError))
119                    } else {
120                        let data = self.as_rgb_data();
121                        let mut img = $crate::image::RgbImage::new(&data, self.data_w(), self.data_h(), self.depth())?;
122                        img.scale(self.w(), self.h(), false, true);
123                        Ok(img)
124                    }
125                }
126
127                fn scale(&mut self, width: i32, height: i32, proportional: bool, can_expand: bool) {
128                    assert!(!self.was_deleted());
129                    let width = if width < 1 {
130                        1
131                    } else {
132                        width
133                    };
134                    let height = if height < 1 {
135                        1
136                    } else {
137                        height
138                    };
139                    unsafe {
140                        [<$flname _scale>](
141                            *self.inner,
142                            width,
143                            height,
144                            proportional as i32,
145                            can_expand as i32,
146                        )
147                    }
148                }
149
150                fn count(&self) -> i32 {
151                    assert!(!self.was_deleted());
152                    unsafe { [<$flname _count>](*self.inner) }
153                }
154
155                fn data_w(&self) -> i32 {
156                    assert!(!self.was_deleted());
157                    unsafe { [<$flname _data_w>](*self.inner) }
158                }
159
160                fn data_h(&self) -> i32 {
161                    assert!(!self.was_deleted());
162                    unsafe { [<$flname _data_h>](*self.inner) }
163                }
164
165                fn depth(&self) -> $crate::enums::ColorDepth {
166                    assert!(!self.was_deleted());
167                    unsafe { std::mem::transmute([<$flname _d>](*self.inner) as u8) }
168                }
169
170                fn ld(&self) -> i32 {
171                    assert!(!self.was_deleted());
172                    unsafe { [<$flname _ld>](*self.inner) }
173                }
174
175                fn inactive(&mut self) {
176                    assert!(!self.was_deleted());
177                    unsafe { [<$flname _inactive>](*self.inner) }
178                }
179
180                unsafe fn delete(img: Self) { unsafe {
181                    assert!(!img.inner.is_null());
182                    [<$flname _delete>](*img.inner);
183                }}
184
185                fn was_deleted(&self) -> bool {
186                    self.inner.is_null()
187                }
188
189                unsafe fn into_image<I: ImageExt>(self) -> I { unsafe {
190                    let ptr = ImageRC::into_raw(ImageRC::clone(&self.inner));
191                    ImageRC::increment_strong_count(ptr);
192                    let image = ImageRC::from_raw(ptr);
193                    I::from_image_ptr(*image as *mut _)
194                }}
195            }
196        }
197    };
198}
199
200pub use impl_image_ext;