1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use freya_common::CachedParagraph;
use freya_engine::prelude::*;
use freya_native_core::prelude::NodeImmutable;
use freya_node_state::FontStyleState;
use torin::prelude::{
    Area,
    AreaModel,
    LayoutNode,
    Length,
    Size2D,
};

use super::utils::ElementUtils;
use crate::{
    prelude::DioxusNode,
    render::align_main_align_paragraph,
};

pub struct LabelElement;

impl ElementUtils for LabelElement {
    fn render(
        self,
        layout_node: &torin::prelude::LayoutNode,
        node_ref: &DioxusNode,
        canvas: &Canvas,
        _font_collection: &mut FontCollection,
        _font_manager: &FontMgr,
        _default_fonts: &[String],
        _scale_factor: f32,
    ) {
        let paragraph = &layout_node
            .data
            .as_ref()
            .unwrap()
            .get::<CachedParagraph>()
            .unwrap()
            .0;
        let area = layout_node.visible_area();

        let x = area.min_x();
        let y = area.min_y() + align_main_align_paragraph(node_ref, &area, paragraph);

        paragraph.paint(canvas, (x, y));
    }

    #[inline]
    fn element_needs_cached_area(&self, node_ref: &DioxusNode) -> bool {
        let font_style = node_ref.get::<FontStyleState>().unwrap();

        !font_style.text_shadows.is_empty()
    }

    fn element_drawing_area(
        &self,
        layout_node: &LayoutNode,
        node_ref: &DioxusNode,
        scale_factor: f32,
    ) -> Area {
        let paragraph_font_height = &layout_node
            .data
            .as_ref()
            .unwrap()
            .get::<CachedParagraph>()
            .unwrap()
            .1;
        let mut area = layout_node.visible_area();
        area.size.height = area.size.height.max(*paragraph_font_height);

        let font_style = node_ref.get::<FontStyleState>().unwrap();

        let mut text_shadow_area = area;

        for text_shadow in &font_style.text_shadows {
            text_shadow_area.move_with_offsets(
                &Length::new(text_shadow.offset.x),
                &Length::new(text_shadow.offset.y),
            );

            let expanded_size = text_shadow.blur_sigma.ceil() as f32 * scale_factor;

            text_shadow_area.expand(&Size2D::new(expanded_size, expanded_size))
        }

        area.union(&text_shadow_area)
    }
}