| 1 | use crate::{ |
| 2 | draw_target::DrawTarget, geometry::Dimensions, iterator::ContiguousIteratorExt, |
| 3 | pixelcolor::BinaryColor, primitives::Rectangle, Pixel, |
| 4 | }; |
| 5 | |
| 6 | pub struct MonoFontDrawTarget<'a, T, C> { |
| 7 | parent: &'a mut T, |
| 8 | colors: C, |
| 9 | } |
| 10 | |
| 11 | impl<'a, T: DrawTarget, C> MonoFontDrawTarget<'a, T, C> { |
| 12 | pub fn new(parent: &'a mut T, colors: C) -> Self { |
| 13 | Self { parent, colors } |
| 14 | } |
| 15 | } |
| 16 | |
| 17 | impl<T: DrawTarget> DrawTarget for MonoFontDrawTarget<'_, T, Foreground<T::Color>> { |
| 18 | type Color = BinaryColor; |
| 19 | type Error = T::Error; |
| 20 | |
| 21 | fn fill_contiguous<I>(&mut self, area: &Rectangle, colors: I) -> Result<(), Self::Error> |
| 22 | where |
| 23 | I: IntoIterator<Item = Self::Color>, |
| 24 | { |
| 25 | let foreground_color = self.colors.0; |
| 26 | |
| 27 | self.parent.draw_iter( |
| 28 | colors |
| 29 | .into_iter() |
| 30 | .into_pixels(area) |
| 31 | .filter(|Pixel(_, color)| color.is_on()) |
| 32 | .map(|Pixel(pos, _)| Pixel(pos, foreground_color)), |
| 33 | ) |
| 34 | } |
| 35 | |
| 36 | fn draw_iter<I>(&mut self, _pixels: I) -> Result<(), Self::Error> |
| 37 | where |
| 38 | I: IntoIterator<Item = Pixel<Self::Color>>, |
| 39 | { |
| 40 | unreachable!() |
| 41 | } |
| 42 | |
| 43 | fn fill_solid(&mut self, area: &Rectangle, color: Self::Color) -> Result<(), Self::Error> { |
| 44 | match color { |
| 45 | BinaryColor::On => self.parent.fill_solid(area, self.colors.0), |
| 46 | BinaryColor::Off => Ok(()), |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | fn clear(&mut self, _color: Self::Color) -> Result<(), Self::Error> { |
| 51 | unreachable!() |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | impl<T: DrawTarget> DrawTarget for MonoFontDrawTarget<'_, T, Background<T::Color>> { |
| 56 | type Color = BinaryColor; |
| 57 | type Error = T::Error; |
| 58 | |
| 59 | fn fill_contiguous<I>(&mut self, area: &Rectangle, colors: I) -> Result<(), Self::Error> |
| 60 | where |
| 61 | I: IntoIterator<Item = Self::Color>, |
| 62 | { |
| 63 | let foreground_color = self.colors.0; |
| 64 | |
| 65 | self.parent.draw_iter( |
| 66 | colors |
| 67 | .into_iter() |
| 68 | .into_pixels(area) |
| 69 | .filter(|Pixel(_, color)| color.is_off()) |
| 70 | .map(|Pixel(pos, _)| Pixel(pos, foreground_color)), |
| 71 | ) |
| 72 | } |
| 73 | |
| 74 | fn draw_iter<I>(&mut self, _pixels: I) -> Result<(), Self::Error> |
| 75 | where |
| 76 | I: IntoIterator<Item = Pixel<Self::Color>>, |
| 77 | { |
| 78 | unreachable!() |
| 79 | } |
| 80 | |
| 81 | fn fill_solid(&mut self, area: &Rectangle, color: Self::Color) -> Result<(), Self::Error> { |
| 82 | match color { |
| 83 | BinaryColor::On => Ok(()), |
| 84 | BinaryColor::Off => self.parent.fill_solid(area, self.colors.0), |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | fn clear(&mut self, _color: Self::Color) -> Result<(), Self::Error> { |
| 89 | unreachable!() |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | impl<T: DrawTarget> DrawTarget for MonoFontDrawTarget<'_, T, Both<T::Color>> { |
| 94 | type Color = BinaryColor; |
| 95 | type Error = T::Error; |
| 96 | |
| 97 | fn fill_contiguous<I>(&mut self, area: &Rectangle, colors: I) -> Result<(), Self::Error> |
| 98 | where |
| 99 | I: IntoIterator<Item = Self::Color>, |
| 100 | { |
| 101 | let foreground_color = self.colors.0; |
| 102 | let background_color = self.colors.1; |
| 103 | |
| 104 | self.parent.fill_contiguous( |
| 105 | area, |
| 106 | colors.into_iter().map(|color| match color { |
| 107 | BinaryColor::Off => background_color, |
| 108 | BinaryColor::On => foreground_color, |
| 109 | }), |
| 110 | ) |
| 111 | } |
| 112 | |
| 113 | fn draw_iter<I>(&mut self, _pixels: I) -> Result<(), Self::Error> |
| 114 | where |
| 115 | I: IntoIterator<Item = Pixel<Self::Color>>, |
| 116 | { |
| 117 | unreachable!() |
| 118 | } |
| 119 | |
| 120 | fn fill_solid(&mut self, area: &Rectangle, color: Self::Color) -> Result<(), Self::Error> { |
| 121 | match color { |
| 122 | BinaryColor::On => self.parent.fill_solid(area, self.colors.0), |
| 123 | BinaryColor::Off => self.parent.fill_solid(area, self.colors.1), |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | fn clear(&mut self, _color: Self::Color) -> Result<(), Self::Error> { |
| 128 | unreachable!() |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | impl<T: DrawTarget, C> Dimensions for MonoFontDrawTarget<'_, T, C> { |
| 133 | fn bounding_box(&self) -> Rectangle { |
| 134 | self.parent.bounding_box() |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | pub struct Foreground<C>(pub C); |
| 139 | pub struct Background<C>(pub C); |
| 140 | pub struct Both<C>(pub C, pub C); |
| 141 | |