pixelab_core/
bitmap.rs

1use crate::{Area, Color, PixelabError, Point};
2
3pub enum BitmapFormat {
4    RGB8888x4(Vec<u8>),
5    RGB565x1(Vec<u16>),
6    RGB8888x1(Vec<u32>),
7}
8
9pub trait Bitmap {
10    fn create(&self, area: Area) -> Box<dyn Bitmap + 'static>;
11    fn set_pixel(&mut self, point: Point, color: Color) -> Result<(), PixelabError>;
12    fn fill(&mut self, color: Color) -> Result<(), PixelabError>;
13    fn overlay(
14        &mut self,
15        fb: &mut Box<dyn Bitmap + 'static>,
16        point: Point,
17    ) -> Result<(), PixelabError>;
18    fn buffer(&mut self) -> &mut BitmapFormat;
19    fn area(&mut self) -> &mut Area;
20    fn draw_line(
21        &mut self,
22        start_point: Point,
23        end_point: Point,
24        color: Color,
25    ) -> Result<(), PixelabError> {
26        let x0 = start_point.x as i32;
27        let y0 = start_point.y as i32;
28        let x1 = end_point.x as i32;
29        let y1 = end_point.y as i32;
30        let dx = (x1 - x0).abs();
31        let dy = (y1 - y0).abs();
32        let sx = if x0 < x1 { 1 } else { -1 };
33        let sy = if y0 < y1 { 1 } else { -1 };
34        let mut x = x0;
35        let mut y = y0;
36        let mut err = dx - dy;
37        loop {
38            if x >= 0 && x < self.area().width as i32 && y >= 0 && y < self.area().height as i32 {
39                let point = Point::new(x as u16, y as u16);
40                self.set_pixel(point, color)?;
41            }
42            if x == x1 && y == y1 {
43                break;
44            }
45            let e2 = 2 * err;
46            if e2 > -dy {
47                err -= dy;
48                x += sx;
49            }
50            if e2 < dx {
51                err += dx;
52                y += sy;
53            }
54        }
55        Ok(())
56    }
57    fn set_border(&mut self, color: Color) -> Result<(), PixelabError> {
58        let width = self.area().width as usize;
59        let height = self.area().height as usize;
60        for x in 0..width {
61            if x < width {
62                self.set_pixel(Point::new(x as u16, 0), color)?;
63            }
64        }
65        for x in 0..width {
66            if x < width {
67                self.set_pixel(Point::new(x as u16, (height - 1) as u16), color)?;
68            }
69        }
70        for y in 1..height - 1 {
71            if y < height {
72                self.set_pixel(Point::new(0, y as u16), color)?;
73            }
74        }
75        for y in 1..height - 1 {
76            if y < height {
77                self.set_pixel(Point::new((width - 1) as u16, y as u16), color)?;
78            }
79        }
80        Ok(())
81    }
82    fn draw_poly_line(&mut self, points: Vec<(Point, Color)>) -> Result<(), PixelabError> {
83        if points.len() < 2 {
84            return Err(PixelabError::InsufficientPoints);
85        }
86        for i in 0..points.len() - 1 {
87            let start = points[i].0;
88            let end = points[i + 1].0;
89            let color = points[i].1;
90            self.draw_line(start, end, color)?;
91        }
92        Ok(())
93    }
94}