minifb_geometry/lib.rs
1use bresenham::Bresenham;
2use error::DrawError;
3mod error;
4
5
6/// A struct representing a geometry drawer.
7pub struct GeometryDrawer {
8 window_width: usize,
9}
10
11impl GeometryDrawer {
12 /// Creates a new `GeometryDrawer` instance.
13 ///
14 /// # Arguments
15 ///
16 /// * `window_width` - The width of the window.
17 ///
18 /// # Returns
19 ///
20 /// A new `GeometryDrawer` instance.
21 pub fn new(window_width: usize) -> Self {
22 Self { window_width }
23 }
24
25 /// Draws a box on the buffer.
26 ///
27 /// # Arguments
28 ///
29 /// * `buf` - The buffer to draw on.
30 /// * `start_x` - The starting x-coordinate of the box.
31 /// * `start_y` - The starting y-coordinate of the box.
32 /// * `end_x` - The ending x-coordinate of the box.
33 /// * `end_y` - The ending y-coordinate of the box.
34 /// * `color` - The color of the box.
35 ///
36 /// # Returns
37 ///
38 /// Returns `Ok(())` if the box is successfully drawn, or a `DrawError` if an error occurs.
39 pub fn draw_box(
40 &self,
41 buf: &mut Vec<u32>,
42 start_x: usize,
43 start_y: usize,
44 end_x: usize,
45 end_y: usize,
46 color: usize,
47 ) -> Result<(), DrawError> {
48 for i in start_x..end_x {
49 for j in start_y..end_y {
50 self.draw_pixel(buf, i, j, color)?;
51 }
52 }
53 Ok(())
54 }
55
56 /// Clears the screen.
57 ///
58 /// # Arguments
59 ///
60 /// * `buf` - The buffer to clear.
61 /// * `start_x` - The starting x-coordinate of the screen.
62 /// * `start_y` - The starting y-coordinate of the screen.
63 /// * `end_x` - The ending x-coordinate of the screen.
64 /// * `end_y` - The ending y-coordinate of the screen.
65 ///
66 /// # Returns
67 ///
68 /// Returns `Ok(())` if the screen is successfully cleared, or a `DrawError` if an error occurs.
69 pub fn screen_clear(
70 &self,
71 buf: &mut Vec<u32>,
72 start_x: usize,
73 start_y: usize,
74 end_x: usize,
75 end_y: usize,
76 ) -> Result<(), DrawError>{
77 self.draw_box( buf, start_x, start_y, end_x, end_y, 0x00_00_00)
78 }
79
80 /// Draws a line on the buffer.
81 ///
82 /// # Arguments
83 ///
84 /// * `buf` - The buffer to draw on.
85 /// * `start_x` - The starting x-coordinate of the line.
86 /// * `start_y` - The starting y-coordinate of the line.
87 /// * `end_x` - The ending x-coordinate of the line.
88 /// * `end_y` - The ending y-coordinate of the line.
89 /// * `color` - The color of the line.
90 ///
91 /// # Returns
92 ///
93 /// Returns `Ok(())` if the line is successfully drawn, or a `DrawError` if an error occurs.
94 pub fn draw_line(
95 &self,
96 buf: &mut Vec<u32>,
97 start_x: usize,
98 start_y: usize,
99 end_x: usize,
100 end_y: usize,
101 color: usize,
102 ) -> Result<(), DrawError>{
103 for (x, y) in Bresenham::new(
104 (start_x as isize, start_y as isize),
105 (end_x as isize, end_y as isize),
106 ) {
107 self.draw_pixel(buf, x as usize, y as usize, color)?;
108 }
109 Ok(())
110 }
111
112 /// Draws a rectangle on the buffer.
113 ///
114 /// # Arguments
115 ///
116 /// * `buf` - The buffer to draw on.
117 /// * `start_x` - The starting x-coordinate of the rectangle.
118 /// * `start_y` - The starting y-coordinate of the rectangle.
119 /// * `end_x` - The ending x-coordinate of the rectangle.
120 /// * `end_y` - The ending y-coordinate of the rectangle.
121 /// * `border_thickness` - The thickness of the border of the rectangle.
122 /// * `color` - The color of the rectangle.
123 ///
124 /// # Returns
125 ///
126 /// Returns `Ok(())` if the rectangle is successfully drawn, or a `DrawError` if an error occurs.
127 pub fn draw_rectangle(
128 &self,
129 buf: &mut Vec<u32>,
130 start_x: usize,
131 start_y: usize,
132 end_x: usize,
133 end_y: usize,
134 border_thickness: usize,
135 color: usize,
136 ) -> Result<(), DrawError>{
137 for i in 0..border_thickness{
138 self.draw_line(buf, start_x + i, start_y, start_x + i, end_y, color)?;
139 self.draw_line(buf, end_x - i -1, start_y, end_x - i -1, end_y, color)?;
140 self.draw_line(buf, start_x, start_y + i, end_x, start_y + i, color)?;
141 self.draw_line(buf, start_x, end_y - i - 1, end_x, end_y - i - 1, color)?;
142 }
143 Ok(())
144 }
145
146 /// Draws a circle on the buffer.
147 ///
148 /// # Arguments
149 ///
150 /// * `buf` - The buffer to draw on.
151 /// * `start_x` - The starting x-coordinate of the circle.
152 /// * `start_y` - The starting y-coordinate of the circle.
153 /// * `radius` - The radius of the circle.
154 /// * `color` - The color of the circle.
155 ///
156 /// # Returns
157 ///
158 /// Returns `Ok(())` if the circle is successfully drawn, or a `DrawError` if an error occurs.
159 pub fn draw_circle(
160 &self,
161 buf: &mut Vec<u32>,
162 start_x: usize,
163 start_y: usize,
164 radius: usize,
165 color: usize,
166 ) -> Result<(), DrawError>{
167 let mut d: isize = 3 - 2 * radius as isize;
168 let mut x = 0;
169 let mut y = radius;
170 while y >= x {
171 x += 1;
172 if d>0 {
173 y -= 1;
174 d = d + 4 * (x as isize - y as isize) + 10;
175 }
176 else {
177 d = d + 4 * x as isize + 6;
178 }
179 self.draw_pixel(buf, start_x + x, start_y + y, color)?;
180 self.draw_pixel(buf, start_x - x, start_y + y, color)?;
181 self.draw_pixel(buf, start_x + x, start_y - y, color)?;
182 self.draw_pixel(buf, start_x - x, start_y - y, color)?;
183 self.draw_pixel(buf, start_x + y, start_y + x, color)?;
184 self.draw_pixel(buf, start_x - y, start_y + x, color)?;
185 self.draw_pixel(buf, start_x + y, start_y - x, color)?;
186 self.draw_pixel(buf, start_x - y, start_y - x, color)?;
187 }
188 Ok(())
189 }
190
191 /// Draws a pixel on the buffer.
192 ///
193 /// # Arguments
194 ///
195 /// * `buf` - The buffer to draw on.
196 /// * `x` - The x-coordinate of the pixel.
197 /// * `y` - The y-coordinate of the pixel.
198 /// * `color` - The color of the pixel.
199 ///
200 /// # Returns
201 ///
202 /// Returns `Ok(())` if the pixel is successfully drawn, or a `DrawError` if an error occurs.
203 fn draw_pixel(
204 &self,
205 buf: &mut Vec<u32>,
206 x: usize,
207 y: usize,
208 color: usize
209 ) -> Result<(), DrawError>{
210 if (y * self.window_width + x ) < buf.len(){
211 buf[y * self.window_width + x ] = color as u32;
212 }
213 else {
214 return Err(DrawError::OutOfBounds(format!("x: {x} y: {y}").to_string()));
215 }
216 Ok(())
217 }
218
219
220}
221
222
223
224
225
226
227
228
229