aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorColin Okay <colin@cicadas.surf>2022-07-20 09:42:03 -0500
committerColin Okay <colin@cicadas.surf>2022-07-20 09:42:03 -0500
commit83a1b8cde2f8401a87b5f08c9b12cd26ce21f2b2 (patch)
tree901bb20d4ced5605050f776a38e29c2913038502
parentd8ce1f0a9cfea879864fb93b7ef960b5490cf50c (diff)
[change] state saving forms
-rw-r--r--src/canvas-language.lisp51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/canvas-language.lisp b/src/canvas-language.lisp
index 7ea72a4..610c8e0 100644
--- a/src/canvas-language.lisp
+++ b/src/canvas-language.lisp
@@ -2,17 +2,17 @@
(in-package #:wheelwork)
-(defvar *current-canvas* nil
- "Bound by with-canvas")
+(defvar *current-canvas* nil)
(defvar *current-pen-color* '(0 0 0 255))
-
(defvar *current-pen-width* 1)
-
(defvar *current-pen-position* '(0 0))
-
(defvar *saved-state* nil)
-(defmacro with-canvas-state (&body body)
+(defmacro with-current-pen-state ( &body body)
+ "Saves the current pen state (color width position) so that it can
+ be restored from using (restore-pen-state) from within the BODY.
+ After BODY executes the state is restored to whatever it was
+ before WITH-CURRENT-PEN-STATE was evaluated."
`(let
((*saved-state*
(list *current-pen-width*
@@ -20,22 +20,42 @@
*current-pen-color*)))
,@body))
+(defmacro with-pen ((&key position (color nil color-supplied-p) width) &body body)
+ "Like WITH-CURRENT-PEN-STATE, but lets you set the state of the pen
+ EXECUTION BODY. After BODY executes, the state is restored to
+ whatever it was before WITH-PEN-STATE was evaluated."
+ `(let ((*current-pen-position* ,(if position nil '*current-pen-position*))
+ (*current-pen-color* ,(if color-supplied-p nil '*current-pen-color*))
+ (*current-pen-width* ,(if width nil '*current-pen-width*)))
+ ,(when position
+ `(move-to ,@position))
+ ,(when color-supplied-p
+ `(canvas-pen-color ,color))
+ ,(when width
+ `(canvas-pen-width ,width))
+ (with-current-pen-state
+ ,@body)))
+
(defmacro with-pen-color (list-or-fn &body body)
+ "Temporarily bind pen color to the value of LIST-OR-FN and execute BODY."
`(let ((*current-pen-color* nil))
(canvas-pen-color ,list-or-fn)
,@body))
(defmacro with-canvas (canvas &body body)
+ "Perform drawing commands in BODY using the value of CANVAS as the
+ target of any drawing operations."
`(let ((*current-canvas* ,canvas)
(*current-pen-width* 1)
(*current-pen-position* (list 0 0))
(*current-pen-color* (list 0 0 0 255)))
- (with-canvas-state
+ (with-current-pen-state
,@body)))
-
-(defun restore-canvas-state ()
+(defun restore-pen ()
+ "Restore the state of the pan (width position color) as previously
+saved by WITH-PEN-STATE"
(destructuring-bind (pw pp pc) *saved-state*
(setf *current-pen-width* pw
*current-pen-position* pp
@@ -46,6 +66,19 @@
(round (clamp 0 c 255)))
(defun canvas-pen-color (&optional newpen)
+ "Set the pens color in the current context. NEWPEN, if supplied, can be one of:
+
+ NIL - set the color to black.
+
+ A list of four unsigned 8 bit integers that looks like (R G B A).
+
+ A function (or symbol naming a function) that accepts the
+ coordinates X Y of the pixel being drawn and returns a list as in
+ the above case.
+
+ All RGBA component values obtained from a pen (either from the
+ return of a functional pen or as members of a list value) are
+ clamped between 0 and 255."
(setf *current-pen-color*
(etypecase newpen
(null nil)