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