1use fltk_egui::{
2 egui::{Image, TextureId, Vec2},
3 Painter,
4};
5
6#[cfg(any(
7 feature = "png",
8 feature = "jpeg",
9 feature = "jpeg_rayon",
10 feature = "bmp",
11 feature = "ico",
12 feature = "gif",
13 feature = "webp",
14 feature = "tga",
15 feature = "pnm",
16 feature = "hdr",
17 feature = "dxt",
18 feature = "dds",
19 feature = "farbfeld"
20))]
21use image::{GenericImageView, ImageError};
22
23#[cfg(any(
24 feature = "svg",
25 feature = "png",
26 feature = "jpeg",
27 feature = "jpeg_rayon",
28 feature = "bmp",
29 feature = "ico",
30 feature = "gif",
31 feature = "webp",
32 feature = "tga",
33 feature = "pnm",
34 feature = "hdr",
35 feature = "dxt",
36 feature = "dds",
37 feature = "farbfeld"
38))]
39pub struct ImageWidget {
40 texture_id: TextureId,
41 _size: Vec2,
42}
43
44#[cfg(any(
45 feature = "png",
46 feature = "jpeg",
47 feature = "jpeg_rayon",
48 feature = "bmp",
49 feature = "ico",
50 feature = "gif",
51 feature = "webp",
52 feature = "tga",
53 feature = "pnm",
54 feature = "hdr",
55 feature = "dxt",
56 feature = "dds",
57 feature = "farbfeld"
58))]
59impl Clone for ImageWidget {
60 fn clone(&self) -> Self {
61 Self {
62 texture_id: self.texture_id.clone(),
63 _size: self._size.clone(),
64 }
65 }
66}
67
68#[cfg(any(
69 feature = "png",
70 feature = "jpeg",
71 feature = "jpeg_rayon",
72 feature = "bmp",
73 feature = "ico",
74 feature = "gif",
75 feature = "webp",
76 feature = "tga",
77 feature = "pnm",
78 feature = "hdr",
79 feature = "dxt",
80 feature = "dds",
81 feature = "farbfeld"
82))]
83impl Drop for ImageWidget {
84 fn drop(&mut self) {}
85}
86
87#[cfg(any(
88 feature = "png",
89 feature = "jpeg",
90 feature = "jpeg_rayon",
91 feature = "bmp",
92 feature = "ico",
93 feature = "gif",
94 feature = "webp",
95 feature = "tga",
96 feature = "pnm",
97 feature = "hdr",
98 feature = "dxt",
99 feature = "dds",
100 feature = "farbfeld"
101))]
102impl ImageWidget {
103 pub fn texture_id(&self) -> TextureId {
104 self.texture_id
105 }
106
107 pub fn size(&self) -> Vec2 {
108 self._size
109 }
110
111 pub fn widget(&self) -> Image {
112 Image::new(self.texture_id, self.size())
113 }
114
115 pub fn resize(&mut self, x: f32, y: f32) {
116 self._size.x = x;
117 self._size.y = y
118 }
119
120 pub fn set_size_x(&mut self, x: f32) {
121 self._size.x = x;
122 }
123
124 pub fn set_size_y(&mut self, y: f32) {
125 self._size.y = y
126 }
127
128 pub fn new(painter: &mut Painter, bytes: &[u8]) -> Result<Self, ImageError> {
130 let pixels;
131 let size;
132 {
133 let dyn_image = image::load_from_memory(bytes)?;
134 size = (dyn_image.width() as usize, dyn_image.height() as usize);
135 pixels = dyn_image.into_rgba8().to_vec();
136 }
137 let tex = painter.new_user_texture_rgba8(size, pixels, true);
138 let feimage = Self {
139 texture_id: tex,
140 _size: Vec2::from((size.0 as f32, size.1 as f32)),
141 };
142 Ok(feimage)
143 }
144
145 pub fn update_image(&mut self, painter: &mut Painter, bytes: &[u8]) -> Result<(), ImageError> {
147 let pixels;
148 let size;
149 {
150 let dyn_image = image::load_from_memory(bytes)?;
151 size = (dyn_image.width() as usize, dyn_image.height() as usize);
152 pixels = dyn_image.into_rgba8().to_vec();
153 }
154 painter.update_user_texture_rgba8_data(self.texture_id, pixels);
155 self._size = Vec2::from((size.0 as f32, size.1 as f32));
156 Ok(())
157 }
158}
159
160#[cfg(any(
161 feature = "png",
162 feature = "jpeg",
163 feature = "jpeg_rayon",
164 feature = "bmp",
165 feature = "ico",
166 feature = "gif",
167 feature = "webp",
168 feature = "tga",
169 feature = "pnm",
170 feature = "hdr",
171 feature = "dxt",
172 feature = "dds",
173 feature = "farbfeld"
174))]
175impl Into<SVGWidget> for ImageWidget {
176 fn into(self) -> SVGWidget {
177 SVGWidget {
178 texture_id: self.texture_id,
179 _size: self._size,
180 }
181 }
182}
183
184#[cfg(any(
185 feature = "png",
186 feature = "jpeg",
187 feature = "jpeg_rayon",
188 feature = "bmp",
189 feature = "ico",
190 feature = "gif",
191 feature = "webp",
192 feature = "tga",
193 feature = "pnm",
194 feature = "hdr",
195 feature = "dxt",
196 feature = "dds",
197 feature = "farbfeld"
198))]
199impl From<SVGWidget> for ImageWidget {
200 fn from(t: SVGWidget) -> ImageWidget {
201 ImageWidget {
202 texture_id: t.texture_id,
203 _size: t._size,
204 }
205 }
206}
207
208#[cfg(feature = "svg")]
209use resvg::render;
210#[cfg(feature = "svg")]
211use std::io::{Error, ErrorKind};
212#[cfg(feature = "svg")]
213use tiny_skia::Pixmap;
214#[cfg(feature = "svg")]
215pub use usvg::Options;
216#[cfg(feature = "svg")]
217use usvg::{OptionsRef, Tree};
218
219#[cfg(any(
220 feature = "svg",
221 feature = "png",
222 feature = "jpeg",
223 feature = "jpeg_rayon",
224 feature = "bmp",
225 feature = "ico",
226 feature = "gif",
227 feature = "webp",
228 feature = "tga",
229 feature = "pnm",
230 feature = "hdr",
231 feature = "dxt",
232 feature = "dds",
233 feature = "farbfeld"
234))]
235pub struct SVGWidget {
236 texture_id: TextureId,
237 _size: Vec2,
238}
239
240#[cfg(feature = "svg")]
241impl Clone for SVGWidget {
242 fn clone(&self) -> Self {
243 Self {
244 texture_id: self.texture_id.clone(),
245 _size: self._size.clone(),
246 }
247 }
248}
249
250#[cfg(feature = "svg")]
251impl Drop for SVGWidget {
252 fn drop(&mut self) {}
253}
254
255#[cfg(feature = "svg")]
256impl SVGWidget {
257 pub fn texture_id(&self) -> TextureId {
258 self.texture_id
259 }
260
261 pub fn size(&self) -> Vec2 {
262 self._size
263 }
264
265 pub fn widget(&self) -> Image {
266 Image::new(self.texture_id, self.size())
267 }
268
269 pub fn resize(&mut self, x: f32, y: f32) {
270 self._size.x = x;
271 self._size.y = y
272 }
273
274 pub fn set_size_x(&mut self, x: f32) {
275 self._size.x = x;
276 }
277
278 pub fn set_size_y(&mut self, y: f32) {
279 self._size.y = y
280 }
281
282 pub fn new(painter: &mut Painter, bytes: &[u8], opt_ref: OptionsRef) -> Result<Self, Error> {
284 let rtree = match Tree::from_data(&bytes, &opt_ref) {
285 Ok(rtree) => rtree,
286 Err(e) => {
287 let err = Error::new(ErrorKind::Other, e.to_string());
288 return Err(err);
289 }
290 };
291 let pixels;
292 let size;
293 {
294 let pixmap_size = rtree.svg_node().size.to_screen_size();
295 let mut pixmap = match Pixmap::new(pixmap_size.width(), pixmap_size.height()) {
296 Some(pixmap) => pixmap,
297 _ => {
298 let err = Error::new(ErrorKind::Other, "while mapping SVG pixels!");
299 return Err(err);
300 }
301 };
302
303 {
304 if render(&rtree, usvg::FitTo::Original, pixmap.as_mut()).is_none() {
305 let err = Error::new(ErrorKind::Other, "while rendering SVG data!");
306 return Err(err);
307 }
308 }
309 size = (pixmap_size.width() as usize, pixmap_size.height() as usize);
310 pixels = pixmap.data().to_vec();
311 }
312 let tex = painter.new_user_texture_rgba8(size, pixels, true);
313 let feimage = Self {
314 texture_id: tex,
315 _size: Vec2::from((size.0 as f32, size.1 as f32)),
316 };
317 Ok(feimage)
318 }
319
320 pub fn update_svg(
322 &mut self,
323 painter: &mut Painter,
324 bytes: &[u8],
325 opt_ref: OptionsRef,
326 ) -> Result<(), Error> {
327 let rtree = match Tree::from_data(&bytes, &opt_ref) {
328 Ok(rtree) => rtree,
329 Err(e) => {
330 let err = Error::new(ErrorKind::Other, e.to_string());
331 return Err(err);
332 }
333 };
334 let pixels;
335 let size;
336 {
337 let pixmap_size = rtree.svg_node().size.to_screen_size();
338 let mut pixmap = match Pixmap::new(pixmap_size.width(), pixmap_size.height()) {
339 Some(pixmap) => pixmap,
340 _ => {
341 let err = Error::new(ErrorKind::Other, "while mapping SVG pixels!");
342 return Err(err);
343 }
344 };
345
346 {
347 if render(&rtree, usvg::FitTo::Original, pixmap.as_mut()).is_none() {
348 let err = Error::new(ErrorKind::Other, "while rendering SVG data!");
349 return Err(err);
350 }
351 }
352
353 size = (pixmap_size.width() as usize, pixmap_size.height() as usize);
354 pixels = pixmap.data().to_vec();
355 }
356 painter.update_user_texture_rgba8_data(self.texture_id, pixels);
357 self._size = Vec2::from((size.0 as f32, size.1 as f32));
358 Ok(())
359 }
360}
361
362#[cfg(feature = "svg")]
363impl Into<ImageWidget> for SVGWidget {
364 fn into(self) -> ImageWidget {
365 ImageWidget {
366 texture_id: self.texture_id,
367 _size: self._size,
368 }
369 }
370}
371
372#[cfg(feature = "svg")]
373impl From<ImageWidget> for SVGWidget {
374 fn from(t: ImageWidget) -> SVGWidget {
375 SVGWidget {
376 texture_id: t.texture_id,
377 _size: t._size,
378 }
379 }
380}