1use core::ops::{Deref, DerefMut};
2use maitake_sync::blocking;
3
4#[cfg(feature = "embedded-graphics-core")]
5#[doc(cfg(feature = "embedded-graphics-core"))]
6mod embedded_graphics;
7#[cfg(feature = "embedded-graphics-core")]
8#[doc(cfg(feature = "embedded-graphics-core"))]
9pub use self::embedded_graphics::*;
10
11pub trait Draw {
12 fn width(&self) -> usize;
14
15 fn height(&self) -> usize;
17
18 fn set_pixel(&mut self, x: usize, y: usize, color: RgbColor) -> &mut Self;
20
21 fn line_horiz(&mut self, y: usize, len: usize, color: RgbColor) -> &mut Self {
27 for x in 0..len {
28 self.set_pixel(x, y, color);
29 }
30 self
31 }
32
33 fn line_vert(&mut self, x: usize, len: usize, color: RgbColor) -> &mut Self {
39 for y in 0..len {
40 self.set_pixel(x, y, color);
41 }
42 self
43 }
44
45 #[inline]
46 fn fill_row(&mut self, y: usize, color: RgbColor) -> &mut Self {
47 self.line_horiz(y, self.width(), color)
48 }
49
50 #[inline]
51 fn fill_col(&mut self, x: usize, color: RgbColor) -> &mut Self {
52 self.line_vert(x, self.height(), color)
53 }
54
55 fn fill(&mut self, color: RgbColor) -> &mut Self {
61 for y in 0..self.height() {
62 self.fill_row(y, color);
63 }
64 self
65 }
66
67 fn clear(&mut self) -> &mut Self {
73 self.fill(RgbColor::BLACK);
74 self
75 }
76
77 fn scroll_vert(&mut self, px: isize) -> &mut Self;
78
79 #[cfg(feature = "embedded-graphics-core")]
80 #[doc(cfg(feature = "embedded-graphics-core"))]
81 fn into_draw_target(self) -> DrawTarget<Self>
82 where
83 Self: Sized,
84 {
85 DrawTarget::new(self)
86 }
87
88 #[cfg(feature = "embedded-graphics-core")]
89 #[doc(cfg(feature = "embedded-graphics-core"))]
90 fn as_draw_target(&mut self) -> DrawTarget<&mut Self>
91 where
92 Self: Sized,
93 {
94 DrawTarget::new(self)
95 }
96}
97
98#[derive(Copy, Clone, Debug, Eq, PartialEq)]
99pub struct RgbColor {
100 pub red: u8,
101 pub green: u8,
102 pub blue: u8,
103}
104
105impl RgbColor {
106 pub const BLACK: Self = Self {
107 red: 0,
108 green: 0,
109 blue: 0,
110 };
111 pub const RED: Self = Self {
112 red: 255,
113 green: 0,
114 blue: 0,
115 };
116 pub const GREEN: Self = Self {
117 red: 0,
118 green: 255,
119 blue: 0,
120 };
121 pub const BLUE: Self = Self {
122 red: 0,
123 green: 0,
124 blue: 255,
125 };
126}
127
128macro_rules! deref_draw_body {
129 () => {
130 #[inline]
131 fn width(&self) -> usize {
132 self.deref().width()
133 }
134
135 #[inline]
136 fn height(&self) -> usize {
137 self.deref().height()
138 }
139
140 #[inline]
141 fn set_pixel(&mut self, x: usize, y: usize, color: RgbColor) -> &mut Self {
142 self.deref_mut().set_pixel(x, y, color);
143 self
144 }
145
146 #[inline]
147 fn line_horiz(&mut self, y: usize, len: usize, color: RgbColor) -> &mut Self {
148 self.deref_mut().line_horiz(y, len, color);
149 self
150 }
151
152 #[inline]
153 fn line_vert(&mut self, x: usize, len: usize, color: RgbColor) -> &mut Self {
154 self.deref_mut().line_vert(x, len, color);
155 self
156 }
157
158 #[inline]
159 fn fill_row(&mut self, y: usize, color: RgbColor) -> &mut Self {
160 self.deref_mut().fill_row(y, color);
161 self
162 }
163
164 #[inline]
165 fn fill_col(&mut self, x: usize, color: RgbColor) -> &mut Self {
166 self.deref_mut().fill_col(x, color);
167 self
168 }
169
170 #[inline]
171 fn scroll_vert(&mut self, px: isize) -> &mut Self {
172 self.deref_mut().scroll_vert(px);
173 self
174 }
175
176 #[inline]
177 fn fill(&mut self, color: RgbColor) -> &mut Self {
178 self.deref_mut().fill(color);
179 self
180 }
181
182 #[inline]
183 fn clear(&mut self) -> &mut Self {
184 self.deref_mut().clear();
185 self
186 }
187 };
188}
189
190impl<D, L> Draw for blocking::MutexGuard<'_, D, L>
191where
192 D: Draw,
193 L: blocking::RawMutex,
194{
195 deref_draw_body! {}
196}
197
198impl<D> Draw for &'_ mut D
199where
200 D: Draw,
201{
202 deref_draw_body! {}
203}