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 size(&self) -> (u32, u32) {
25 let s = self.inner.size();
26 (s.width, s.height)
27 }
28
29 pub fn draw_pixel(&mut self, point: Point, color: Color) {
31 let rgb = Rgb888::new(color.0, color.1, color.2);
32 let _ = self.inner.draw_iter(iter::once(Pixel(point, rgb)));
33 }
34
35 pub fn pixels(&self) -> Vec<Color> {
37 self.inner
38 .pixels
39 .iter()
40 .map(|p| match p {
41 Some(c) => Color(c.r(), c.g(), c.b(), 255),
42 None => Color(0, 0, 0, 255),
43 })
44 .collect()
45 }
46
47 #[cfg(feature = "png")]
49 pub fn to_png(&self) -> Result<Vec<u8>, png::EncodingError> {
50 use png::{ColorType, Encoder};
51 let (w, h) = (self.inner.size().width, self.inner.size().height);
52 let mut buf = Vec::new();
53 {
54 let mut encoder = Encoder::new(&mut buf, w, h);
55 encoder.set_color(ColorType::Rgb);
56 let mut writer = encoder.write_header()?;
57 let data: Vec<u8> = self
58 .pixels()
59 .into_iter()
60 .flat_map(|c| vec![c.0, c.1, c.2])
61 .collect();
62 writer.write_image_data(&data)?;
63 }
64 Ok(buf)
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn draw_and_get_pixels() {
74 let mut canvas = Canvas::new(1, 1);
75 canvas.draw_pixel(Point::new(0, 0), Color(255, 0, 0, 255));
76 assert_eq!(canvas.pixels(), vec![Color(255, 0, 0, 255)]);
77 }
78
79 #[test]
80 fn blank_canvas_pixels() {
81 let canvas = Canvas::new(1, 1);
82 assert_eq!(canvas.pixels(), vec![Color(0, 0, 0, 255)]);
83 }
84
85 #[cfg(feature = "png")]
86 #[test]
87 fn export_png() {
88 let mut canvas = Canvas::new(1, 1);
89 canvas.draw_pixel(Point::new(0, 0), Color(255, 0, 0, 255));
90 let data = canvas.to_png().unwrap();
91 let (pixels, w, h) = crate::plugins::png::decode(&data).unwrap();
92 assert_eq!((w, h), (1, 1));
93 assert_eq!(pixels, vec![Color(255, 0, 0, 255)]);
94 }
95}