use embedded_graphics::{
drawable::Pixel,
geometry::{Dimensions, Size},
image::{Image, ImageDimensions},
pixelcolor::{Rgb565, Rgb888, RgbColor},
prelude::*,
primitives,
style::{PrimitiveStyle, Styled},
DrawTarget,
};
use raqote;
pub mod prelude;
pub struct RaqoteDisplay {
draw_target: raqote::DrawTarget,
size: Size,
}
impl RaqoteDisplay {
pub fn new(width: u32, height: u32) -> Result<Self, String> {
Ok(RaqoteDisplay {
draw_target: raqote::DrawTarget::new(width as i32, height as i32),
size: Size::new(width, height),
})
}
fn fill(&mut self, path: &raqote::Path, color: Rgb565) {
self.draw_target.fill(
path,
&raqote::Source::from(convert_color(color)),
&raqote::DrawOptions::default(),
);
}
fn stroke(&mut self, path: &raqote::Path, color: Rgb565, stroke_width: u32) {
self.draw_target.stroke(
path,
&raqote::Source::from(convert_color(color)),
&raqote::StrokeStyle {
width: stroke_width as f32,
..Default::default()
},
&raqote::DrawOptions::default(),
);
}
pub fn data(&self) -> &[u32] {
self.draw_target.get_data()
}
pub fn flip(&mut self, surface: &mut [u32]) {
surface.clone_from_slice(self.draw_target.get_data());
self.draw_target = raqote::DrawTarget::new(self.size.width as i32, self.size.height as i32);
}
}
impl DrawTarget<Rgb565> for RaqoteDisplay {
type Error = String;
fn draw_pixel(&mut self, pixel: Pixel<Rgb565>) -> Result<(), Self::Error> {
self.draw_target.fill_rect(
pixel.0.x as f32,
pixel.0.y as f32,
1.,
1.,
&raqote::Source::from(convert_color(pixel.1)),
&raqote::DrawOptions::default(),
);
Ok(())
}
fn draw_line(
&mut self,
item: &Styled<primitives::Line, PrimitiveStyle<Rgb565>>,
) -> Result<(), Self::Error> {
let line = item.primitive;
let style = item.style;
let mut path_builder = raqote::PathBuilder::new();
path_builder.move_to(line.start.x as f32, line.start.y as f32);
path_builder.line_to(line.end.x as f32, line.end.y as f32);
let path = path_builder.finish();
if let Some(fill_color) = style.fill_color {
self.fill(&path, fill_color);
}
if let Some(stroke_color) = style.stroke_color {
self.stroke(&path, stroke_color, style.stroke_width);
}
Ok(())
}
fn draw_rectangle(
&mut self,
item: &Styled<primitives::Rectangle, PrimitiveStyle<Rgb565>>,
) -> Result<(), Self::Error> {
let rectangle = item.primitive;
let style = item.style;
let width = (rectangle.bottom_right.x - rectangle.top_left.x) as f32;
let height = (rectangle.bottom_right.y - rectangle.top_left.y) as f32;
if let Some(fill_color) = style.fill_color {
self.draw_target.fill_rect(
rectangle.top_left().x as f32,
rectangle.top_left().y as f32,
width,
height,
&raqote::Source::from(convert_color(fill_color)),
&raqote::DrawOptions::default(),
);
}
if let Some(stroke_color) = style.stroke_color {
let mut path_builder = raqote::PathBuilder::new();
path_builder.rect(
rectangle.top_left().x as f32,
rectangle.top_left().y as f32,
width,
height,
);
self.stroke(&path_builder.finish(), stroke_color, style.stroke_width);
}
Ok(())
}
fn draw_circle(
&mut self,
item: &Styled<primitives::Circle, PrimitiveStyle<Rgb565>>,
) -> Result<(), Self::Error> {
let circle = item.primitive;
let style = item.style;
let mut path_builder = raqote::PathBuilder::new();
path_builder.arc(
circle.center.x as f32,
circle.center.y as f32,
circle.radius as f32,
0.0,
2.0 * std::f32::consts::PI,
);
let path = path_builder.finish();
if let Some(fill_color) = style.fill_color {
self.fill(&path, fill_color);
}
if let Some(stroke_color) = style.stroke_color {
self.stroke(&path, stroke_color, style.stroke_width);
}
Ok(())
}
fn draw_image<'a, 'b, I>(&mut self, item: &'a Image<'b, I, Rgb565>) -> Result<(), Self::Error>
where
&'b I: IntoPixelIter<Rgb565>,
I: ImageDimensions,
{
let mut pixels = vec![];
for pixel in item {
let color = convert_color(pixel.1);
pixels.push(
0xFF00_0000
| ((color.r() as u32) << 16)
| ((color.g() as u32) << 8)
| (color.b() as u32),
);
}
let image = raqote::Image {
width: item.size().width as i32,
height: item.size().height as i32,
data: &pixels,
};
self.draw_target.draw_image_at(
item.top_left().x as f32,
item.top_left().y as f32,
&image,
&raqote::DrawOptions::default(),
);
Ok(())
}
fn size(&self) -> Size {
self.size
}
}
fn convert_color(color: Rgb565) -> raqote::Color {
let color: Rgb888 = Rgb888::from(color);
raqote::Color::new(255, color.r(), color.g(), color.b())
}