3 <title>Vecto - Simple Vector Drawing with Common Lisp
</title>
4 <style type=
"text/css">
5 a
, a:visited
{ text-decoration: none
}
6 a
[href
]:hover
{ text-decoration: underline
}
7 pre
{ background: #DDD; padding: 0.25em }
8 p
.download
{ color: red
}
9 .transparent { background-image: url
(background.gif) }
15 <h2>Vecto - Simple Vector Drawing with Common Lisp
</h2>
17 <blockquote class='abstract'
>
20 <p>Vecto is a simplified interface to the
21 powerful
<a href=
"http://projects.tuxee.net/cl-vectors/">CL-VECTORS
</a>
22 vector rasterization library. It presents a function-oriented
23 interface similar to
<a href=
"http://www.cliki.net/CL-PDF">CL-PDF
</a>,
24 but the results can be saved to a PNG instead of a PDF file. Since
25 Vecto and all supporting libraries are written completely in Common
26 Lisp, without depending on external non-Lisp libraries, it should work
27 in any Common Lisp environment. Vecto is available under a BSD-like
28 license. The current version is
1.1, released on January
1st,
31 <p>Vecto is used by
<a href=
"http://wigflip.com/easystreet/">Easystreet
</a>.
33 <p>The canonical location for Vecto
34 is
<a href=
"http://www.xach.com/lisp/vecto/">http://www.xach.com/lisp/vecto/
</a>.
36 <p class='download'
>Download shortcut:
</p>
38 <p><a href=
"http://www.xach.com/lisp/vecto.tgz">http://www.xach.com/lisp/vecto.tgz
</a>
45 <li> <a href='#sect-overview-and-limitations'
>Overview and Limitations
</a>
46 <li> <a href='#sect-examples'
>Examples
</a>
47 <li> <a href='#sect-dictionary'
>Dictionary
</a>
50 <li> <a href='#sect-canvases'
>Canvases
</a>
52 <li> <a href='#with-canvas'
><tt>with-canvas
</tt></a>
53 <li> <a href='#clear-canvas'
><tt>clear-canvas
</tt></a>
54 <li> <a href='#save-png'
><tt>save-png
</tt></a>
55 <li> <a href='#save-png-stream'
><tt>save-png-stream
</tt></a>
58 <li> <a href='#sect-graphics-state'
>Graphics State
</a>
60 <li> <a href='#with-graphics-state'
><tt>with-graphics-state
</tt></a>
61 <li> <a href='#set-rgba-fill'
><tt>set-rgba-fill
</tt></a>
62 <li> <a href='#set-rgba-fill'
><tt>set-rgb-fill
</tt></a>
63 <li> <a href='#set-rgba-stroke'
><tt>set-rgba-stroke
</tt></a>
64 <li> <a href='#set-rgba-stroke'
><tt>set-rgb-stroke
</tt></a>
65 <li> <a href='#set-line-cap'
><tt>set-line-cap
</tt></a>
66 <li> <a href='#set-line-join'
><tt>set-line-join
</tt></a>
67 <li> <a href='#set-line-width'
><tt>set-line-width
</tt></a>
68 <li> <a href='#set-dash-pattern'
><tt>set-dash-pattern
</tt></a>
69 <li> <a href='#translate'
><tt>translate
</tt></a>
70 <li> <a href='#rotate'
><tt>rotate
</tt></a>
71 <li> <a href='#scale'
><tt>scale
</tt></a>
72 <li> <a href='#skew'
><tt>skew
</tt></a>
73 <li> <a href='#clip-path'
><tt>clip-path
</tt></a>
74 <li> <a href='#even-odd-clip-path'
><tt>even-odd-clip-path
</tt></a>
77 <li> <a href='#sect-paths'
>Paths
</a>
79 <li> <a href='#move-to'
><tt>move-to
</tt></a>
80 <li> <a href='#line-to'
><tt>line-to
</tt></a>
81 <li> <a href='#curve-to'
><tt>curve-to
</tt></a>
82 <li> <a href='#quadratic-to'
><tt>quadratic-to
</tt></a>
83 <li> <a href='#arc'
><tt>arc
</tt></a>
84 <li> <a href='#arcn'
><tt>arcn
</tt></a>
85 <li> <a href='#close-subpath'
><tt>close-subpath
</tt></a>
86 <li> <a href='#rectangle'
><tt>rectangle
</tt></a>
87 <li> <a href='#rounded-rectangle'
><tt>rounded-rectangle
</tt></a>
88 <li> <a href='#centered-ellipse-path'
><tt>centered-ellipse-path
</tt></a>
89 <li> <a href='#centered-circle-path'
><tt>centered-circle-path
</tt></a>
92 <li> <a href='#sect-painting'
>Painting
</a>
94 <li> <a href='#fill-path'
><tt>fill-path
</tt></a>
95 <li> <a href='#even-odd-fill'
><tt>even-odd-fill
</tt></a>
96 <li> <a href='#stroke'
><tt>stroke
</tt></a>
97 <li> <a href='#fill-and-stroke'
><tt>fill-and-stroke
</tt></a>
98 <li> <a href='#even-odd-fill-and-stroke'
><tt>even-odd-fill-and-stroke
</tt></a>
99 <li> <a href='#end-path-no-op'
><tt>end-path-no-op
</tt></a>
102 <li> <a href='#sect-text'
>Text
</a>
104 <li> <a href='#get-font'
><tt>get-font
</tt></a>
105 <li> <a href='#set-font'
><tt>set-font
</tt></a>
106 <li> <a href='#draw-string'
><tt>draw-string
</tt></a>
107 <li> <a href='#draw-centered-string'
><tt>draw-centered-string
</tt></a>
108 <li> <a href='#string-bounding-box'
><tt>string-bounding-box
</tt></a>
111 <li> <a href='#sect-miscellaneous'
>Miscellaneous
</a>
113 <li> <a href='#const-kappa'
><tt>+kappa+
</tt></a>
118 <li> <a href='#sect-references'
>References
</a>
119 <li> <a href='#sect-acknowledgements'
>Acknowledgements
</a>
120 <li> <a href='#sect-feedback'
>Feedback
</a>
124 <a name='sect-overview-and-limitations'
><h3>Overview and Limitations
</h3></a>
126 <p>Vecto is a library that provides a simple interface to the
127 the
<a href=
"http://projects.tuxee.net/cl-vectors/">CL-VECTORS
</a>
128 vector drawing library. It supports drawing on a canvas and saving the
129 results to a PNG file.
131 <p>Vecto depends on the following libraries:
134 <li> <a href=
"http://projects.tuxee.net/cl-vectors/">CL-VECTORS
</a>
135 <li> <a href=
"http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF
</a>
136 <li> <a href=
"http://www.xach.com/lisp/salza2/">Salza2
</a>
137 <li> <a href=
"http://www.xach.com/lisp/zpng/">ZPNG
</a>
140 <p>The easiest way to install Vecto and all its dependencies is
141 with
<a href=
"http://www.cliki.net/asdf-install">ASDF-Install
</a>.
143 <p>Vecto's function interface is similar to the
144 PDF vector description and painting interface: you create images by
145 describing vector paths, then using stroke or fill operations to paint
148 <p>Vecto's color system uses red, green, blue, and alpha color
149 components for drawing. The results can be be saved to a PNG with an
152 <p>Vecto's coordinate system starts at the lower-left corner of the
153 image, and increases rightwards along the X axis and upwards along the
156 <p>All measurements are in pixels.
158 <p>PDF is a feature-rich system. Vecto supports a small subset of
159 PDF-style operations. In particular, it does not support:
163 <li> pattern, gradient, or functional fill
164 <li> complex layout of text
165 <li> PostScript fonts
166 <li> non-RGB color spaces
169 <p>Other limitations:
172 <li> No output formats other than
8-bit, truecolor-alpha PNGs
173 <li> No access to underlying pixel data
176 <p>Related libraries:
179 <li> <a href=
"http://common-lisp.net/project/imago/">Imago
</a>
181 <li> <a href=
"http://cyrusharmon.org/projects?project=ch-image">ch-image
</a>
183 <li> <a href=
"http://ygingras.net/poly-pen">Poly-pen
</a>
187 <a name='sect-examples'
><h3>Examples
</h3></a>
189 <p>All examples are available in
<tt>doc/examples.lisp
</tt> in the Vecto
190 distribution. That file starts with:
193 (defpackage #:vecto-examples
196 (in-package #:vecto-examples)
201 <img border=
0 align=right src='lambda-example.png'
202 >(defun radiant-lambda (file)
203 (
<a href='#with-canvas'
>with-canvas
</a> (:width
90 :height
90)
204 (let ((font (
<a href='#get-font'
>get-font
</a> "times.ttf"))
206 (
<a href='#set-font'
>set-font
</a> font
40)
207 (
<a href='#translate'
>translate
</a> 45 45)
208 (
<a href='#draw-centered-string'
>draw-centered-string
</a> 0 -
10 #(#x3BB))
209 (
<a href='#set-rgb-stroke'
>set-rgb-stroke
</a> 1 0 0)
210 (
<a href='#centered-circle-path'
>centered-circle-path
</a> 0 0 35)
211 (
<a href='#stroke'
>stroke
</a>)
212 (
<a href='#set-rgba-stroke'
>set-rgba-stroke
</a> 0 0 1.0 0.5)
213 (
<a href='#set-line-width'
>set-line-width
</a> 4)
215 (
<a href='#with-graphics-state'
>with-graphics-state
</a>
216 (
<a href='#rotate'
>rotate
</a> (* i step))
217 (
<a href='#move-to'
>move-to
</a> 30 0)
218 (
<a href='#line-to'
>line-to
</a> 40 0)
220 (
<a href='#save-png'
>save-png
</a> file))))
224 <img align=right src='feedlike-icon.png'
225 >(defun feedlike-icon (file)
226 (with-canvas (:width
100 :height
100)
227 (set-rgb-fill
1.0 0.65 0.3)
228 (
<a href='#rounded-rectangle'
>rounded-rectangle
</a> 0 0 100 100 10 10)
229 (
<a href='#fill-path'
>fill-path
</a>)
230 (set-rgb-fill
1.0 1.0 1.0)
231 (centered-circle-path
20 20 10)
233 (flet ((quarter-circle (x y radius)
234 (let ((kappa (*
<a href='#const-kappa'
>+kappa+
</a> radius)))
235 (move-to (+ x radius) y)
236 (curve-to (+ x radius) (+ y kappa)
237 (+ x kappa) (+ y radius)
239 (set-rgb-stroke
1.0 1.0 1.0)
241 (quarter-circle
20 20 30)
243 (quarter-circle
20 20 60)
248 <pre><div style='float: right' class='transparent'
><img src='star-clipping.png'
249 ></div>(defun star-clipping (file)
250 (with-canvas (:width
200 :height
200)
253 (step (*
2 (/ (* pi
2)
5))))
254 (translate size size)
257 (setf angle (+ angle step))
258 (line-to (* (sin angle) size)
259 (* (cos angle) size)))
260 (
<a href='#even-odd-clip-path'
><tt>even-odd-clip-path
</tt></a>)
261 (
<a href='#end-path-no-op'
><tt>end-path-no-op
</tt></a>)
262 (flet ((circle (distance)
263 (
<a href='#set-rgba-fill'
><tt>set-rgba-fill
</tt></a> distance
0 0
265 (centered-circle-path
0 0 (* size distance))
267 (loop for i downfrom
1.0 by
0.05
273 <a name='sect-dictionary'
><h3>Dictionary
</h3></a>
275 <p>The following symbols are exported from the
<tt>VECTO
</tt> package.
277 <a name='sect-canvases'
><h4>Canvases
</h4></a>
279 <p><a name='with-canvas'
>[Macro]
</a><br>
280 <b>with-canvas
</b> (
<tt>&key
</tt> <i>width
</i> <i>height
</i>)
281 <tt>&body
</tt> <i>body
</i>
284 Evaluates
<i>body
</i> with a canvas established with the specified
285 dimensions as the target for drawing commands. The canvas is initially
286 completely clear (all pixels have
0 alpha).
290 <p><a name='clear-canvas'
>[Function]
</a><br>
291 <b>clear-canvas
</b> =
> |
294 Completely fills the canvas with the current fill color. Any marks on
295 the canvas are cleared.
299 <p><a name='save-png'
>[Function]
</a><br>
300 <b>save-png
</b> <i>file
</i> =
> <i>truename
</i>
303 Writes the contents of the canvas as the PNG
<i>file
</i>, and returns
304 the truename of
<i>file
</i>.
308 <p><a name='save-png-stream'
>[Function]
</a><br>
309 <b>save-png-stream
</b> <i>stream
</i> =
> |
312 Writes the contents of the canvas as a PNG to
<i>stream
</i>, which
313 must accept
<tt>(unsigned-byte
8)
</tt> data.
317 <a name='sect-graphics-state'
><h4>Graphics State
</h4></a>
319 <p>The graphics state stores several parameters used for graphic
322 <p><a name='with-graphics-state'
>[Macro]
</a><br>
323 <b>with-graphics-state
</b> <tt>&body
</tt> <i>body
</i>
326 Evaluates the forms of
<i>body
</i> with a copy of the current graphics
327 state. Any modifications to the state are undone at the end of the
332 <p><a name='set-rgba-fill'
>[Functions]
</a><br>
333 <b>set-rgba-fill
</b> <i>r
</i> <i>g
</i> <i>b
</i> <i>alpha
</i> =
> |
<br>
334 <b>set-rgb-fill
</b> <i>r
</i> <i>g
</i> <i>b
</i> =
> |
337 Sets the fill color.
<i>r
</i>,
<i>g
</i>,
<i>b
</i>, and
<i>alpha
</i>
338 should be in the range of
0.0 to
1.0.
340 <p><tt>set-rgb-fill
</tt> is the same as
<tt>set-rgba-fill
</tt> with an
341 implicit alpha value of
1.0.
343 <p>The fill color is used
345 href='#clear-canvas'
><tt>CLEAR-CANVAS
</tt></a>,
<a
346 href='#fill-path'
><tt>FILL-PATH
</tt></a>,
<a
347 href='#even-odd-fill'
><tt>EVEN-ODD-FILL
</tt></a>,
<a
348 href='#fill-and-stroke'
><tt>FILL-AND-STROKE
</tt></a>,
<a
349 href='#even-odd-fill-and-stroke'
><tt>EVEN-ODD-FILL-AND-STROKE
</tt></a>,
350 and
<a href='#draw-string'
><tt>DRAW-STRING
</tt></a>.
354 <p><a name='set-rgba-stroke'
>[Functions]
</a><br>
355 <b>set-rgba-stroke
</b> <i>r
</i> <i>g
</i> <i>b
</i> <i>alpha
</i> =
> |
<br>
356 <b>set-rgb-stroke
</b> <i>r
</i> <i>g
</i> <i>b
</i> =
> |
359 Sets the stroke color.
<i>r
</i>,
<i>g
</i>,
<i>b
</i>, and
<i>alpha
</i>
360 should be in the range of
0.0 to
1.0.
362 <p><tt>set-rgb-stroke
</tt> is the same as
<tt>set-rgba-stroke
</tt>
363 with an implicit alpha value of
1.0.
365 <p>The stroke color is used for
<a href='#stroke'
><tt>STROKE
</tt></a>,
366 <a href='#fill-and-stroke'
><tt>FILL-AND-STROKE
</tt></a>,
367 and
<a href='#even-odd-fill-and-stroke'
><tt>EVEN-ODD-FILL-AND-STROKE
</tt></a>.
371 <p><a name='set-line-cap'
>[Function]
</a><br>
372 <b>set-line-cap
</b> <i>style
</i> =
> |
375 Sets the line cap style to
<i>style
</i>, which must be one
376 of
<tt>:BUTT
</tt>,
<tt>:SQUARE
</tt>, or
<tt>:ROUND
</tt>. The initial
377 value is
<tt>:BUTT
</tt>.
379 <p><table cellspacing=
5 id=
"line-cap">
381 <td align=center
><img src=
"cap-style-butt.png"></td>
382 <td align=center
><img src=
"cap-style-square.png"></td>
383 <td align=center
><img src=
"cap-style-round.png"></td>
386 <td align=center
><tt>:BUTT
</tt></td>
387 <td align=center
><tt>:SQUARE
</tt></td>
388 <td align=center
><tt>:ROUND
</tt></td>
395 <p><a name='set-line-join'
>[Function]
</a><br>
396 <b>set-line-join
</b> <i>style
</i> =
> |
399 Sets the line join style to
<i>style
</i>, which must be one
400 of
<tt>:MITER
</tt>,
<tt>:BEVEL
</tt>, or
<tt>:ROUND
</tt>. The initial
401 value is
<tt>:MITER
</tt>.
403 <p><table cellspacing=
5 id=
"line-join">
405 <td align=center
><img src=
"join-style-miter.png"></td>
406 <td align=center
><img src=
"join-style-bevel.png"></td>
407 <td align=center
><img src=
"join-style-round.png"></td>
410 <td align=center
><tt>:MITER
</tt></td>
411 <td align=center
><tt>:BEVEL
</tt></td>
412 <td align=center
><tt>:ROUND
</tt></td>
419 <p><a name='set-line-width'
>[Function]
</a><br>
420 <b>set-line-width
</b> <i>width
</i> =
> |
423 Sets the line width for strokes to
<i>width
</i>.
428 <p><a name='set-dash-pattern'
>[Function]
</a><br>
429 <b>set-dash-pattern
</b> <i>dash-vector
</i> <i>phase
</i> =
> |
432 Sets the dash pattern according to
<i>dash-vector
</i> and
<i>phase
</i>.
434 <p><i>dash-vector
</i> should be a vector of numbers denoting on and
435 off patterns for a stroke. An empty
<i>dash-vector
</i> is the same as
436 having no dash pattern at all.
438 <p><i>phase
</i> is how far along the dash pattern to proceed before
439 applying the pattern to the current stroke.
445 <th>Dash Vector and Phase
</th>
448 <td align=center
><img src=
"dash-pattern-none.png"></td>
449 <td align=left
><tt>#()
0</tt></td>
452 <td align=center
><img src=
"dash-pattern-a.png"></td>
453 <td align=left
><tt>#(
30 30)
0</tt></td>
456 <td align=center
><img src=
"dash-pattern-b.png"></td>
457 <td align=left
><tt>#(
30 30)
15</tt></td>
460 <td align=center
><img src=
"dash-pattern-c.png"></td>
461 <td align=left
><tt>#(
10 20 10 40)
0</tt></td>
464 <td align=center
><img src=
"dash-pattern-d.png"></td>
465 <td align=left
><tt>#(
10 20 10 40)
13</tt></td>
468 <td align=center
><img src=
"dash-pattern-e.png"></td>
469 <td align=left
><tt>#(
30 30)
0</tt>,
<tt>:ROUND
</tt> line caps
</td>
475 <p><a name='translate'
>[Function]
</a><br>
476 <b>translate
</b> <i>x
</i> <i>y
</i> =
> |
479 Offsets the coordinate system by
<i>x
</i> units horizontally
480 and
<i>y
</i> units vertically.
484 <p><a name='rotate'
>[Function]
</a><br>
485 <b>rotate
</b> <i>radians
</i> =
> |
488 Rotates the coordinate system by
<i>radians
</i>.
492 <p><a name='scale'
>[Function]
</a><br>
493 <b>scale
</b> <i>sx
</i> <i>sy
</i> =
> |
496 Scales the coordinate system by
<i>sx
</i> horizontally
497 and
<i>sy
</i> vertically.
501 <p><a name='skew'
>[Function]
</a><br>
502 <b>skew
</b> <i>ax
</i> <i>ay
</i> =
> |
505 Skews the X axis of the coordinate system by
<i>ax
</i> radians and the
506 Y axis by
<i>ay
</i> radians.
510 <p><a name='clip-path'
>[Function]
</a><br>
511 <b>clip-path
</b> =
> |
514 Defines a clipping path based on the current path. It is not applied
515 immediately, but is created after after the painting is done in the
518 href='#fill-path'
><tt>FILL-PATH
</tt></a>,
<a
519 href='#even-odd-fill'
><tt>EVEN-ODD-FILL
</tt></a>,
<a
520 href='#fill-and-stroke'
><tt>FILL-AND-STROKE
</tt></a>,
<a
521 href='#even-odd-fill-and-stroke'
><tt>EVEN-ODD-FILL-AND-STROKE
</tt></a>,
522 or
<a href='#end-path-no-op'
><tt>END-PATH-NO-OP
</tt></a>.
524 <p>The clipping path initially covers the entire canvas; no clipping
525 is done. Subsequent calls to
<tt>CLIP-PATH
</tt> set the clipping path
526 to the intersection of the established clipping path and the new
527 clipping path, and all drawing will be done within the outline of the
530 <p>The outline of the clipping path is defined with the nonzero
531 winding rule, as with
<a href='#fill-path'
><tt>FILL-PATH
</tt></a>.
533 <p>There is no way to enlarge the clipping path. However, the clipping
534 path is part of the graphics state, so changes may be localized by
535 using
<a href='#with-graphics-state'
><tt>WITH-GRAPHICS-STATE
</tt></a>.
540 <td><img src=
"clip-unclipped.png"></td>
541 <td>A filled red rectangle, not clipped
</td>
544 <td><img src=
"clip-to-circle.png"></td>
545 <td>The same rectangle drawn with a circle clipping path in effect
</td>
548 <td><img src=
"clip-to-rectangle.png"></td>
549 <td>Clipped to a rounded rectangle clipping path
</td>
552 <td><img src=
"clip-to-both.png"></td>
553 <td>Clipped to the intersection of the circle and rounded rectangle clipping paths
</td>
562 <p><a name='even-odd-clip-path'
>[Function]
</a><br>
563 <b>even-odd-clip-path
</b> =
> |
566 Like
<a href='#clip-path'
><tt>CLIP-PATH
</tt></a>, but uses the
567 even/odd fill rule to determine the outline of the clipping path.
571 <a name='sect-paths'
><h4>Paths
</h4></a>
573 <p>Paths are used to create lines for stroking or outlines for
574 filling. Paths consist of straight lines and curves. Paths consist of
575 one or more subpaths.
577 <p><a name='move-to'
>[Function]
</a><br>
578 <b>move-to
</b> <i>x
</i> <i>y
</i> =
> |
581 Starts a new subpath at (
<i>x
</i>,
<i>y
</i>).
<tt>move-to
</tt> must be the
582 first step of constructing a subpath.
586 <p><a name='line-to'
>[Function]
</a><br>
587 <b>line-to
</b> <i>x
</i> <i>y
</i> =
> |
590 Appends a straight line ending at (
<i>x
</i>,
<i>y
</i>) to the
595 <p><a name='curve-to'
>[Function]
</a><br>
597 <i>cx1
</i> <i>cy1
</i>
598 <i>cx2
</i> <i>cy2
</i>
599 <i>x
</i> <i>y
</i> =
> |
603 cubic
<a href=
"http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B
ézier
604 curve
</a> ending at (
<i>x
</i>,
<i>y
</i>) and with control
605 points (
<i>cx1
</i>,
<i>cy1
</i>) and (
<i>cx2
</i>,
<i>cy2
</i>) to the current
610 <p><a name='quadratic-to'
>[Function]
</a><br>
613 <i>x
</i> <i>y
</i> =
> |
616 Appends a quadratic B
ézier curve ending at (
<i>x
</i>,
<i>y
</i>)
617 and with the control point (
<i>cx
</i>,
<i>cy
</i>) to the current
622 <p><a name='arc'
>[Function]
</a><br>
623 <b>arc
</b> <i>x
</i> <i>y
</i> <i>radius
</i> <i>angle1
</i> <i>angle2
</i>
627 Appends an arc of a circle to the current path. The center of the arc is
628 at (
<i>x
</i>,
<i>y
</i>). The arc begins at point at a
629 distance
<i>radius
</i> from the center and with an angle
<i>angle1
</i>
630 radians from the positive x axis, and ends at the point
631 with
<i>angle2
</i> radians. If
<i>angle2
</i> is less
632 than
<i>angle1
</i>, it is increased by increasing multiples of
2π
633 until it is greater than or equal to
<i>angle1
</i>.
635 <p><table cellpadding=
5>
636 <tr><td align=center
><img src=
"arc.png"></td></tr>
637 <tr><td><span style='color: #
0f0'
><i>radius
</i></span>,
638 <span style='color: #f00'
><i>angle1
</i></span>,
639 <span style='color: #
00f'
><i>angle2
</i></span></td></tr>
642 <p>If there is a current point, a straight line is added from the
643 current point to the start point of the arc. Otherwise, a new path
646 <pre><img class='transparent' style='float: right' src='pie-wedge.png'
647 >(defun pie-wedge (file)
648 (with-canvas (:width
80 :height
60)
651 (angle1 (* (/ pi
180)
15))
652 (angle2 (* (/ pi
180)
45)))
656 (arc x y radius angle1 angle2)
664 <p><a name='arcn'
>[Function]
</a><br>
665 <b>arcn
</b> <i>x
</i> <i>y
</i> <i>radius
</i> <i>angle1
</i> <i>angle2
</i>
669 Like
<a href='#arc'
><tt>ARC
</tt></a>, but draws the arc clockwise
670 instead of counterclockwise. If
<i>angle2
</i> is greater
671 than
<i>angle1
</i>, it is decreased by increasing multiples of
2π
672 until it is less than or equal to
<i>angle1
</i>.
674 <pre><img class='transparent' style='float: right' src='wiper.png'
676 (with-canvas (:width
70 :height
70)
680 (angle2 (* (/ pi
180)
90)))
682 (set-rgba-fill
1 1 1 0.75)
683 (arc x y r1 angle1 angle2)
684 (arcn x y r2 angle2 angle1)
692 <p><a name='close-subpath'
>[Function]
</a><br>
693 <b>close-subpath
</b> =
> |
696 Closes the current subpath. If the current point is not the same as the
697 starting point for the subpath, appends a straight line from the
698 current point to the starting point of the current subpath.
700 <p>Subpaths with start and end points that coincidentally overlap are
701 not the same as closed subpaths. The distinction is important when
704 <p><table cellpadding=
5>
706 <td align=center
><img src=
"open-subpath.png"></td>
707 <td align=center
><img src=
"closed-subpath.png"></td>
710 <td align=center
>Open subpath
</td>
711 <td align=center
>Closed subpath
</td>
715 <p>If the subpath is not closed, the start and points of the subpath
716 will be drawn with the current line cap style. If the path is
717 closed, the start and endpoints will be treated as joined and drawn
718 with the line join style.
722 <p><a name='rectangle'
>[Function]
</a><br>
723 <b>rectangle
</b> <i>x
</i> <i>y
</i> <i>width
</i> <i>height
</i> =
> |
726 Creates a rectangular subpath with the given
<i>width
</i>
727 and
<i>height
</i> that has its lower-left corner at
728 (
<i>x
</i>,
<i>y
</i>). It is effectively the same as:
732 (line-to (+ x width) y)
733 (line-to (+ x width) (+ y height))
734 (line-to x (+ y height))
739 <p><a name='rounded-rectangle'
>[Function]
</a><br>
740 <b>rounded-rectangle
</b> <i>x
</i> <i>y
</i>
741 <i>width
</i> <i>height
</i> <i>rx
</i> <i>ry
</i> =
> |
744 Like
<a href='#rectangle'
><tt>RECTANGLE
</tt></a>, but rounds the
745 corners of the rectangle paths by the x radius
<i>rx
</i> and the y
749 <p><a name='centered-ellipse-path'
>[Function]
</a><br>
750 <b>centered-ellipse-path
</b>
755 Adds a closed subpath that outlines an ellipse centered at
756 (
<i>x
</i>,
<i>y
</i>) with an X radius of
<i>rx
</i> and a Y radius
760 <p><a name='centered-circle-path'
>[Function]
</a><br>
761 <b>centered-circle-path
</b> <i>x
</i> <i>y
</i> <i>radius
</i> =
> |
764 Adds a closed subpath that outlines a circle centered at
765 (
<i>x
</i>,
<i>y
</i>) with a radius of
<i>radius
</i>. It is effectively
769 (centered-ellipse-path x y radius radius)
775 <a name='sect-painting'
><h4>Painting
</h4></a>
777 <p>After a path is defined, filling, stroking, or both will use the
778 path to apply color to the canvas. After a path has been filled or
779 stroked, it is no longer active; it effectively disappears.
782 <p><a name='fill-path'
>[Function]
</a><br>
783 <b>fill-path
</b> =
> |
786 Fills the current path with the fill color. If the path has not been
788 with
<a href='#close-subpath'
><tt>CLOSE-SUBPATH
</tt></a>, it is
789 implicitly closed before filling. The non-zero winding rule is used
790 to determine what areas are considered inside the path.
794 <p><a name='even-odd-fill'
>[Function]
</a><br>
795 <b>even-odd-fill
</b> =
> |
798 The same as
<a href='#fill-path'
><tt>FILL-PATH
</tt></a>, but uses the
799 even/odd rule to determine what areas are considered inside the path.
803 <p><a name='stroke'
>[Function]
</a><br>
807 Strokes the current path. The line width, stroke color, line join
808 style, line cap style, and dash pattern and phase determine how the
809 stroked path will appear on the canvas.
813 <p><a name='fill-and-stroke'
>[Function]
</a><br>
814 <b>fill-and-stroke
</b> =
> |
817 Fills the current path, then strokes it.
821 <p><a name='even-odd-fill-and-stroke'
>[Function]
</a><br>
822 <b>even-odd-fill-and-stroke
</b> =
> |
825 Fills the current path using the even/odd rule, then strokes it.
829 <p><a name='end-path-no-op'
>[Function]
</a><br>
830 <b>end-path-no-op
</b> =
> |
833 Ends the current path without painting anything. If a clipping path
834 has been specified with
<a href='#clip-path'
><tt>CLIP-PATH
</tt></a>
835 or
<a href='#even-odd-clip-path'
><tt>EVEN-ODD-CLIP-PATH
</tt></a>, it
836 will be created by
<tt>end-path-no-op
</tt>.
841 <a name='sect-text'
><h4>Text
</h4></a>
843 <p>Vecto can draw text to a canvas. It loads glyph shapes from
845 with
<a href=
"http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF
</a>.
847 <p><a name='get-font'
>[Function]
</a><br>
848 <b>get-font
</b> <i>font-file
</i> =
> <i>font-loader
</i>
851 Creates and returns a ZPB-TTF font loader object
852 from
<i>font-file
</i>. Any font loader created this way will
853 automatically be closed at the end of its
854 enclosing
<a href='#with-canvas'
><tt>WITH-CANVAS
</tt></a> form.
858 <p><a name='set-font'
>[Function]
</a><br>
859 <b>set-font
</b> <i>font-loader
</i> <i>size
</i> =
> |
862 Sets the active font to the font associated
863 with
<i>font-loader
</i>, scaled to
<i>size
</i> units per line.
865 <p>The first argument can be any ZPB-TTF font loader; it need not be
866 created via
<a href='#get-font'
><tt>GET-FONT
</tt></a>. However, only
867 font loaders created via
<tt>GET-FONT
</tt> will be automatically
868 closed at the end of
<a href='#with-canvas'
><tt>WITH-CANVAS
</tt></a>.
872 <p><a name='draw-string'
>[Function]
</a><br>
873 <b>draw-string
</b> <i>x
</i> <i>y
</i> <i>string
</i> =
> |
876 Draws
<i>string
</i> on the canvas with the active font. The glyph
877 origin of the first character in the string is positioned at
<i>x
</i>
878 and the baseline of the string is positioned at
<i>y
</i>. The text is
879 filled with the current
<a href='#set-rgba-fill'
>fill color
</a>.
881 <p>The string may be a specialized vector of characters (a true CL
882 string) or a vector containing characters, Unicode code-points, or both. For
883 example,
<tt>#(#\L #\a #\m #\b #\d #\a #\= #x3BB)
</tt> is a valid
884 argument for
<tt>DRAW-STRING
</tt>.
888 <p><a name='draw-centered-string'
>[Function]
</a><br>
889 <b>draw-centered-string
</b> <i>x
</i> <i>y
</i> <i>string
</i> =
> |
892 Draws
<i>string
</i> on the canvas with the active font. The horizontal
893 center of the string is positioned at
<i>x
</i> and the baseline of the
894 string is positioned at
<i>y
</i>.
898 <p><a name='string-bounding-box'
>[Function]
</a><br>
899 <b>string-bounding-box
</b> <i>string
</i> <i>size
</i> <i>loader
</i>
900 =
> <i>#(xmin ymin xmax ymax)
</i>
903 Calculates the bounding box of
<i>string
</i> for
<i>font-loader
</i>
908 <a name='sect-miscellaneous'
><h3>Miscellaneous
</h3></a>
910 <p><a name='const-kappa'
>[Constant]
</a><br>
911 <b>+kappa+
</b> =
> 0.5522847498307936d0.
914 This constant is useful to draw portions of a circle.
918 <a name='sect-references'
><h2>References
</h2></a>
921 <li> Adobe Systems Inc.,
<a href=
"http://www.adobe.com/devnet/pdf/pdf_reference.html">PDF Reference, Sixth Edition, Version
1.7</a>
922 <li> Lawrence Kesteloot,
<a href=
"http://www.teamten.com/lawrence/graphics/premultiplication/">Alpha Premultiplication
</a>
923 <li> Dr. Thomas Sederberg,
<a href=
"http://www.tsplines.com/resources/class_notes/Bezier_curves.pdf">B
ézier curves
</a>
924 <li> Alvy Ray Smith,
<a href=
"http://alvyray.com/Memos/MemosMicrosoft.htm#ImageCompositing">Image Compositing Fundamentals
</a>
925 <li> G. Adam Stanislav,
<a href=
"http://www.whizkidtech.redprince.net/bezier/circle/">Drawing a circle with B
ézier curves
</a>
926 <li> Alexander Thomas,
<a href=
"http://www.dr-lex.be/random/matrix_inv.html">The Inverse and Determinants of
2x2 and
3x3 Matrices
</a>
927 <li> Wikipedia,
<a href=
"http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B
ézier curve
</a>
932 <a name='sect-acknowledgements'
><h2>Acknowledgements
</h2></a>
934 <p>Many thanks to
<a href=
"http://www.elbeno.com/">Ben Deane
</a> for
935 permission to adapt code from his curve library for drawing arcs.
938 <a name='sect-feedback'
><h2>Feedback
</h2></a>
940 <p>If you have any questions, comments, bug reports, or other feedback
941 regarding Vecto, please email
<a href=
"mailto:xach@xach.com">Zach
945 <tt>$Id: index.html,v
1.27 2007/
10/
01 20:
03:
18 xach Exp $
</tt>