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}