rlvgl_core/plugins/
canvas.rs1use crate::widget::Color;
3use alloc::vec;
4use alloc::vec::Vec;
5use core::iter;
6use embedded_canvas::Canvas as EcCanvas;
7use embedded_graphics::pixelcolor::Rgb888;
8use embedded_graphics::prelude::{DrawTarget, OriginDimensions, Pixel, Point, RgbColor, Size};
9
10pub struct Canvas {
12 inner: EcCanvas<Rgb888>,
13}
14
15impl Canvas {
16 pub fn new(width: u32, height: u32) -> Self {
18 Self {
19 inner: EcCanvas::new(Size::new(width, height)),
20 }
21 }
22
23 pub fn draw_pixel(&mut self, point: Point, color: Color) {
25 let rgb = Rgb888::new(color.0, color.1, color.2);
26 let _ = self.inner.draw_iter(iter::once(Pixel(point, rgb)));
27 }
28
29 pub fn pixels(&self) -> Vec<Color> {
31 self.inner
32 .pixels
33 .iter()
34 .map(|p| match p {
35 Some(c) => Color(c.r(), c.g(), c.b(), 255),
36 None => Color(0, 0, 0, 255),
37 })
38 .collect()
39 }
40
41 #[cfg(feature = "png")]
43 pub fn to_png(&self) -> Result<Vec<u8>, png::EncodingError> {
44 use png::{ColorType, Encoder};
45 let (w, h) = (self.inner.size().width, self.inner.size().height);
46 let mut buf = Vec::new();
47 {
48 let mut encoder = Encoder::new(&mut buf, w, h);
49 encoder.set_color(ColorType::Rgb);
50 let mut writer = encoder.write_header()?;
51 let data: Vec<u8> = self
52 .pixels()
53 .into_iter()
54 .flat_map(|c| vec![c.0, c.1, c.2])
55 .collect();
56 writer.write_image_data(&data)?;
57 }
58 Ok(buf)
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn draw_and_get_pixels() {
68 let mut canvas = Canvas::new(1, 1);
69 canvas.draw_pixel(Point::new(0, 0), Color(255, 0, 0, 255));
70 assert_eq!(canvas.pixels(), vec![Color(255, 0, 0, 255)]);
71 }
72
73 #[test]
74 fn blank_canvas_pixels() {
75 let canvas = Canvas::new(1, 1);
76 assert_eq!(canvas.pixels(), vec![Color(0, 0, 0, 255)]);
77 }
78
79 #[cfg(feature = "png")]
80 #[test]
81 fn export_png() {
82 let mut canvas = Canvas::new(1, 1);
83 canvas.draw_pixel(Point::new(0, 0), Color(255, 0, 0, 255));
84 let data = canvas.to_png().unwrap();
85 let (pixels, w, h) = crate::plugins::png::decode(&data).unwrap();
86 assert_eq!((w, h), (1, 1));
87 assert_eq!(pixels, vec![Color(255, 0, 0, 255)]);
88 }
89}