freya_core/elements/
image.rs1use freya_engine::prelude::*;
2use freya_native_core::real_dom::NodeImmutable;
3
4use super::utils::ElementUtils;
5use crate::{
6 dom::{
7 DioxusNode,
8 ImagesCache,
9 },
10 render::{
11 get_or_create_image,
12 ImageData,
13 },
14 states::ImageState,
15 values::{
16 ImageCover,
17 SamplingMode,
18 },
19};
20
21pub struct ImageElement;
22
23impl ElementUtils for ImageElement {
24 fn render(
25 self,
26 layout_node: &torin::prelude::LayoutNode,
27 node_ref: &DioxusNode,
28 canvas: &Canvas,
29 _font_collection: &mut FontCollection,
30 _font_manager: &FontMgr,
31 _default_fonts: &[String],
32 images_cache: &mut ImagesCache,
33 _scale_factor: f32,
34 ) {
35 let area = layout_node.visible_area();
36
37 let Some(ImageData { image, size }) =
38 get_or_create_image(node_ref, &area.size, images_cache)
39 else {
40 return;
41 };
42
43 let image_state = node_ref.get::<ImageState>().unwrap();
44
45 let mut rect = Rect::new(
46 area.min_x(),
47 area.min_y(),
48 area.min_x() + size.width,
49 area.min_y() + size.height,
50 );
51 let clip_rect = Rect::new(area.min_x(), area.min_y(), area.max_x(), area.max_y());
52
53 if image_state.image_cover == ImageCover::Center {
54 let width_offset = (size.width - area.width()) / 2.;
55 let height_offset = (size.height - area.height()) / 2.;
56
57 rect.left -= width_offset;
58 rect.right -= width_offset;
59 rect.top -= height_offset;
60 rect.bottom -= height_offset;
61 }
62
63 canvas.save();
64 canvas.clip_rect(clip_rect, ClipOp::Intersect, true);
65
66 let mut paint = Paint::default();
67 paint.set_anti_alias(true);
68
69 let sampling = match image_state.image_sampling {
70 SamplingMode::Nearest => SamplingOptions::new(FilterMode::Nearest, MipmapMode::None),
71 SamplingMode::Bilinear => SamplingOptions::new(FilterMode::Linear, MipmapMode::None),
72 SamplingMode::Trilinear => SamplingOptions::new(FilterMode::Linear, MipmapMode::Linear),
73 SamplingMode::Mitchell => SamplingOptions::from(CubicResampler::mitchell()),
74 SamplingMode::CatmullRom => SamplingOptions::from(CubicResampler::catmull_rom()),
75 };
76
77 canvas.draw_image_rect_with_sampling_options(
78 image,
79 None,
80 rect,
81 sampling,
82 &Paint::default(),
83 );
84
85 canvas.restore();
86 }
87 fn clip(
88 &self,
89 layout_node: &torin::prelude::LayoutNode,
90 _node_ref: &DioxusNode,
91 canvas: &Canvas,
92 _scale_factor: f32,
93 ) {
94 canvas.clip_rect(
95 Rect::new(
96 layout_node.area.min_x(),
97 layout_node.area.min_y(),
98 layout_node.area.max_x(),
99 layout_node.area.max_y(),
100 ),
101 ClipOp::Intersect,
102 true,
103 );
104 }
105}