1use crate::draw_target::MultiMonoFontDrawTarget;
2use embedded_graphics::{
3 Drawable,
4 geometry::{OriginDimensions, Point},
5 image::{Image, ImageDrawable, ImageRaw},
6 pixelcolor::BinaryColor,
7 prelude::{DrawTarget, PixelColor, Size},
8 primitives::{Primitive, PrimitiveStyle, Rectangle},
9};
10
11#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
16#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
17pub struct MonoImage<'a, C> {
18 image: &'a ImageRaw<'a, BinaryColor>,
19 foreground_color: C,
20 background_color: Option<C>,
21}
22
23impl<'a, C> MonoImage<'a, C> {
24 pub const fn new(image: &'a ImageRaw<'a, BinaryColor>, foreground_color: C) -> Self {
26 Self {
27 image,
28 foreground_color,
29 background_color: None,
30 }
31 }
32
33 pub const fn new_with_background_color(
35 image: &'a ImageRaw<'a, BinaryColor>,
36 foreground_color: C,
37 background_color: C,
38 ) -> Self {
39 Self {
40 image,
41 foreground_color,
42 background_color: Some(background_color),
43 }
44 }
45
46 pub fn with_background_color(mut self, background_color: C) -> Self {
48 self.background_color = Some(background_color);
49 self
50 }
51
52 pub fn clear_background_color(&mut self) {
54 self.background_color = None;
55 }
56}
57
58impl<C> OriginDimensions for MonoImage<'_, C>
59where
60 C: PixelColor + From<<C as PixelColor>::Raw>,
61{
62 fn size(&self) -> Size {
63 self.image.size()
64 }
65}
66
67impl<'a, C> ImageDrawable for MonoImage<'a, C>
68where
69 C: PixelColor + From<<C as PixelColor>::Raw>,
70{
71 type Color = C;
72
73 fn draw<D>(&self, target: &mut D) -> Result<(), D::Error>
74 where
75 D: DrawTarget<Color = C>,
76 {
77 let mut bin_target =
78 MultiMonoFontDrawTarget::new(target, self.foreground_color, self.background_color);
79
80 self.image.draw(&mut bin_target)
81 }
82
83 fn draw_sub_image<D>(&self, target: &mut D, area: &Rectangle) -> Result<(), D::Error>
84 where
85 D: DrawTarget<Color = Self::Color>,
86 {
87 let mut bin_target =
88 MultiMonoFontDrawTarget::new(target, self.foreground_color, self.background_color);
89
90 self.image.draw_sub_image(&mut bin_target, area)
91 }
92}
93
94#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
99#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
100pub struct MonoRleImage<C> {
101 glyph: &'static [u8],
102 x: i16,
103 y: i16,
104 width: u16,
105 height: u16,
106 foreground_color: C,
107 background_color: Option<C>,
108}
109
110impl<C> MonoRleImage<C> {
111 pub const fn new(glyph: &'static [u8], width: u16, height: u16, foreground_color: C) -> Self {
113 Self {
114 glyph,
115 x: 0,
116 y: 0,
117 width,
118 height,
119 foreground_color,
120 background_color: None,
121 }
122 }
123
124 pub const fn new_with_background_color(
126 glyph: &'static [u8],
127 width: u16,
128 height: u16,
129 foreground_color: C,
130 background_color: C,
131 ) -> Self {
132 Self {
133 glyph,
134 x: 0,
135 y: 0,
136 width,
137 height,
138 foreground_color,
139 background_color: Some(background_color),
140 }
141 }
142
143 pub const fn with_offset(mut self, x: i16, y: i16) -> Self {
144 self.x = x;
145 self.y = y;
146 self
147 }
148
149 pub fn with_background_color(mut self, background_color: C) -> Self {
151 self.background_color = Some(background_color);
152 self
153 }
154
155 pub fn clear_background_color(&mut self) {
157 self.background_color = None;
158 }
159
160 pub fn rectangle(&self) -> Rectangle {
161 Rectangle::new(
162 Point::new(self.x as i32, self.y as i32),
163 Size::new(self.width as u32, self.height as u32),
164 )
165 }
166}
167
168impl<C> OriginDimensions for MonoRleImage<C>
169where
170 C: PixelColor + From<<C as PixelColor>::Raw>,
171{
172 fn size(&self) -> Size {
173 Size::new(self.width as u32, self.height as u32)
174 }
175}
176
177impl<C> ImageDrawable for MonoRleImage<C>
178where
179 C: PixelColor + From<<C as PixelColor>::Raw>,
180{
181 type Color = C;
182
183 fn draw<D>(&self, target: &mut D) -> Result<(), D::Error>
184 where
185 D: DrawTarget<Color = C>,
186 {
187 let mut target =
188 MultiMonoFontDrawTarget::new(target, self.foreground_color, self.background_color);
189
190 let glyph_rder = crate::glyph_reader::GlyphReader::new(self.glyph);
191 crate::glyph_reader::render_glyph_as_box_fill(&self.rectangle(), glyph_rder, &mut target)
192 }
193
194 fn draw_sub_image<D>(&self, target: &mut D, area: &Rectangle) -> Result<(), D::Error>
195 where
196 D: DrawTarget<Color = Self::Color>,
197 {
198 let mut target =
199 MultiMonoFontDrawTarget::new(target, self.foreground_color, self.background_color);
200
201 let glyph_rder = crate::glyph_reader::GlyphReader::new(self.glyph);
202 crate::glyph_reader::render_glyph_as_box_fill(area, glyph_rder, &mut target)
203 }
204}
205
206pub struct MonoImageStack<'a, T: ImageDrawable> {
210 images: &'a [&'a T],
211 position: Point,
212 size: Size,
213 background_color: Option<T::Color>,
214}
215
216impl<'a, T: ImageDrawable> MonoImageStack<'a, T> {
217 pub const fn new(images: &'a [&'a T], position: Point) -> Self {
218 Self {
219 images,
220 position,
221 size: Size::zero(),
222 background_color: None,
223 }
224 }
225
226 pub const fn new_with_background_color(
227 images: &'a [&'a T],
228 area: Rectangle,
229 background_color: T::Color,
230 ) -> Self {
231 Self {
232 images,
233 position: area.top_left,
234 size: area.size,
235 background_color: Some(background_color),
236 }
237 }
238
239 pub fn draw<D: DrawTarget<Color = T::Color>>(&self, target: &mut D) -> Result<(), D::Error> {
240 if let Some(bg_color) = self.background_color {
241 let area = Rectangle::new(self.position, self.size);
242 area.into_styled(PrimitiveStyle::with_fill(bg_color))
243 .draw(target)?;
244 }
245 for image in self.images {
246 Image::new(*image, self.position).draw(target)?
247 }
248
249 Ok(())
250 }
251}