line_box.rs

 1use crate::{
 2    font_cache::FamilyId,
 3    fonts::Properties,
 4    geometry::vector::{vec2f, Vector2F},
 5    AfterLayoutContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
 6    SizeConstraint,
 7};
 8
 9pub struct LineBox {
10    child: ElementBox,
11    family_id: FamilyId,
12    font_size: f32,
13    font_properties: Properties,
14}
15
16impl LineBox {
17    pub fn new(family_id: FamilyId, font_size: f32, child: ElementBox) -> Self {
18        Self {
19            child,
20            family_id,
21            font_size,
22            font_properties: Properties::default(),
23        }
24    }
25}
26
27impl Element for LineBox {
28    type LayoutState = f32;
29    type PaintState = ();
30
31    fn layout(
32        &mut self,
33        constraint: SizeConstraint,
34        ctx: &mut LayoutContext,
35    ) -> (Vector2F, Self::LayoutState) {
36        match ctx
37            .font_cache
38            .select_font(self.family_id, &self.font_properties)
39        {
40            Ok(font_id) => {
41                let line_height = ctx.font_cache.line_height(font_id, self.font_size);
42                let character_height = ctx.font_cache.ascent(font_id, self.font_size)
43                    + ctx.font_cache.descent(font_id, self.font_size);
44                let child_max = vec2f(constraint.max.x(), character_height);
45                let child_size = self.child.layout(
46                    SizeConstraint::new(constraint.min.min(child_max), child_max),
47                    ctx,
48                );
49                let size = vec2f(child_size.x(), line_height);
50                (size, (line_height - character_height) / 2.)
51            }
52            Err(error) => {
53                log::error!("can't find font for LineBox: {}", error);
54                (constraint.min, 0.0)
55            }
56        }
57    }
58
59    fn after_layout(
60        &mut self,
61        _: Vector2F,
62        _: &mut Self::LayoutState,
63        ctx: &mut AfterLayoutContext,
64    ) {
65        self.child.after_layout(ctx);
66    }
67
68    fn paint(
69        &mut self,
70        bounds: pathfinder_geometry::rect::RectF,
71        padding_top: &mut f32,
72        ctx: &mut PaintContext,
73    ) -> Self::PaintState {
74        self.child
75            .paint(bounds.origin() + vec2f(0., *padding_top), ctx);
76    }
77
78    fn dispatch_event(
79        &mut self,
80        event: &Event,
81        _: pathfinder_geometry::rect::RectF,
82        _: &mut Self::LayoutState,
83        _: &mut Self::PaintState,
84        ctx: &mut EventContext,
85    ) -> bool {
86        self.child.dispatch_event(event, ctx)
87    }
88}