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