diff options
author | Colin Okay <colin@cicadas.surf> | 2022-07-20 09:42:03 -0500 |
---|---|---|
committer | Colin Okay <colin@cicadas.surf> | 2022-07-20 09:42:03 -0500 |
commit | 83a1b8cde2f8401a87b5f08c9b12cd26ce21f2b2 (patch) | |
tree | 901bb20d4ced5605050f776a38e29c2913038502 | |
parent | d8ce1f0a9cfea879864fb93b7ef960b5490cf50c (diff) |
[change] state saving forms
-rw-r--r-- | src/canvas-language.lisp | 51 |
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) |