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}