From ef37a6552a71f86eb1e393b61a3bbb5d81815783 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 13 Mar 2021 22:54:21 +0530 Subject: factor out line and circle drawing into bitmap --- src/app.rs | 115 ++++++++++++++++++++++++++++--------------------------------- 1 file changed, 53 insertions(+), 62 deletions(-) (limited to 'src/app.rs') diff --git a/src/app.rs b/src/app.rs index c0d3018..3c57f27 100644 --- a/src/app.rs +++ b/src/app.rs @@ -103,61 +103,30 @@ impl<'ctx> AppState<'ctx> { center: P, val: bool, ) -> Result, ()> { - let radius = self.brush_size; - if radius == 1 { - let center_point: Point = center.into(); - return Ok(if let Some(pt) = self.idx_at_coord(center_point) { - let old_val = self.pixmap.set(pt, val); - Ok(ModifyRecord::new(pt, old_val, val)) - } else { - Err(()) - } - .map(|x| vec![x])?); - } else { - if let Some(center_on_grid) = self.idx_at_coord(center) { - // center_on_grid is now a coordinate on the drawing grid - let (x0, y0) = (center_on_grid.0 as i64, center_on_grid.1 as i64); - let (mut dx, mut dy, mut err) = (radius as i64, 0i64, 1 - radius as i64); - let mut circle = vec![]; - let mut old_vals = vec![]; - while dx >= dy { - circle.push((x0 + dx, y0 + dy)); - circle.push((x0 - dx, y0 + dy)); - circle.push((x0 + dx, y0 - dy)); - circle.push((x0 - dx, y0 - dy)); - circle.push((x0 + dy, y0 + dx)); - circle.push((x0 - dy, y0 + dx)); - circle.push((x0 + dy, y0 - dx)); - circle.push((x0 - dy, y0 - dx)); - dy = dy + 1; - if err < 0 { - err = err + 2 * dy + 1; - } else { - dx -= 1; - err += 2 * (dy - dx) + 1; - } - } - // circle's insides - for x in 0..radius as i64 { - for y in 0..radius as i64 { - if x.pow(2) + y.pow(2) < (radius as i64).pow(2) { - circle.push((x0 + x, y0 + y)); - circle.push((x0 - x, y0 + y)); - circle.push((x0 + x, y0 - y)); - circle.push((x0 - x, y0 - y)); - } - } - } - for circumference_pt in circle { - if let Ok(mp) = MapPoint::try_from(circumference_pt) { - let old_val = self.pixmap.set(mp, val); - old_vals.push(ModifyRecord::new((mp.x, mp.y), old_val, val)); - } - } - return Ok(old_vals); + let radius = self.brush_size as u32; + let center = self.idx_at_coord(center).ok_or(())?; + let mut circle_modify_record = vec![]; + for point in self.pixmap.get_circle(center, radius) { + let old_val = self.pixmap.set(point, val); + circle_modify_record.push(ModifyRecord::new(point, old_val, val)); + } + Ok(circle_modify_record) + } + + fn paint_line>(&mut self, start: P, end: P) -> Result, ()> { + let start = self.idx_at_coord(start).ok_or(())?; + let end = self.idx_at_coord(end).ok_or(())?; + let line_coords = self.pixmap.get_line(start, end); + let mut line_modify_record = vec![]; + let val = self.active_color; + for point in line_coords { + let circle_around_point = self.pixmap.get_circle(point, self.brush_size as u32); + for c in circle_around_point { + let old_val = self.pixmap.set(c, val); + line_modify_record.push(ModifyRecord::new(c, old_val, val)); } } - return Err(()); + Ok(line_modify_record) } fn apply_operation(&mut self, op: Operation, op_kind: OpKind) { @@ -176,6 +145,17 @@ impl<'ctx> AppState<'ctx> { } } + fn commit_operation(&mut self) { + if !self.current_operation.is_empty() { + let op = self + .current_operation + .drain(..) + .filter(|v| !v.old_val == v.val) + .collect::>(); + self.undo_stack.push(op); + } + } + fn zoom_in(&mut self, p: (i32, i32)) { // attempt to center around cursor if let Some(p) = self.idx_at_coord(p) { @@ -192,8 +172,8 @@ impl<'ctx> AppState<'ctx> { self.brush_size += 1; } - fn descrease_brush_size(&mut self) { - if self.brush_size > 1 { + fn decrease_brush_size(&mut self) { + if self.brush_size > 0 { self.brush_size -= 1; } } @@ -296,7 +276,7 @@ impl<'ctx> AppState<'ctx> { Self { start: Point::new(60, 60), zoom: 5, - brush_size: 1, + brush_size: 0, pixmap, grid: Grid::new(), canvas, @@ -339,12 +319,25 @@ impl<'ctx> AppState<'ctx> { self.modify(|e| e.zoom_out(cursor)); } // brush ops - Keycode::Q => self.modify(|e| e.descrease_brush_size()), - Keycode::E => self.modify(|e| e.increase_brush_size()), + Keycode::Q => self.decrease_brush_size(), + Keycode::E => self.increase_brush_size(), // flip color Keycode::X => self.modify(|e| e.change_active_color()), // toggle grid Keycode::Tab => self.modify(|e| e.toggle_grid()), + // line drawing + Keycode::F => self.modify(|e| { + let end = (mouse.x(), mouse.y()).into(); + if let Some(start) = e.last_point { + if let Ok(o) = e.paint_line(start, end) { + e.commit_operation(); + e.current_operation = + o.into_iter().filter(|v| !v.old_val == v.val).collect(); + e.commit_operation(); + e.last_point = Some(end); + } + } + }), // exit Keycode::Escape => break 'running, // undo & redo @@ -381,9 +374,7 @@ impl<'ctx> AppState<'ctx> { Event::MouseMotion { x, y, mousestate, .. } => { - let is_left = mousestate.is_mouse_button_pressed(MouseButton::Left); - let is_right = mousestate.is_mouse_button_pressed(MouseButton::Right); - if is_left { + if mousestate.is_mouse_button_pressed(MouseButton::Left) { self.modify(|e| { let pt = (x, y); let val = e.active_color; @@ -391,7 +382,7 @@ impl<'ctx> AppState<'ctx> { e.current_operation.extend(o); } }); - } else if is_right { + } else if mousestate.is_mouse_button_pressed(MouseButton::Right) { self.modify(|e| { let pt = (x, y); let val = !e.active_color; -- cgit v1.2.3