freya_core/elements/
label.rs

1use freya_engine::prelude::*;
2use freya_native_core::prelude::NodeImmutable;
3use torin::prelude::{
4    Area,
5    AreaModel,
6    LayoutNode,
7    Length,
8    Size2D,
9};
10
11use super::utils::ElementUtils;
12use crate::{
13    dom::{
14        DioxusNode,
15        ImagesCache,
16    },
17    elements::paragraph::CachedParagraph,
18    render::align_main_align_paragraph,
19    states::{
20        FontStyleState,
21        StyleState,
22    },
23};
24
25pub struct LabelElement;
26
27impl ElementUtils for LabelElement {
28    fn render(
29        self,
30        layout_node: &torin::prelude::LayoutNode,
31        node_ref: &DioxusNode,
32        canvas: &Canvas,
33        _font_collection: &mut FontCollection,
34        _font_manager: &FontMgr,
35        _default_fonts: &[String],
36        _images_cache: &mut ImagesCache,
37        _scale_factor: f32,
38    ) {
39        let paragraph = &layout_node
40            .data
41            .as_ref()
42            .unwrap()
43            .get::<CachedParagraph>()
44            .unwrap()
45            .0;
46        let area = layout_node.visible_area();
47
48        let x = area.min_x();
49        let y = area.min_y() + align_main_align_paragraph(node_ref, &area, paragraph);
50
51        paragraph.paint(canvas, (x, y));
52    }
53
54    fn clip(
55        &self,
56        layout_node: &LayoutNode,
57        _node_ref: &DioxusNode,
58        canvas: &Canvas,
59        _scale_factor: f32,
60    ) {
61        canvas.clip_rect(
62            Rect::new(
63                layout_node.area.min_x(),
64                layout_node.area.min_y(),
65                layout_node.area.max_x(),
66                layout_node.area.max_y(),
67            ),
68            ClipOp::Intersect,
69            true,
70        );
71    }
72
73    #[inline]
74    fn element_needs_cached_area(&self, node_ref: &DioxusNode, _style_state: &StyleState) -> bool {
75        let font_style = node_ref.get::<FontStyleState>().unwrap();
76
77        !font_style.text_shadows.is_empty()
78    }
79
80    fn element_drawing_area(
81        &self,
82        layout_node: &LayoutNode,
83        node_ref: &DioxusNode,
84        scale_factor: f32,
85        _node_style: &StyleState,
86    ) -> Area {
87        let area = layout_node.visible_area();
88
89        let font_style = node_ref.get::<FontStyleState>().unwrap();
90
91        let mut text_shadow_area = area;
92
93        for text_shadow in font_style.text_shadows.iter() {
94            text_shadow_area.move_with_offsets(
95                &Length::new(text_shadow.offset.x),
96                &Length::new(text_shadow.offset.y),
97            );
98
99            let expanded_size = text_shadow.blur_sigma.ceil() as f32 * scale_factor;
100
101            text_shadow_area.expand(&Size2D::new(expanded_size, expanded_size))
102        }
103
104        area.union(&text_shadow_area)
105    }
106}