1#[doc(hidden)]
2#[macro_export]
3macro_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;