Adjust COMPOSE to work with coordinate translation
[vecto.git] / doc / index.html
bloba7bb5518ab7f3a2619ae2a3e18e4a7d3d5d7355f
1 <html>
2 <head>
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) }
10 #content {
11 max-width: 50em; margin-left: auto; margin-right: auto;
12 font-family: sans-serif;
13 line-height: 1.4em;
14 background-color: white;
15 padding: 0.25em 1em 0.25em 1em;
17 body {
18 background-color: #f4eecf;
20 </style>
21 </head>
23 <body>
24 <div id="content">
26 <h2>Vecto - Simple Vector Drawing with Common Lisp</h2>
28 <blockquote class='abstract'>
29 <h3>Abstract</h3>
31 <p>Vecto is a simplified interface to the
32 powerful <a href="http://projects.tuxee.net/cl-vectors/">CL-VECTORS</a>
33 vector rasterization library. It presents a function-oriented
34 interface similar to <a href="http://www.cliki.net/CL-PDF">CL-PDF</a>,
35 but the results can be saved to a PNG instead of a PDF file. Since
36 Vecto and all supporting libraries are written completely in Common
37 Lisp, without depending on external non-Lisp libraries, it should work
38 in any Common Lisp environment. Vecto is available under a BSD-like
39 license.
41 The latest version is 1.6, released on December 30th, 2021.
43 <p>Vecto is used
44 by <a href="http://wigflip.com/easystreet/">Easystreet</a>
45 and <a href='http://www.xach.com/moviecharts/'>Movie Charts</a>.
47 <p>The canonical location for Vecto
48 is <a href="http://www.xach.com/lisp/vecto/">http://www.xach.com/lisp/vecto/</a>.
50 <p class='download'>Download shortcut:</p>
52 <p><a href="http://www.xach.com/lisp/vecto.tgz">http://www.xach.com/lisp/vecto.tgz</a>
54 </blockquote>
56 <h3>Contents</h3>
58 <ol>
59 <li> <a href='#sect-overview-and-limitations'>Overview and Limitations</a>
60 <li> <a href='#sect-examples'>Examples</a>
61 <li> <a href='#sect-dictionary'>Dictionary</a>
63 <ul>
64 <li> <a href='#sect-canvases'>Canvases</a>
65 <ul>
66 <li> <a href='#with-canvas'><tt>with-canvas</tt></a>
67 <li> <a href='#clear-canvas'><tt>clear-canvas</tt></a>
68 <li> <a href='#compose'><tt>compose</tt></a>
69 <li> <a href='#save-png'><tt>save-png</tt></a>
70 <li> <a href='#save-png-stream'><tt>save-png-stream</tt></a>
71 </ul>
73 <li> <a href='#sect-graphics-state'>Graphics State</a>
74 <ul>
75 <li> <a href='#with-graphics-state'><tt>with-graphics-state</tt></a>
76 <li> <a href='#set-rgba-fill'><tt>set-rgba-fill</tt></a>
77 <li> <a href='#set-rgba-fill'><tt>set-rgb-fill</tt></a>
78 <li> <a href='#set-gradient-fill'><tt>set-gradient-fill</tt></a>
79 <li> <a href='#set-rgba-stroke'><tt>set-rgba-stroke</tt></a>
80 <li> <a href='#set-rgba-stroke'><tt>set-rgb-stroke</tt></a>
81 <li> <a href='#set-line-cap'><tt>set-line-cap</tt></a>
82 <li> <a href='#set-line-join'><tt>set-line-join</tt></a>
83 <li> <a href='#set-line-width'><tt>set-line-width</tt></a>
84 <li> <a href='#set-dash-pattern'><tt>set-dash-pattern</tt></a>
85 <li> <a href='#translate'><tt>translate</tt></a>
86 <li> <a href='#rotate'><tt>rotate</tt></a>
87 <li> <a href='#scale'><tt>scale</tt></a>
88 <li> <a href='#skew'><tt>skew</tt></a>
89 <li> <a href='#clip-path'><tt>clip-path</tt></a>
90 <li> <a href='#even-odd-clip-path'><tt>even-odd-clip-path</tt></a>
91 </ul>
93 <li> <a href='#sect-paths'>Paths</a>
94 <ul>
95 <li> <a href='#move-to'><tt>move-to</tt></a>
96 <li> <a href='#line-to'><tt>line-to</tt></a>
97 <li> <a href='#curve-to'><tt>curve-to</tt></a>
98 <li> <a href='#quadratic-to'><tt>quadratic-to</tt></a>
99 <li> <a href='#arc'><tt>arc</tt></a>
100 <li> <a href='#arcn'><tt>arcn</tt></a>
101 <li> <a href='#ellipse-arc'><tt>ellipse-arc</tt></a>
102 <li> <a href='#ellipse-arcn'><tt>ellipse-arcn</tt></a>
103 <li> <a href='#close-subpath'><tt>close-subpath</tt></a>
104 <li> <a href='#stroke-to-paths'><tt>stroke-to-paths</tt></a>
105 <li> <a href='#rectangle'><tt>rectangle</tt></a>
106 <li> <a href='#rounded-rectangle'><tt>rounded-rectangle</tt></a>
107 <li> <a href='#centered-ellipse-path'><tt>centered-ellipse-path</tt></a>
108 <li> <a href='#centered-circle-path'><tt>centered-circle-path</tt></a>
109 </ul>
111 <li> <a href='#sect-painting'>Painting</a>
112 <ul>
113 <li> <a href='#fill-path'><tt>fill-path</tt></a>
114 <li> <a href='#even-odd-fill'><tt>even-odd-fill</tt></a>
115 <li> <a href='#stroke'><tt>stroke</tt></a>
116 <li> <a href='#fill-and-stroke'><tt>fill-and-stroke</tt></a>
117 <li> <a href='#even-odd-fill-and-stroke'><tt>even-odd-fill-and-stroke</tt></a>
118 <li> <a href='#end-path-no-op'><tt>end-path-no-op</tt></a>
119 </ul>
121 <li> <a href='#sect-text'>Text</a>
122 <ul>
123 <li> <a href='#get-font'><tt>get-font</tt></a>
124 <li> <a href='#set-font'><tt>set-font</tt></a>
125 <li> <a href='#set-character-spacing'><tt>set-character-spacing</tt></a>
126 <li> <a href='#*default-character-spacing*'><tt>*default-character-spacing*</tt></a>
127 <li> <a href='#draw-string'><tt>draw-string</tt></a>
128 <li> <a href='#string-paths'><tt>string-paths</tt></a>
129 <li> <a href='#draw-centered-string'><tt>draw-centered-string</tt></a>
130 <li> <a href='#centered-string-paths'><tt>centered-string-paths</tt></a>
131 <li> <a href='#string-bounding-box'><tt>string-bounding-box</tt></a>
132 </ul>
134 <li> <a href='#sect-miscellaneous'>Miscellaneous</a>
135 <ul>
136 <li> <a href='#const-kappa'><tt>+kappa+</tt></a>
137 </ul>
139 </ul>
141 <li> <a href='#sect-references'>References</a>
142 <li> <a href='#sect-acknowledgements'>Acknowledgements</a>
143 <li> <a href='#sect-feedback'>Feedback</a>
145 </ol>
147 <a name='sect-overview-and-limitations'><h3>Overview and Limitations</h3></a>
149 <p>Vecto is a library that provides a simple interface to the
150 the <a href="http://projects.tuxee.net/cl-vectors/">CL-VECTORS</a>
151 vector drawing library. It supports drawing on a canvas and saving the
152 results to a PNG file.
154 <p>Vecto depends on the following libraries:
156 <ul>
157 <li> <a href="http://projects.tuxee.net/cl-vectors/">CL-VECTORS</a>
158 <li> <a href="http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF</a>
159 <li> <a href="http://www.xach.com/lisp/salza2/">Salza2</a>
160 <li> <a href="http://www.xach.com/lisp/zpng/">ZPNG</a>
161 </ul>
163 <p>The easiest way to install Vecto and all its dependencies is
164 with <a href="http://www.quicklisp.org/">Quicklisp</a>.
166 <p>Vecto's function interface is similar to the
167 PDF vector description and painting interface: you create images by
168 describing vector paths, then using stroke or fill operations to paint
169 to the canvas.
171 <p>Vecto's color system uses red, green, blue, and alpha color
172 components for drawing. The results can be be saved to a PNG with an
173 alpha channel.
175 <p>Vecto's coordinate system starts at the lower-left corner of the
176 image, and increases rightwards along the X axis and upwards along the
177 Y axis.
179 <p>All measurements are in pixels.
181 <p>PDF is a feature-rich system. Vecto supports a small subset of
182 PDF-style operations. In particular, it does not support:
184 <ul>
185 <li> sampled images
186 <li> pattern or functional fill
187 <li> complex layout of text
188 <li> PostScript fonts
189 <li> non-RGB color spaces
190 </ul>
192 <p>Other limitations:
194 <ul>
195 <li> No output formats other than 8-bit, truecolor-alpha PNGs
196 <li> No access to underlying pixel data
197 </ul>
199 <p>Related libraries:
201 <ul>
202 <li> <a href="http://common-lisp.net/project/imago/">Imago</a>
204 <li> <a href="http://cyrusharmon.org/projects?project=ch-image">ch-image</a>
206 <li> <a href="http://ygingras.net/poly-pen">Poly-pen</a>
207 </ul>
210 <a name='sect-examples'><h3>Examples</h3></a>
212 <p>All examples are available in <tt>doc/examples.lisp</tt> in the Vecto
213 distribution. That file starts with:
215 <pre>
216 (defpackage #:vecto-examples
217 (:use #:cl #:vecto))
219 (in-package #:vecto-examples)
220 </pre>
223 <pre>
224 <img border=0 align=right src='lambda-example.png'
225 >(defun radiant-lambda (file)
226 (<a href='#with-canvas'>with-canvas</a> (:width 90 :height 90)
227 (let ((font (<a href='#get-font'>get-font</a> "times.ttf"))
228 (step (/ pi 7)))
229 (<a href='#set-font'>set-font</a> font 40)
230 (<a href='#translate'>translate</a> 45 45)
231 (<a href='#draw-centered-string'>draw-centered-string</a> 0 -10 #(#x3BB))
232 (<a href='#set-rgba-stroke'>set-rgb-stroke</a> 1 0 0)
233 (<a href='#centered-circle-path'>centered-circle-path</a> 0 0 35)
234 (<a href='#stroke'>stroke</a>)
235 (<a href='#set-rgba-stroke'>set-rgba-stroke</a> 0 0 1.0 0.5)
236 (<a href='#set-line-width'>set-line-width</a> 4)
237 (dotimes (i 14)
238 (<a href='#with-graphics-state'>with-graphics-state</a>
239 (<a href='#rotate'>rotate</a> (* i step))
240 (<a href='#move-to'>move-to</a> 30 0)
241 (<a href='#line-to'>line-to</a> 40 0)
242 (stroke)))
243 (<a href='#save-png'>save-png</a> file))))
244 </pre>
246 <pre>
247 <img align=right src='feedlike-icon.png'
248 >(defun feedlike-icon (file)
249 (with-canvas (:width 100 :height 100)
250 (set-rgb-fill 1.0 0.65 0.3)
251 (<a href='#rounded-rectangle'>rounded-rectangle</a> 0 0 100 100 10 10)
252 (<a href='#fill-path'>fill-path</a>)
253 (set-rgb-fill 1.0 1.0 1.0)
254 (centered-circle-path 20 20 10)
255 (fill-path)
256 (flet ((quarter-circle (x y radius)
257 (move-to (+ x radius) y)
258 (<a href='#arc'>arc</a> x y radius 0 (/ pi 2))))
259 (set-rgb-stroke 1.0 1.0 1.0)
260 (set-line-width 15)
261 (quarter-circle 20 20 30)
262 (stroke)
263 (quarter-circle 20 20 60)
264 (stroke))
265 (rounded-rectangle 5 5 90 90 7 7)
266 (<a href='#set-gradient-fill'>set-gradient-fill</a> 50 90
267 1.0 1.0 1.0 0.7
268 50 20
269 1.0 1.0 1.0 0.0)
270 (set-line-width 2)
271 (set-rgba-stroke 1.0 1.0 1.0 0.1)
272 (<a href='#fill-and-stroke'>fill-and-stroke</a>)
273 (save-png file)))
274 </pre>
276 <pre><div style='float: right' class='transparent'><img src='star-clipping.png'
277 ></div>(defun star-clipping (file)
278 (with-canvas (:width 200 :height 200)
279 (let ((size 100)
280 (angle 0)
281 (step (* 2 (/ (* pi 2) 5))))
282 (translate size size)
283 (move-to 0 size)
284 (dotimes (i 5)
285 (setf angle (+ angle step))
286 (line-to (* (sin angle) size)
287 (* (cos angle) size)))
288 (<a href='#even-odd-clip-path'><tt>even-odd-clip-path</tt></a>)
289 (<a href='#end-path-no-op'><tt>end-path-no-op</tt></a>)
290 (flet ((circle (distance)
291 (<a href='#set-rgba-fill'><tt>set-rgba-fill</tt></a> distance 0 0
292 (- 1.0 distance))
293 (centered-circle-path 0 0 (* size distance))
294 (fill-path)))
295 (loop for i downfrom 1.0 by 0.05
296 repeat 20 do
297 (circle i)))
298 (save-png file))))
299 </pre>
301 <a name='sect-dictionary'><h3>Dictionary</h3></a>
303 <p>The following symbols are exported from the <tt>VECTO</tt> package.
305 <a name='sect-canvases'><h4>Canvases</h4></a>
307 <p><a name='with-canvas'>[Macro]</a><br>
308 <b>with-canvas</b> (<tt>&amp;key</tt> <i>width</i> <i>height</i>
309 <i>image-data-allocator</i>) <tt>&amp;body</tt> <i>body</i>
311 <blockquote>
312 Evaluates <i>body</i> with a canvas established with the specified
313 dimensions as the target for drawing commands. The canvas is initially
314 completely clear (all pixels have 0 alpha).
316 It is possible to provide a one-argument function to the
317 <i>image-data-allocator</i> argument. That function will be called with
318 one argument (the size of the resulting vector) and must return a vector
319 of <i>(unsigned-byte 8)</i> which will be used as storage for the image
320 data. This is useful e.g. for using a
321 <a href='https://github.com/sionescu/static-vectors'>static vector</a>
322 for the storage in order to make the resulting PNG data interoperable
323 with foreign libraries:
325 <pre><img style='float: right' class='transparent'
326 src='linear-gradient.png'>(flet ((allocate (size)
327 (static-vectors:make-static-vector size :initial-element 0)))
328 (with-canvas (:width ... :height ...
329 :image-data-allocator #'allocate)
330 ...))
331 </pre>
333 Also see <a href='#zpng-object'><tt>ZPNG-OBJECT</tt></a>.
335 </blockquote>
338 <p><a name='clear-canvas'>[Function]</a><br>
339 <b>clear-canvas</b> => |
341 <blockquote>
342 Completely fills the canvas with the current fill color. Any marks on
343 the canvas are cleared.
344 </blockquote>
347 <p><a name='compose'>[Generic Function]</a><br>
348 <b>compose</b> <i>layer</i> => |
350 <blockquote>
351 Performs image composition by superimposing <i>image</i> on top of the
352 current canvas, starting from the coordinate center of the image.
354 <b>This composition disregards all transformations done to the image's
355 coordinate system other than translations - so, skewing, rotations, etc..</b>
356 Use systems that manipulate raster graphics (such as
357 <a href='https://common-lisp.net/project/imago/'>Imago</a>) to adjust
358 the raster image before compositing it with Vecto.
360 This GF has no default implementations and is meant to be implemented
361 by users.
362 </blockquote>
365 <p><a name='save-png'>[Function]</a><br>
366 <b>save-png</b> <i>file</i> => <i>truename</i>
368 <blockquote>
369 Writes the contents of the canvas as the PNG <i>file</i>, and returns
370 the truename of <i>file</i>.
371 </blockquote>
374 <p><a name='save-png-stream'>[Function]</a><br>
375 <b>save-png-stream</b> <i>stream</i> => |
377 <blockquote>
378 Writes the contents of the canvas as a PNG to <i>stream</i>, which
379 must accept <tt>(unsigned-byte&nbsp;8)</tt> data.
380 </blockquote>
383 <p><a name='zpng-object'>[Function]</a><br>
384 <b>zpng-object</b> => <i>png</i>
386 <blockquote>
387 Returns the ZPNG object representing the canvas.
388 </blockquote>
390 <a name='sect-graphics-state'><h4>Graphics State</h4></a>
392 <p>The graphics state stores several parameters used for graphic
393 operations.
395 <p><a name='with-graphics-state'>[Macro]</a><br>
396 <b>with-graphics-state</b> <tt>&amp;body</tt> <i>body</i>
398 <blockquote>
399 Evaluates the forms of <i>body</i> with a copy of the current graphics
400 state. Any modifications to the state are undone at the end of the
401 form.
402 </blockquote>
405 <p><a name='set-rgba-fill'>[Functions]</a><br>
406 <b>set-rgba-fill</b> <i>r</i> <i>g</i> <i>b</i> <i>alpha</i> => |<br>
407 <b>set-rgb-fill</b> <i>r</i> <i>g</i> <i>b</i> => |
409 <blockquote>
410 Sets the fill color. <i>r</i>, <i>g</i>, <i>b</i>, and <i>alpha</i>
411 should be in the range of 0.0 to 1.0.
413 <p><tt>set-rgb-fill</tt> is the same as <tt>set-rgba-fill</tt> with an
414 implicit alpha value of 1.0.
416 <p>The fill color is used
417 for <a
418 href='#clear-canvas'><tt>CLEAR-CANVAS</tt></a>, <a
419 href='#fill-path'><tt>FILL-PATH</tt></a>, <a
420 href='#even-odd-fill'><tt>EVEN-ODD-FILL</tt></a>, <a
421 href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>, <a
422 href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>,
423 and <a href='#draw-string'><tt>DRAW-STRING</tt></a>.
425 </blockquote>
427 <p><a name='set-gradient-fill'>[Function]</a><br>
428 <b>set-gradient-fill</b>
429 <i>x0</i> <i>y0</i> <i>r0</i> <i>g0</i> <i>b0</i> <i>a0</i>
430 <i>x1</i> <i>y1</i> <i>r1</i> <i>g1</i> <i>b1</i> <i>a1</i>
431 <tt>&amp;key</tt> (<i>extend-start</i> <tt>t</tt>)
432 (<i>extend-end</i> <tt>t</tt>)
433 (<i>domain-function</i> <tt>'linear-domain</tt>)
435 <blockquote>
436 Set the fill color source to an axial gradient. The start point
437 is <i>x0,y0</i> and the start color is <i>r0,g0,b0,a0</i>. The end
438 point is <i>x1, y1</i> and the end color is <i>r1,g1,b1,a1</i>.
440 <p>Two domain functions are available:
442 <ul>
444 <li> <tt>LINEAR-DOMAIN</tt>, the default, makes a transition from the
445 start color to the end color along the axis between the start and end
446 points
448 <li> <tt>BILINEAR-DOMAIN</tt> makes a transition from the start color
449 to the end color from the start point to the midpoint, then back to
450 the start color from the midpoint to the end point
451 </ul>
454 <p>Two coordinate functions are available:
456 <ul>
458 <li> <tt>CARTESIAN-COORDINATES</tt>, the default, creates a linear
459 gradient.
461 <li> <tt>POLAR-COORDINATES</tt> creates a radial gradient with the
462 start point denoting the start of the circle and the end point
463 denoting the ending circle.
464 </ul>
467 <pre><img style='float: right' class='transparent'
468 src='linear-gradient.png'>(defun gradient-example (file)
469 (with-canvas (:width 200 :height 50)
470 (set-gradient-fill 25 0
471 1 0 0 1
472 175 0
473 1 0 0 0)
474 (rectangle 0 0 200 50)
475 (fill-path)
476 (save-png file)))
477 </pre>
479 <pre><img style='float: right' class='transparent'
480 src='bilinear-gradient.png'>(defun gradient-bilinear-example (file)
481 (with-canvas (:width 200 :height 50)
482 (set-gradient-fill 25 0
483 1 0 0 1
484 175 0
485 1 0 0 0
486 :domain-function 'bilinear-domain)
487 (rectangle 0 0 200 50)
488 (fill-path)
489 (save-png file)))
490 </pre>
494 </blockquote>
496 <p><a name='set-rgba-stroke'>[Functions]</a><br>
497 <b>set-rgba-stroke</b> <i>r</i> <i>g</i> <i>b</i> <i>alpha</i> => |<br>
498 <b>set-rgb-stroke</b> <i>r</i> <i>g</i> <i>b</i> => |
500 <blockquote>
501 Sets the stroke color. <i>r</i>, <i>g</i>, <i>b</i>, and <i>alpha</i>
502 should be in the range of 0.0 to 1.0.
504 <p><tt>set-rgb-stroke</tt> is the same as <tt>set-rgba-stroke</tt>
505 with an implicit alpha value of 1.0.
507 <p>The stroke color is used for <a href='#stroke'><tt>STROKE</tt></a>,
508 <a href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>,
509 and <a href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>.
510 </blockquote>
513 <p><a name='set-line-cap'>[Function]</a><br>
514 <b>set-line-cap</b> <i>style</i> => |
516 <blockquote>
517 Sets the line cap style to <i>style</i>, which must be one
518 of <tt>:BUTT</tt>, <tt>:SQUARE</tt>, or <tt>:ROUND</tt>. The initial
519 value is <tt>:BUTT</tt>.
521 <p><table cellspacing=5 id="line-cap">
522 <tr>
523 <td align=center><img src="cap-style-butt.png"></td>
524 <td align=center><img src="cap-style-square.png"></td>
525 <td align=center><img src="cap-style-round.png"></td>
526 </tr>
527 <tr>
528 <td align=center><tt>:BUTT</tt></td>
529 <td align=center><tt>:SQUARE</tt></td>
530 <td align=center><tt>:ROUND</tt></td>
531 </tr>
532 </table>
534 </blockquote>
537 <p><a name='set-line-join'>[Function]</a><br>
538 <b>set-line-join</b> <i>style</i> => |
540 <blockquote>
541 Sets the line join style to <i>style</i>, which must be one
542 of <tt>:MITER</tt>, <tt>:BEVEL</tt>, or <tt>:ROUND</tt>. The initial
543 value is <tt>:MITER</tt>.
545 <p><table cellspacing=5 id="line-join">
546 <tr>
547 <td align=center><img src="join-style-miter.png"></td>
548 <td align=center><img src="join-style-bevel.png"></td>
549 <td align=center><img src="join-style-round.png"></td>
550 </tr>
551 <tr>
552 <td align=center><tt>:MITER</tt></td>
553 <td align=center><tt>:BEVEL</tt></td>
554 <td align=center><tt>:ROUND</tt></td>
555 </tr>
556 </table>
558 </blockquote>
561 <p><a name='set-line-width'>[Function]</a><br>
562 <b>set-line-width</b> <i>width</i> => |
564 <blockquote>
565 Sets the line width for strokes to <i>width</i>.
566 </blockquote>
570 <p><a name='set-dash-pattern'>[Function]</a><br>
571 <b>set-dash-pattern</b> <i>dash-vector</i> <i>phase</i> => |
573 <blockquote>
574 Sets the dash pattern according to <i>dash-vector</i> and <i>phase</i>.
576 <p><i>dash-vector</i> should be a vector of numbers denoting on and
577 off patterns for a stroke. An empty <i>dash-vector</i> is the same as
578 having no dash pattern at all.
580 <p><i>phase</i> is how far along the dash pattern to proceed before
581 applying the pattern to the current stroke.
584 <table>
585 <tr>
586 <th>Appearance</th>
587 <th>Dash Vector and Phase</th>
588 </tr>
589 <tr>
590 <td align=center><img src="dash-pattern-none.png"></td>
591 <td align=left><tt>#() 0</tt></td>
592 </tr>
593 <tr>
594 <td align=center><img src="dash-pattern-a.png"></td>
595 <td align=left><tt>#(30 30) 0</tt></td>
596 </tr>
597 <tr>
598 <td align=center><img src="dash-pattern-b.png"></td>
599 <td align=left><tt>#(30 30) 15</tt></td>
600 </tr>
601 <tr>
602 <td align=center><img src="dash-pattern-c.png"></td>
603 <td align=left><tt>#(10 20 10 40) 0</tt></td>
604 </tr>
605 <tr>
606 <td align=center><img src="dash-pattern-d.png"></td>
607 <td align=left><tt>#(10 20 10 40) 13</tt></td>
608 </tr>
609 <tr>
610 <td align=center><img src="dash-pattern-e.png"></td>
611 <td align=left><tt>#(30 30) 0</tt>, <tt>:ROUND</tt> line caps</td>
612 </tr>
613 </table>
614 </blockquote>
617 <p><a name='translate'>[Function]</a><br>
618 <b>translate</b> <i>x</i> <i>y</i> => |
620 <blockquote>
621 Offsets the coordinate system by <i>x</i> units horizontally
622 and <i>y</i> units vertically.
623 </blockquote>
626 <p><a name='rotate'>[Function]</a><br>
627 <b>rotate</b> <i>radians</i> => |
629 <blockquote>
630 Rotates the coordinate system by <i>radians</i>.
631 </blockquote>
634 <p><a name='scale'>[Function]</a><br>
635 <b>scale</b> <i>sx</i> <i>sy</i> => |
637 <blockquote>
638 Scales the coordinate system by <i>sx</i> horizontally
639 and <i>sy</i> vertically.
640 </blockquote>
643 <p><a name='skew'>[Function]</a><br>
644 <b>skew</b> <i>ax</i> <i>ay</i> => |
646 <blockquote>
647 Skews the X axis of the coordinate system by <i>ax</i> radians and the
648 Y axis by <i>ay</i> radians.
649 </blockquote>
652 <p><a name='clip-path'>[Function]</a><br>
653 <b>clip-path</b> => |
655 <blockquote>
656 Defines a clipping path based on the current path. It is not applied
657 immediately, but is created after after the painting is done in the
658 next call to one
659 of <a
660 href='#fill-path'><tt>FILL-PATH</tt></a>, <a
661 href='#even-odd-fill'><tt>EVEN-ODD-FILL</tt></a>, <a
662 href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>, <a
663 href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>,
664 or <a href='#end-path-no-op'><tt>END-PATH-NO-OP</tt></a>.
666 <p>The clipping path initially covers the entire canvas; no clipping
667 is done. Subsequent calls to <tt>CLIP-PATH</tt> set the clipping path
668 to the intersection of the established clipping path and the new
669 clipping path, and all drawing will be done within the outline of the
670 clipping path.
672 <p>The outline of the clipping path is defined with the nonzero
673 winding rule, as with <a href='#fill-path'><tt>FILL-PATH</tt></a>.
675 <p>There is no way to enlarge the clipping path. However, the clipping
676 path is part of the graphics state, so changes may be localized by
677 using <a href='#with-graphics-state'><tt>WITH-GRAPHICS-STATE</tt></a>.
680 <p><table>
681 <tr>
682 <td><img src="clip-unclipped.png"></td>
683 <td>A filled red rectangle, not clipped</td>
684 </tr>
685 <tr>
686 <td><img src="clip-to-circle.png"></td>
687 <td>The same rectangle drawn with a circle clipping path in effect</td>
688 </tr>
689 <tr>
690 <td><img src="clip-to-rectangle.png"></td>
691 <td>Clipped to a rounded rectangle clipping path</td>
692 </tr>
693 <tr>
694 <td><img src="clip-to-both.png"></td>
695 <td>Clipped to the intersection of the circle and rounded rectangle clipping paths</td>
696 </tr>
697 </table>
701 </blockquote>
704 <p><a name='even-odd-clip-path'>[Function]</a><br>
705 <b>even-odd-clip-path</b> => |
707 <blockquote>
708 Like <a href='#clip-path'><tt>CLIP-PATH</tt></a>, but uses the
709 even/odd fill rule to determine the outline of the clipping path.
710 </blockquote>
713 <a name='sect-paths'><h4>Paths</h4></a>
715 <p>Paths are used to create lines for stroking or outlines for
716 filling. Paths consist of straight lines and curves. Paths consist of
717 one or more subpaths.
719 <p><a name='move-to'>[Function]</a><br>
720 <b>move-to</b> <i>x</i> <i>y</i> => |
722 <blockquote>
723 Starts a new subpath at (<i>x</i>,<i>y</i>). <tt>move-to</tt> must be the
724 first step of constructing a subpath.
725 </blockquote>
728 <p><a name='line-to'>[Function]</a><br>
729 <b>line-to</b> <i>x</i> <i>y</i> => |
731 <blockquote>
732 Appends a straight line ending at (<i>x</i>,<i>y</i>) to the
733 current subpath.
734 </blockquote>
737 <p><a name='curve-to'>[Function]</a><br>
738 <b>curve-to</b>
739 <i>cx1</i> <i>cy1</i>
740 <i>cx2</i> <i>cy2</i>
741 <i>x</i> <i>y</i> => |
743 <blockquote>
744 Appends a
745 cubic <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier
746 curve</a> ending at (<i>x</i>,<i>y</i>) and with control
747 points (<i>cx1</i>,<i>cy1</i>) and (<i>cx2</i>,<i>cy2</i>) to the current
748 subpath.
749 </blockquote>
752 <p><a name='quadratic-to'>[Function]</a><br>
753 <b>quadratic-to</b>
754 <i>cx</i> <i>cy</i>
755 <i>x</i> <i>y</i> => |
757 <blockquote>
758 Appends a quadratic B&eacute;zier curve ending at (<i>x</i>,<i>y</i>)
759 and with the control point (<i>cx</i>,<i>cy</i>) to the current
760 subpath.
761 </blockquote>
764 <p><a name='arc'>[Function]</a><br>
765 <b>arc</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
766 => |
768 <blockquote>
769 Appends an arc of a circle to the current path. The center of the arc is
770 at (<i>x</i>,<i>y</i>). The arc begins at point at a
771 distance <i>radius</i> from the center and with an angle <i>angle1</i>
772 radians from the positive x axis, and ends at the point
773 with <i>angle2</i> radians. If <i>angle2</i> is less
774 than <i>angle1</i>, it is increased by increasing multiples of 2&pi;
775 until it is greater than or equal to <i>angle1</i>.
777 <p><table cellpadding=5>
778 <tr><td align=center><img src="arc.png"></td></tr>
779 <tr><td><span style='color: #0f0'><i>radius</i></span>,
780 <span style='color: #f00'><i>angle1</i></span>,
781 <span style='color: #00f'><i>angle2</i></span></td></tr>
782 </table>
784 <p>If there is a current point, a straight line is added from the
785 current point to the start point of the arc. Otherwise, a new path
786 is started.
788 <pre><img class='transparent' style='float: right' src='pie-wedge.png'
789 >(defun pie-wedge (file)
790 (with-canvas (:width 80 :height 60)
791 (let ((x 0) (y 0)
792 (radius 70)
793 (angle1 (* (/ pi 180) 15))
794 (angle2 (* (/ pi 180) 45)))
795 (translate 5 5)
796 (set-rgb-fill 1 1 1)
797 (move-to 0 0)
798 (arc x y radius angle1 angle2)
799 (fill-and-stroke)
800 (save-png file))))
801 </pre>
803 </blockquote>
806 <p><a name='arcn'>[Function]</a><br>
807 <b>arcn</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
808 => |
810 <blockquote>
811 Like <a href='#arc'><tt>ARC</tt></a>, but draws the arc clockwise
812 instead of counterclockwise. If <i>angle2</i> is greater
813 than <i>angle1</i>, it is decreased by increasing multiples of 2&pi;
814 until it is less than or equal to <i>angle1</i>.
816 <pre><img class='transparent' style='float: right' src='wiper.png'
817 >(defun wiper (file)
818 (with-canvas (:width 70 :height 70)
819 (let ((x 0) (y 0)
820 (r1 40) (r2 60)
821 (angle1 0)
822 (angle2 (* (/ pi 180) 90)))
823 (translate 5 5)
824 (set-rgba-fill 1 1 1 0.75)
825 (arc x y r1 angle1 angle2)
826 (arcn x y r2 angle2 angle1)
827 (fill-and-stroke)
828 (save-png file))))
829 </pre>
831 </blockquote>
833 <p><a name='ellipse-arc'>[Function]</a><br>
834 <b>ellipse-arc</b> <i>cx</i> <i>cy</i> <i>radius-x</i> <i>radius-y</i>
835 <i>rotation-angle</i> <i>angle1</i> <i>angle2</i> => |
837 <blockquote>
838 Like <a href='#arc'><tt>ARC</TT></a>, but draws an arc from an
839 ellipse. The arc is drawn counterclockwise.
840 </blockquote>
843 <p><a name='ellipse-arcn'>[Function]</a><br>
844 <b>ellipse-arcn</b> <i>cx</i> <i>cy</i> <i>radius-x</i> <i>radius-y</i>
845 <i>rotation-angle</i> <i>angle1</i> <i>angle2</i> => |
847 <blockquote>
848 Like <a href='#ellipse-arcn'><tt>ELLIPSE-ARCN</TT></a>, but draws the
849 arc clockwise.
850 </blockquote>
853 <p><a name='close-subpath'>[Function]</a><br>
854 <b>close-subpath</b> => |
856 <blockquote>
857 Closes the current subpath. If the current point is not the same as the
858 starting point for the subpath, appends a straight line from the
859 current point to the starting point of the current subpath.
861 <p>Subpaths with start and end points that coincidentally overlap are
862 not the same as closed subpaths. The distinction is important when
863 stroking:
865 <p><table cellpadding=5>
866 <tr>
867 <td align=center><img src="open-subpath.png"></td>
868 <td align=center><img src="closed-subpath.png"></td>
869 </tr>
870 <tr>
871 <td align=center>Open subpath</td>
872 <td align=center>Closed subpath</td>
873 </tr>
874 </table>
876 <p>If the subpath is not closed, the start and points of the subpath
877 will be drawn with the current line cap style. If the path is
878 closed, the start and endpoints will be treated as joined and drawn
879 with the line join style.
880 </blockquote>
883 <p><a name='stroke-to-paths'>[Function]</a><br>
884 <b>stroke-to-paths</b> => |
886 <blockquote>
887 Sets the current active paths to the paths that would result from
888 outlining a <a href='#stroke'><tt>STROKE</tt></a> operation.
889 </blockquote>
892 <p><a name='rectangle'>[Function]</a><br>
893 <b>rectangle</b> <i>x</i> <i>y</i> <i>width</i> <i>height</i> => |
895 <blockquote>
896 Creates a rectangular subpath with the given <i>width</i>
897 and <i>height</i> that has its lower-left corner at
898 (<i>x</i>,<i>y</i>). It is effectively the same as:
900 <pre>
901 (move-to x y)
902 (line-to (+ x width) y)
903 (line-to (+ x width) (+ y height))
904 (line-to x (+ y height))
905 (close-subpath)
906 </pre>
907 </blockquote>
909 <p><a name='rounded-rectangle'>[Function]</a><br>
910 <b>rounded-rectangle</b> <i>x</i> <i>y</i>
911 <i>width</i> <i>height</i> <i>rx</i> <i>ry</i> => |
913 <blockquote>
914 Like <a href='#rectangle'><tt>RECTANGLE</tt></a>, but rounds the
915 corners of the rectangle paths by the x radius <i>rx</i> and the y
916 radius <i>ry</i>.
917 </blockquote>
919 <p><a name='centered-ellipse-path'>[Function]</a><br>
920 <b>centered-ellipse-path</b>
921 <i>x</i> <i>y</i>
922 <i>rx</i> <i>ry</i>
924 <blockquote>
925 Adds a closed subpath that outlines an ellipse centered at
926 (<i>x</i>,<i>y</i>) with an X radius of <i>rx</i> and a Y radius
927 of <i>ry</i>.
928 </blockquote>
930 <p><a name='centered-circle-path'>[Function]</a><br>
931 <b>centered-circle-path</b> <i>x</i> <i>y</i> <i>radius</i> => |
933 <blockquote>
934 Adds a closed subpath that outlines a circle centered at
935 (<i>x</i>,<i>y</i>) with a radius of <i>radius</i>. It is effectively
936 the same as:
938 <pre>
939 (centered-ellipse-path x y radius radius)
940 </pre>
941 </blockquote>
945 <a name='sect-painting'><h4>Painting</h4></a>
947 <p>After a path is defined, filling, stroking, or both will use the
948 path to apply color to the canvas. After a path has been filled or
949 stroked, it is no longer active; it effectively disappears.
952 <p><a name='fill-path'>[Function]</a><br>
953 <b>fill-path</b> => |
955 <blockquote>
956 Fills the current path with the fill color or gradient. If the path
957 has not been explicitly closed
958 with <a href='#close-subpath'><tt>CLOSE-SUBPATH</tt></a>, it is
959 implicitly closed before filling. The non-zero winding rule is used
960 to determine what areas are considered inside the path.
961 </blockquote>
964 <p><a name='even-odd-fill'>[Function]</a><br>
965 <b>even-odd-fill</b> => |
967 <blockquote>
968 The same as <a href='#fill-path'><tt>FILL-PATH</tt></a>, but uses the
969 even/odd rule to determine what areas are considered inside the path.
970 </blockquote>
973 <p><a name='stroke'>[Function]</a><br>
974 <b>stroke</b> => |
976 <blockquote>
977 Strokes the current path. The line width, stroke color, line join
978 style, line cap style, and dash pattern and phase determine how the
979 stroked path will appear on the canvas.
980 </blockquote>
983 <p><a name='fill-and-stroke'>[Function]</a><br>
984 <b>fill-and-stroke</b> => |
986 <blockquote>
987 Fills the current path, then strokes it.
988 </blockquote>
991 <p><a name='even-odd-fill-and-stroke'>[Function]</a><br>
992 <b>even-odd-fill-and-stroke</b> => |
994 <blockquote>
995 Fills the current path using the even/odd rule, then strokes it.
996 </blockquote>
999 <p><a name='end-path-no-op'>[Function]</a><br>
1000 <b>end-path-no-op</b> => |
1002 <blockquote>
1003 Ends the current path without painting anything. If a clipping path
1004 has been specified with <a href='#clip-path'><tt>CLIP-PATH</tt></a>
1005 or <a href='#even-odd-clip-path'><tt>EVEN-ODD-CLIP-PATH</tt></a>, it
1006 will be created by <tt>end-path-no-op</tt>.
1007 </blockquote>
1011 <a name='sect-text'><h4>Text</h4></a>
1013 <p>Vecto can draw text to a canvas. It loads glyph shapes from
1014 TrueType font files
1015 with <a href="http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF</a>.
1017 <p><a name='get-font'>[Function]</a><br>
1018 <b>get-font</b> <i>font-file</i> => <i>font-loader</i>
1020 <blockquote>
1021 Creates and returns a ZPB-TTF font loader object
1022 from <i>font-file</i>. Any font loader created this way will
1023 automatically be closed at the end of its
1024 enclosing <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form.
1025 </blockquote>
1028 <p><a name='set-font'>[Function]</a><br>
1029 <b>set-font</b> <i>font-loader</i> <i>size</i> => |
1031 <blockquote>
1032 Sets the active font to the font associated
1033 with <i>font-loader</i>, scaled to <i>size</i> units per line.
1035 <p>The first argument can be any ZPB-TTF font loader; it need not be
1036 created via <a href='#get-font'><tt>GET-FONT</tt></a>. However, only
1037 font loaders created via <tt>GET-FONT</tt> will be automatically
1038 closed at the end of <a href='#with-canvas'><tt>WITH-CANVAS</tt></a>.
1039 </blockquote>
1042 <p><a name='set-character-spacing'>[Function]</a><br>
1043 <b>set-character-spacing</b> <i>spacing</i> => |
1045 <blockquote>
1046 Sets the scale of the spacing used between characters when drawing
1047 text with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
1048 functions.
1050 <p>Normally, the character spacing for drawing text is taken directly
1051 from a font's advance-width and kerning
1052 metrics. <tt>SET-CHARACTER-SPACING</tt> can be used to adjust this
1053 spacing; for example, a character spacing of 2.0d0 would double the
1054 normal space between characters, and 0.5d0 would halve it.
1055 </blockquote>
1057 <p><a name='*default-character-spacing*'>[Special variable]</a><br>
1058 <b>*default-character-spacing*</b>
1060 <blockquote>
1061 The default scale for character spacing when drawing text
1062 with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
1063 functions. Initial value is 1.0d0.
1065 <p>Changes to this variable affect the
1066 next <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form. To affect
1067 the spacing within the current <tt>WITH-CANVAS</tt> form,
1068 use <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>.
1069 </blockquote>
1072 <p><a name='draw-string'>[Function]</a><br>
1073 <b>draw-string</b> <i>x</i> <i>y</i> <i>string</i> => |
1075 <blockquote>
1076 Draws <i>string</i> on the canvas with the active font. The glyph
1077 origin of the first character in the string is positioned at <i>x</i>
1078 and the baseline of the string is positioned at <i>y</i>. The text is
1079 filled with the current <a href='#set-rgba-fill'>fill color</a>.
1081 <p>The string may be a specialized vector of characters (a true CL
1082 string) or a vector containing characters, Unicode code-points, or both. For
1083 example, <tt>#(#\L #\a #\m #\b #\d #\a #\= #x3BB)</tt> is a valid
1084 argument for <tt>DRAW-STRING</tt>.
1086 <p>The horizontal space between characters is determined by the
1087 advance-width and kerning metrics of the font, then multiplied by
1088 the current character spacing. At the default character spacing of
1089 1.0d0, the spacing is not adjusted at
1090 all. <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>
1091 can be used to increase or decrease the character spacing.
1092 </blockquote>
1095 <p><a name='string-paths'>[Function]</a><br>
1096 <b>string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1098 <blockquote>
1099 Like <a href='#draw-string'><tt>DRAW-STRING</tt></a>, but instead of
1100 drawing the text, adds the subpaths that make up the string glyphs to
1101 the graphics state. This can be used to stroke, fill, or clip based on
1102 the outlines of a string.
1103 </blockquote>
1106 <p><a name='draw-centered-string'>[Function]</a><br>
1107 <b>draw-centered-string</b> <i>x</i> <i>y</i> <i>string</i> => |
1109 <blockquote>
1110 Draws <i>string</i> on the canvas with the active font. The horizontal
1111 center of the string is positioned at <i>x</i> and the baseline of the
1112 string is positioned at <i>y</i>.
1113 </blockquote>
1116 <p><a name='centered-string-paths'>[Function]</a><br>
1117 <b>centered-string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1119 <blockquote>
1120 Like <a href='#draw-centered-string'><tt>DRAW-CENTERED-STRING</tt></a>,
1121 but adds subpaths instead of painting. See
1122 also <a href='#string-paths'><tt>STRING-PATHS</tt></a>.
1123 </blockquote>
1126 <p><a name='string-bounding-box'>[Function]</a><br>
1127 <b>string-bounding-box</b> <i>string</i> <i>size</i> <i>loader</i>
1128 => <i>#(xmin ymin xmax ymax)</i>
1130 <blockquote>
1131 Calculates the bounding box of <i>string</i> for <i>font-loader</i>
1132 at <i>size</i>.
1133 </blockquote>
1136 <a name='sect-miscellaneous'><h3>Miscellaneous</h3></a>
1138 <p><a name='const-kappa'>[Constant]</a><br>
1139 <b>+kappa+</b> => 0.5522847498307936d0.
1141 <blockquote>
1142 This constant is useful to draw portions of a circle.
1143 </blockquote>
1146 <a name='sect-references'><h2>References</h2></a>
1148 <ul>
1149 <li> Adobe Systems Inc., <a href="http://www.adobe.com/devnet/pdf/pdf_reference.html">PDF Reference, Sixth Edition, Version 1.7</a>
1150 <li> Lawrence Kesteloot, <a href="http://www.teamten.com/lawrence/graphics/premultiplication/">Alpha Premultiplication</a>
1151 <li> Dr. Thomas Sederberg, <a href="http://www.tsplines.com/resources/class_notes/Bezier_curves.pdf">B&eacute;zier curves</a>
1152 <li> Alvy Ray Smith, <a href="http://alvyray.com/Memos/MemosMicrosoft.htm#ImageCompositing">Image Compositing Fundamentals</a>
1153 <li> G. Adam Stanislav, <a href="http://www.whizkidtech.redprince.net/bezier/circle/">Drawing a circle with B&eacute;zier curves</a>
1154 <li> Alexander Thomas, <a href="http://www.dr-lex.be/random/matrix_inv.html">The Inverse and Determinants of 2x2 and 3x3 Matrices</a>
1155 <li> Wikipedia, <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier curve</a>
1157 </ul>
1160 <a name='sect-acknowledgements'><h2>Acknowledgements</h2></a>
1162 <p>Many thanks to <a href="http://www.elbeno.com/">Ben Deane</a> for
1163 permission to adapt code from his curve library for drawing arcs.
1165 <p>Ryan Davis helped fix my adaptation of the arc drawing.
1167 <a name='sect-feedback'><h2>Feedback</h2></a>
1169 <p>If you have any questions, comments, bug reports, or other feedback
1170 regarding Vecto, please email <a href="mailto:xach@xach.com">Zach
1171 Beane</a>.
1174 </div>
1175 </body>