1use embedded_graphics::{
2 drawable::Pixel,
3 geometry::{Dimensions, Size},
4 image::{Image, ImageDimensions},
5 pixelcolor::{Rgb565, Rgb888, RgbColor},
6 prelude::*,
7 primitives,
8 style::{PrimitiveStyle, Styled},
9 DrawTarget,
10};
11
12use raqote;
13
14pub mod prelude;
15
16pub struct RaqoteDisplay {
42 draw_target: raqote::DrawTarget,
43 size: Size,
44}
45
46impl RaqoteDisplay {
47 pub fn new(width: u32, height: u32) -> Result<Self, String> {
49 Ok(RaqoteDisplay {
50 draw_target: raqote::DrawTarget::new(width as i32, height as i32),
51 size: Size::new(width, height),
52 })
53 }
54
55 fn fill(&mut self, path: &raqote::Path, color: Rgb565) {
56 self.draw_target.fill(
57 path,
58 &raqote::Source::from(convert_color(color)),
59 &raqote::DrawOptions::default(),
60 );
61 }
62
63 fn stroke(&mut self, path: &raqote::Path, color: Rgb565, stroke_width: u32) {
64 self.draw_target.stroke(
65 path,
66 &raqote::Source::from(convert_color(color)),
67 &raqote::StrokeStyle {
68 width: stroke_width as f32,
69 ..Default::default()
70 },
71 &raqote::DrawOptions::default(),
72 );
73 }
74
75 pub fn data(&self) -> &[u32] {
76 self.draw_target.get_data()
77 }
78
79 pub fn flip(&mut self, surface: &mut [u32]) {
81 surface.clone_from_slice(self.draw_target.get_data());
82 self.draw_target = raqote::DrawTarget::new(self.size.width as i32, self.size.height as i32);
83 }
84}
85
86impl DrawTarget<Rgb565> for RaqoteDisplay {
87 type Error = String;
88
89 fn draw_pixel(&mut self, pixel: Pixel<Rgb565>) -> Result<(), Self::Error> {
90 self.draw_target.fill_rect(
91 pixel.0.x as f32,
92 pixel.0.y as f32,
93 1.,
94 1.,
95 &raqote::Source::from(convert_color(pixel.1)),
96 &raqote::DrawOptions::default(),
97 );
98
99 Ok(())
100 }
101
102 fn draw_line(
103 &mut self,
104 item: &Styled<primitives::Line, PrimitiveStyle<Rgb565>>,
105 ) -> Result<(), Self::Error> {
106 let line = item.primitive;
107 let style = item.style;
108
109 let mut path_builder = raqote::PathBuilder::new();
110 path_builder.move_to(line.start.x as f32, line.start.y as f32);
111 path_builder.line_to(line.end.x as f32, line.end.y as f32);
112
113 let path = path_builder.finish();
114
115 if let Some(fill_color) = style.fill_color {
116 self.fill(&path, fill_color);
117 }
118
119 if let Some(stroke_color) = style.stroke_color {
120 self.stroke(&path, stroke_color, style.stroke_width);
121 }
122
123 Ok(())
124 }
125
126 fn draw_rectangle(
127 &mut self,
128 item: &Styled<primitives::Rectangle, PrimitiveStyle<Rgb565>>,
129 ) -> Result<(), Self::Error> {
130 let rectangle = item.primitive;
131 let style = item.style;
132
133 let width = (rectangle.bottom_right.x - rectangle.top_left.x) as f32;
134 let height = (rectangle.bottom_right.y - rectangle.top_left.y) as f32;
135
136 if let Some(fill_color) = style.fill_color {
137 self.draw_target.fill_rect(
138 rectangle.top_left().x as f32,
139 rectangle.top_left().y as f32,
140 width,
141 height,
142 &raqote::Source::from(convert_color(fill_color)),
143 &raqote::DrawOptions::default(),
144 );
145 }
146
147 if let Some(stroke_color) = style.stroke_color {
148 let mut path_builder = raqote::PathBuilder::new();
149 path_builder.rect(
150 rectangle.top_left().x as f32,
151 rectangle.top_left().y as f32,
152 width,
153 height,
154 );
155
156 self.stroke(&path_builder.finish(), stroke_color, style.stroke_width);
157 }
158
159 Ok(())
160 }
161
162 fn draw_circle(
163 &mut self,
164 item: &Styled<primitives::Circle, PrimitiveStyle<Rgb565>>,
165 ) -> Result<(), Self::Error> {
166 let circle = item.primitive;
167 let style = item.style;
168
169 let mut path_builder = raqote::PathBuilder::new();
170 path_builder.arc(
171 circle.center.x as f32,
172 circle.center.y as f32,
173 circle.radius as f32,
174 0.0,
175 2.0 * std::f32::consts::PI,
176 );
177
178 let path = path_builder.finish();
179
180 if let Some(fill_color) = style.fill_color {
181 self.fill(&path, fill_color);
182 }
183
184 if let Some(stroke_color) = style.stroke_color {
185 self.stroke(&path, stroke_color, style.stroke_width);
186 }
187
188 Ok(())
189 }
190
191 fn draw_image<'a, 'b, I>(&mut self, item: &'a Image<'b, I, Rgb565>) -> Result<(), Self::Error>
192 where
193 &'b I: IntoPixelIter<Rgb565>,
194 I: ImageDimensions,
195 {
196 let mut pixels = vec![];
197
198 for pixel in item {
199 let color = convert_color(pixel.1);
200
201 pixels.push(
202 0xFF00_0000
203 | ((color.r() as u32) << 16)
204 | ((color.g() as u32) << 8)
205 | (color.b() as u32),
206 );
207 }
208
209 let image = raqote::Image {
210 width: item.size().width as i32,
211 height: item.size().height as i32,
212 data: &pixels,
213 };
214
215 self.draw_target.draw_image_at(
216 item.top_left().x as f32,
217 item.top_left().y as f32,
218 &image,
219 &raqote::DrawOptions::default(),
220 );
221
222 Ok(())
223 }
224
225 fn size(&self) -> Size {
226 self.size
227 }
228}
229
230fn convert_color(color: Rgb565) -> raqote::Color {
231 let color: Rgb888 = Rgb888::from(color);
232 raqote::Color::new(255, color.r(), color.g(), color.b())
233}