embedded_text/style/
vertical_overdraw.rs1use az::SaturatingAs;
4
5use crate::rendering::cursor::Cursor;
6use core::ops::Range;
7
8#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
10pub enum VerticalOverdraw {
11 FullRowsOnly,
13 Hidden,
15 Visible,
17}
18
19impl VerticalOverdraw {
20 pub(crate) fn calculate_displayed_row_range(self, cursor: &Cursor) -> Range<u32> {
22 let line_height = cursor.line_height();
23 match self {
24 VerticalOverdraw::FullRowsOnly => {
25 if cursor.in_display_area() {
26 0..line_height
27 } else {
28 0..0
29 }
30 }
31
32 VerticalOverdraw::Hidden => {
33 let offset_top = (cursor.top_left().y - cursor.y).saturating_as::<u32>();
34 let offset_bottom =
35 line_height - (cursor.y - cursor.bottom()).saturating_as::<u32>();
36
37 offset_top..offset_bottom
38 }
39
40 VerticalOverdraw::Visible => 0..line_height,
41 }
42 }
43}
44
45#[cfg(test)]
46mod test {
47 use embedded_graphics::{
48 geometry::{Point, Size},
49 mock_display::MockDisplay,
50 mono_font::{ascii::FONT_6X9, MonoTextStyleBuilder},
51 pixelcolor::BinaryColor,
52 primitives::Rectangle,
53 Drawable,
54 };
55
56 use crate::{
57 alignment::*,
58 style::{HeightMode, TextBoxStyleBuilder, VerticalOverdraw},
59 TextBox,
60 };
61
62 #[test]
63 fn default_is_full_rows_only() {
64 let mut display = MockDisplay::new();
66
67 let character_style = MonoTextStyleBuilder::new()
68 .font(&FONT_6X9)
69 .text_color(BinaryColor::On)
70 .background_color(BinaryColor::Off)
71 .build();
72
73 let style = TextBoxStyleBuilder::new()
74 .alignment(HorizontalAlignment::Left)
75 .build();
76
77 TextBox::with_textbox_style(
78 "word and other words",
79 Rectangle::new(Point::zero(), Size::new(55, 15)),
80 character_style,
81 style,
82 )
83 .draw(&mut display)
84 .unwrap();
85
86 display.assert_pattern(&[
87 "................................................",
88 "......................#.......................#.",
89 "......................#.......................#.",
90 "#...#...##...#.#....###.........###..###....###.",
91 "#.#.#..#..#..##.#..#..#........#..#..#..#..#..#.",
92 "#.#.#..#..#..#.....#..#........#..#..#..#..#..#.",
93 ".#.#....##...#......###.........###..#..#...###.",
94 "................................................",
95 "................................................",
96 ]);
97 }
98
99 #[test]
100 fn visible_displays_regardless_of_bounds() {
101 let mut display = MockDisplay::new();
104
105 let character_style = MonoTextStyleBuilder::new()
106 .font(&FONT_6X9)
107 .text_color(BinaryColor::On)
108 .background_color(BinaryColor::Off)
109 .build();
110
111 let style = TextBoxStyleBuilder::new()
112 .alignment(HorizontalAlignment::Left)
113 .vertical_alignment(VerticalAlignment::Middle)
114 .height_mode(HeightMode::Exact(VerticalOverdraw::Visible))
115 .build();
116
117 TextBox::with_textbox_style(
119 "word",
120 Rectangle::new(Point::new(0, 3), Size::new(55, 3)),
121 character_style,
122 style,
123 )
124 .draw(&mut display)
125 .unwrap();
126
127 display.assert_pattern(&[
128 "........................",
129 "......................#.",
130 "......................#.",
131 "#...#...##...#.#....###.",
132 "#.#.#..#..#..##.#..#..#.",
133 "#.#.#..#..#..#.....#..#.",
134 ".#.#....##...#......###.",
135 "........................",
136 "........................",
137 ]);
138 }
139
140 #[test]
141 fn hidden_only_displays_visible_rows() {
142 let mut display = MockDisplay::new();
145
146 let character_style = MonoTextStyleBuilder::new()
147 .font(&FONT_6X9)
148 .text_color(BinaryColor::On)
149 .background_color(BinaryColor::Off)
150 .build();
151
152 let style = TextBoxStyleBuilder::new()
153 .alignment(HorizontalAlignment::Left)
154 .vertical_alignment(VerticalAlignment::Middle)
155 .height_mode(HeightMode::Exact(VerticalOverdraw::Hidden))
156 .build();
157
158 TextBox::with_textbox_style(
159 "word",
160 Rectangle::new(Point::zero(), Size::new(55, 4)),
161 character_style,
162 style,
163 )
164 .draw(&mut display)
165 .unwrap();
166
167 display.assert_pattern(&[
168 "......................#.",
169 "#...#...##...#.#....###.",
170 "#.#.#..#..#..##.#..#..#.",
171 "#.#.#..#..#..#.....#..#.",
172 ]);
173 }
174}