laser_pdf/test_utils/
fake_text.rs1use super::*;
2
3pub struct FakeText {
7 pub lines: u32,
8 pub line_height: f32,
9 pub width: f32,
10}
11
12struct Layout {
13 first_lines: u32,
14 full_height_lines: u32,
15 lines: u32,
16 breaks: u32,
17}
18
19impl FakeText {
20 fn lines_and_breaks(&self, first_height: f32, full_height: f32) -> Layout {
21 let first_lines = (first_height / self.line_height).floor() as u32;
22
23 if self.lines <= first_lines {
24 Layout {
25 first_lines: self.lines,
26 full_height_lines: 0,
27 lines: self.lines,
28 breaks: 0,
29 }
30 } else {
31 let remaining_lines = self.lines - first_lines;
32 let lines_per_page = ((full_height / self.line_height).floor() as u32).max(1);
33 let full_pages = remaining_lines / lines_per_page;
34 let last_page_lines = remaining_lines % lines_per_page;
35
36 Layout {
37 first_lines,
38 full_height_lines: lines_per_page,
39 lines: if last_page_lines == 0 {
40 lines_per_page
41 } else {
42 last_page_lines
43 },
44 breaks: full_pages + if last_page_lines == 0 { 0 } else { 1 },
45 }
46 }
47 }
48}
49
50impl Element for FakeText {
51 fn first_location_usage(&self, ctx: FirstLocationUsageCtx) -> FirstLocationUsage {
52 if ctx.first_height < self.line_height {
53 FirstLocationUsage::WillSkip
54 } else {
55 FirstLocationUsage::WillUse
56 }
57 }
58
59 fn measure(&self, ctx: MeasureCtx) -> ElementSize {
60 let lines = if let Some(breakable) = ctx.breakable {
61 let layout = self.lines_and_breaks(ctx.first_height, breakable.full_height);
62
63 *breakable.break_count = layout.breaks;
64 layout.lines
65 } else {
66 self.lines
67 };
68
69 ElementSize {
70 width: Some(ctx.width.constrain(self.width)),
71 height: Some(lines as f32 * self.line_height),
72 }
73 }
74
75 fn draw(&self, ctx: DrawCtx) -> ElementSize {
76 let lines = if let Some(breakable) = ctx.breakable {
77 let layout = self.lines_and_breaks(ctx.first_height, breakable.full_height);
78
79 for i in 0..layout.breaks {
80 (breakable.do_break)(
81 ctx.pdf,
82 i,
83 Some(if i == 0 {
84 self.line_height * layout.first_lines as f32
85 } else {
86 self.line_height * layout.full_height_lines as f32
87 }),
88 );
89 }
90
91 layout.lines
92 } else {
93 self.lines
94 };
95
96 ElementSize {
97 width: Some(ctx.width.constrain(self.width)),
98 height: Some(lines as f32 * self.line_height),
99 }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn test_fake_text() {
109 let element = FakeText {
110 line_height: 1.,
111 lines: 11,
112 width: 5.,
113 };
114
115 for mut output in (ElementTestParams {
116 first_height: 1.999,
117 full_height: 3.3,
118 ..Default::default()
119 })
120 .run(&element)
121 {
122 if let Some(ref mut b) = output.breakable {
123 b.assert_break_count(if output.first_height == 1.999 { 4 } else { 3 });
124 }
125
126 output.assert_size(ElementSize {
127 width: Some(if output.width.expand {
128 output.width.max
129 } else {
130 5.
131 }),
132
133 height: Some(if output.breakable.is_some() {
134 if output.first_height == 1.999 {
135 1.
136 } else {
137 2.
138 }
139 } else {
140 11.
141 }),
142 });
143 }
144 }
145}