1 ;;; Copyright (c) 2007 Zachary Beane, All Rights Reserved
3 ;;; Redistribution and use in source and binary forms, with or without
4 ;;; modification, are permitted provided that the following conditions
7 ;;; * Redistributions of source code must retain the above copyright
8 ;;; notice, this list of conditions and the following disclaimer.
10 ;;; * Redistributions in binary form must reproduce the above
11 ;;; copyright notice, this list of conditions and the following
12 ;;; disclaimer in the documentation and/or other materials
13 ;;; provided with the distribution.
15 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
16 ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19 ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 ;;; $Id: graphics-state.lisp,v 1.15 2007/10/01 02:24:44 xach Exp $
31 (defconstant +png-channels
+ 4)
32 (defconstant +png-color-type
+ :truecolor-alpha
)
33 (defvar *default-character-spacing
* 1.0d0
)
35 (defclass graphics-state
()
52 :initarg
:stroke-color
53 :accessor stroke-color
)
59 :accessor dash-vector
)
68 :accessor fill-source
)
76 :initarg
:transform-matrix
77 :accessor transform-matrix
)
79 :initarg
:clipping-path
80 :accessor clipping-path
)
82 :initarg
:after-paint-fun
83 :accessor after-paint-fun
)
85 :initarg
:font-loaders
86 :accessor font-loaders
)
91 :initarg
:character-spacing
92 :accessor character-spacing
))
96 :stroke-color
(make-instance 'rgba-color
)
100 :fill-color
(make-instance 'rgba-color
)
104 :transform-matrix
(scaling-matrix 1.0 -
1.0)
105 :after-paint-fun
(constantly nil
)
106 :font-loaders
(make-hash-table :test
'equal
)
108 :character-spacing
*default-character-spacing
*))
110 (defgeneric image-data
(state)
112 (zpng:image-data
(image state
))))
114 (defgeneric transform-function
(state)
115 (:documentation
"Return a function that takes x, y coordinates
116 and returns them transformed by STATE's current transformation
117 matrix as multiple values.")
119 (make-transform-function (transform-matrix state
))))
122 (defgeneric call-after-painting
(state fun
)
124 "Call FUN after painting, and reset the post-painting fun to a no-op.")
126 (setf (after-paint-fun state
)
129 (setf (after-paint-fun state
) (constantly nil
))))))
131 (defgeneric after-painting
(state)
132 (:documentation
"Invoke the post-painting function.")
134 (funcall (after-paint-fun state
))))
137 (defgeneric apply-matrix
(state matrix
)
138 (:documentation
"Replace the current transform matrix of STATE
139 with the result of premultiplying it with MATRIX.")
140 (:method
(state matrix
)
141 (let ((old (transform-matrix state
)))
142 (setf (transform-matrix state
) (mult matrix old
)))))
144 (defgeneric clear-paths
(state)
145 (:documentation
"Clear out any paths in STATE.")
147 (setf (paths state
) nil
149 (after-paint-fun state
) (constantly nil
))))
151 (defmethod (setf paths
) :after
(new-value (state graphics-state
))
152 (setf (path state
) (first new-value
)))
154 (defun state-image (state width height
)
155 "Set the backing image of the graphics state to an image of the
156 specified dimensions."
158 (make-instance 'zpng
:png
161 :color-type
+png-color-type
+)
163 (height state
) height
164 (clipping-path state
) (make-clipping-path width height
))
165 (apply-matrix state
(translation-matrix 0 (- height
))))
168 (defun find-font-loader (state file
)
169 (let* ((cache (font-loaders state
))
170 (key (namestring (truename file
))))
171 (or (gethash key cache
)
172 (setf (gethash key cache
) (zpb-ttf:open-font-loader file
)))))
174 (defgeneric close-font-loaders
(state)
175 (:documentation
"Close any font loaders that were obtained with GET-FONT.")
177 (maphash (lambda (filename loader
)
178 (declare (ignore filename
))
179 (ignore-errors (zpb-ttf:close-font-loader loader
)))
180 (font-loaders state
))))
182 (defgeneric clear-state
(state)
183 (:documentation
"Clean up any state in STATE.")
184 (:method
((state graphics-state
))
185 (close-font-loaders state
)))
187 (defun clear-fill-source (state)
188 (setf (fill-source state
) nil
))
190 (defmethod copy ((state graphics-state
))
191 (make-instance 'graphics-state
194 :height
(height state
)
197 :stroke-color
(copy (stroke-color state
))
198 :line-width
(line-width state
)
199 :dash-vector
(copy-seq (dash-vector state
))
200 :dash-phase
(dash-phase state
)
201 :fill-color
(copy (fill-color state
))
202 :fill-source
(fill-source state
)
203 :join-style
(join-style state
)
204 :cap-style
(cap-style state
)
205 :transform-matrix
(copy-seq (transform-matrix state
))
206 :clipping-path
(copy (clipping-path state
))
207 :after-paint-fun
(after-paint-fun state
)
208 :font-loaders
(font-loaders state
)
210 :character-spacing
(character-spacing state
)))