aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-28 05:21:26 +0100
committerAkshay <[email protected]>2021-03-28 05:21:26 +0100
commitbbfca639547fcd08e51181b70e449e71281d1d9b (patch)
treee4f420286daf694624a7d7df33b2c517cd231143
parentd0d222c3f7e765437f2fdfa5754654a8a815f52e (diff)
add new brush type
-rw-r--r--src/brush.rs73
-rw-r--r--src/lisp/error.rs2
-rw-r--r--src/lisp/eval.rs1
-rw-r--r--src/lisp/expr.rs1
-rw-r--r--src/lisp/prelude.rs21
-rw-r--r--src/main.rs1
6 files changed, 98 insertions, 1 deletions
diff --git a/src/brush.rs b/src/brush.rs
new file mode 100644
index 0000000..98c2b23
--- /dev/null
+++ b/src/brush.rs
@@ -0,0 +1,73 @@
1use std::fmt;
2
3use crate::bitmap::MapPoint;
4
5#[derive(Debug, Copy, Clone)]
6pub enum Brush {
7 Line {
8 size: u8,
9 start: Option<MapPoint>,
10 extend: bool,
11 },
12 Circle {
13 size: u8,
14 },
15 RectSelect {
16 start: MapPoint,
17 end: MapPoint,
18 },
19 Fill,
20 Custom {
21 size: u8,
22 },
23}
24
25impl Brush {
26 pub fn grow(&mut self) -> Result<(), BrushError> {
27 match self {
28 Brush::Line { ref mut size, .. } => *size += 1,
29 Brush::Circle { ref mut size, .. } => *size += 1,
30 Brush::Custom { ref mut size, .. } => *size += 1,
31 _ => return Err(BrushError::CannotIncreaseSize),
32 }
33 Ok(())
34 }
35 pub fn shrink(&mut self) -> Result<(), BrushError> {
36 match self {
37 Brush::Line { ref mut size, .. } => *size += size.saturating_sub(1),
38 Brush::Circle { ref mut size, .. } => *size += size.saturating_sub(1),
39 Brush::Custom { ref mut size, .. } => *size += size.saturating_sub(1),
40 _ => return Err(BrushError::CannotIncreaseSize),
41 }
42 Ok(())
43 }
44 pub fn new() -> Self {
45 Brush::Circle { size: 0 }
46 }
47 pub fn line(size: u8, extend: bool) -> Self {
48 Brush::Line {
49 size,
50 start: None,
51 extend,
52 }
53 }
54 pub fn is_line(&self) -> bool {
55 matches!(self, Self::Line { .. })
56 }
57}
58
59impl fmt::Display for Brush {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 Brush::Line { extend, .. } => write!(f, "LINE{}", if *extend { "+" } else { "" }),
63 Brush::Circle { .. } => write!(f, "CIRCLE"),
64 Brush::RectSelect { .. } => write!(f, "SELECT"),
65 Brush::Fill => write!(f, "FILL"),
66 Brush::Custom { .. } => write!(f, "CUSTOM"),
67 }
68 }
69}
70
71pub enum BrushError {
72 CannotIncreaseSize,
73}
diff --git a/src/lisp/error.rs b/src/lisp/error.rs
index b90e211..a360eb2 100644
--- a/src/lisp/error.rs
+++ b/src/lisp/error.rs
@@ -90,6 +90,7 @@ pub enum EvalError {
90 DivByZero, 90 DivByZero,
91 TypeMismatch, 91 TypeMismatch,
92 NoFileName, 92 NoFileName,
93 CustomInternal(&'static str),
93} 94}
94 95
95impl fmt::Display for EvalError { 96impl fmt::Display for EvalError {
@@ -112,6 +113,7 @@ impl fmt::Display for EvalError {
112 Self::TypeMismatch => write!(f, "mismatched types"), 113 Self::TypeMismatch => write!(f, "mismatched types"),
113 Self::DivByZero => write!(f, "attempt to divide by zero"), 114 Self::DivByZero => write!(f, "attempt to divide by zero"),
114 Self::NoFileName => write!(f, "no file name specified"), 115 Self::NoFileName => write!(f, "no file name specified"),
116 Self::CustomInternal(s) => write!(f, "{}", s),
115 } 117 }
116 } 118 }
117} 119}
diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs
index 370b624..6ffff23 100644
--- a/src/lisp/eval.rs
+++ b/src/lisp/eval.rs
@@ -20,6 +20,7 @@ pub fn eval(expr: &LispExpr, app: &mut AppState) -> Result<LispExpr, LispError>
20 LispExpr::Number(_) => Ok(expr.clone()), 20 LispExpr::Number(_) => Ok(expr.clone()),
21 LispExpr::BoolLit(_) => Ok(expr.clone()), 21 LispExpr::BoolLit(_) => Ok(expr.clone()),
22 LispExpr::Ident(ref id) => lookup_extended(&app.lisp_env, id), 22 LispExpr::Ident(ref id) => lookup_extended(&app.lisp_env, id),
23 LispExpr::Quote(_, _) => Ok(expr.clone()),
23 LispExpr::List(li) => { 24 LispExpr::List(li) => {
24 let func_expr = &li[0]; 25 let func_expr = &li[0];
25 match func_expr { 26 match func_expr {
diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs
index 40420a1..9ef9f65 100644
--- a/src/lisp/expr.rs
+++ b/src/lisp/expr.rs
@@ -222,6 +222,7 @@ impl AsRef<str> for LispExpr {
222 fn as_ref(&self) -> &str { 222 fn as_ref(&self) -> &str {
223 match self { 223 match self {
224 LispExpr::StringLit(i) => &i, 224 LispExpr::StringLit(i) => &i,
225 LispExpr::Ident(i) => &i,
225 _ => panic!("invalid downcast!"), 226 _ => panic!("invalid downcast!"),
226 } 227 }
227 } 228 }
diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs
index 6153e4f..d2a6ae6 100644
--- a/src/lisp/prelude.rs
+++ b/src/lisp/prelude.rs
@@ -1,7 +1,8 @@
1use crate::{ 1use crate::{
2 brush::Brush,
2 lisp::{ 3 lisp::{
3 error::{EvalError, LispError}, 4 error::{EvalError, LispError},
4 expr::{Arity, LispExpr}, 5 expr::{is_ident, Arity, LispExpr},
5 number::LispNumber, 6 number::LispNumber,
6 Environment, 7 Environment,
7 }, 8 },
@@ -193,5 +194,23 @@ pub fn new_env() -> Environment {
193 return Ok(LispExpr::Unit); 194 return Ok(LispExpr::Unit);
194 }); 195 });
195 196
197 primitive!(env, Arity::Atmost(1), "brush", |args, app| {
198 info!("brush {}", &args[0]);
199 if let [LispExpr::Quote(kind, _)] = args {
200 if is_ident(kind) {
201 match (&**kind).as_ref() {
202 "fill" => app.brush = Brush::Fill,
203 "circle" => app.brush = Brush::new(),
204 "line" => app.brush = Brush::line(0, false),
205 "line-extend" => app.brush = Brush::line(0, true),
206 _ => return Err(EvalError::CustomInternal("unknown brush type").into()),
207 }
208 }
209 } else {
210 return Err(EvalError::TypeMismatch.into());
211 }
212 return Ok(LispExpr::Unit);
213 });
214
196 env 215 env
197} 216}
diff --git a/src/main.rs b/src/main.rs
index 1ecad69..34f087a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
1mod app; 1mod app;
2mod bitmap; 2mod bitmap;
3mod brush;
3mod command; 4mod command;
4mod consts; 5mod consts;
5mod dither; 6mod dither;