1use crate::{
2 font_cache::FamilyId,
3 fonts::{FontId, 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 = Option<FontId>;
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.bounding_box(font_id, self.font_size).y();
42 let child_max = vec2f(
43 constraint.max.x(),
44 ctx.font_cache.ascent(font_id, self.font_size)
45 - ctx.font_cache.descent(font_id, self.font_size),
46 );
47 let child_size = self.child.layout(
48 SizeConstraint::new(constraint.min.min(child_max), child_max),
49 ctx,
50 );
51 let size = vec2f(child_size.x(), line_height);
52 (size, Some(font_id))
53 }
54 Err(error) => {
55 log::error!("can't find font for LineBox: {}", error);
56 (constraint.min, None)
57 }
58 }
59 }
60
61 fn after_layout(
62 &mut self,
63 _: Vector2F,
64 _: &mut Self::LayoutState,
65 ctx: &mut AfterLayoutContext,
66 ) {
67 self.child.after_layout(ctx);
68 }
69
70 fn paint(
71 &mut self,
72 bounds: pathfinder_geometry::rect::RectF,
73 font_id: &mut Option<FontId>,
74 ctx: &mut PaintContext,
75 ) -> Self::PaintState {
76 if let Some(font_id) = font_id {
77 let descent = ctx.font_cache.descent(*font_id, self.font_size);
78 self.child
79 .paint(bounds.origin() + vec2f(0.0, -descent), ctx);
80 }
81 }
82
83 fn dispatch_event(
84 &mut self,
85 event: &Event,
86 _: pathfinder_geometry::rect::RectF,
87 _: &mut Self::LayoutState,
88 _: &mut Self::PaintState,
89 ctx: &mut EventContext,
90 ) -> bool {
91 self.child.dispatch_event(event, ctx)
92 }
93}