Update doc styling a bit.
[vecto.git] / doc / index.html
blob84398111df67dbf6448d756834d203191f98d889
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.4.8, released on October 14th, 2014.
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='#save-png'><tt>save-png</tt></a>
69 <li> <a href='#save-png-stream'><tt>save-png-stream</tt></a>
70 </ul>
72 <li> <a href='#sect-graphics-state'>Graphics State</a>
73 <ul>
74 <li> <a href='#with-graphics-state'><tt>with-graphics-state</tt></a>
75 <li> <a href='#set-rgba-fill'><tt>set-rgba-fill</tt></a>
76 <li> <a href='#set-rgba-fill'><tt>set-rgb-fill</tt></a>
77 <li> <a href='#set-gradient-fill'><tt>set-gradient-fill</tt></a>
78 <li> <a href='#set-rgba-stroke'><tt>set-rgba-stroke</tt></a>
79 <li> <a href='#set-rgba-stroke'><tt>set-rgb-stroke</tt></a>
80 <li> <a href='#set-line-cap'><tt>set-line-cap</tt></a>
81 <li> <a href='#set-line-join'><tt>set-line-join</tt></a>
82 <li> <a href='#set-line-width'><tt>set-line-width</tt></a>
83 <li> <a href='#set-dash-pattern'><tt>set-dash-pattern</tt></a>
84 <li> <a href='#translate'><tt>translate</tt></a>
85 <li> <a href='#rotate'><tt>rotate</tt></a>
86 <li> <a href='#scale'><tt>scale</tt></a>
87 <li> <a href='#skew'><tt>skew</tt></a>
88 <li> <a href='#clip-path'><tt>clip-path</tt></a>
89 <li> <a href='#even-odd-clip-path'><tt>even-odd-clip-path</tt></a>
90 </ul>
92 <li> <a href='#sect-paths'>Paths</a>
93 <ul>
94 <li> <a href='#move-to'><tt>move-to</tt></a>
95 <li> <a href='#line-to'><tt>line-to</tt></a>
96 <li> <a href='#curve-to'><tt>curve-to</tt></a>
97 <li> <a href='#quadratic-to'><tt>quadratic-to</tt></a>
98 <li> <a href='#arc'><tt>arc</tt></a>
99 <li> <a href='#arcn'><tt>arcn</tt></a>
100 <li> <a href='#close-subpath'><tt>close-subpath</tt></a>
101 <li> <a href='#stroke-to-paths'><tt>stroke-to-paths</tt></a>
102 <li> <a href='#rectangle'><tt>rectangle</tt></a>
103 <li> <a href='#rounded-rectangle'><tt>rounded-rectangle</tt></a>
104 <li> <a href='#centered-ellipse-path'><tt>centered-ellipse-path</tt></a>
105 <li> <a href='#centered-circle-path'><tt>centered-circle-path</tt></a>
106 </ul>
108 <li> <a href='#sect-painting'>Painting</a>
109 <ul>
110 <li> <a href='#fill-path'><tt>fill-path</tt></a>
111 <li> <a href='#even-odd-fill'><tt>even-odd-fill</tt></a>
112 <li> <a href='#stroke'><tt>stroke</tt></a>
113 <li> <a href='#fill-and-stroke'><tt>fill-and-stroke</tt></a>
114 <li> <a href='#even-odd-fill-and-stroke'><tt>even-odd-fill-and-stroke</tt></a>
115 <li> <a href='#end-path-no-op'><tt>end-path-no-op</tt></a>
116 </ul>
118 <li> <a href='#sect-text'>Text</a>
119 <ul>
120 <li> <a href='#get-font'><tt>get-font</tt></a>
121 <li> <a href='#set-font'><tt>set-font</tt></a>
122 <li> <a href='#set-character-spacing'><tt>set-character-spacing</tt></a>
123 <li> <a href='#*default-character-spacing*'><tt>*default-character-spacing*</tt></a>
124 <li> <a href='#draw-string'><tt>draw-string</tt></a>
125 <li> <a href='#string-paths'><tt>string-paths</tt></a>
126 <li> <a href='#draw-centered-string'><tt>draw-centered-string</tt></a>
127 <li> <a href='#centered-string-paths'><tt>centered-string-paths</tt></a>
128 <li> <a href='#string-bounding-box'><tt>string-bounding-box</tt></a>
129 </ul>
131 <li> <a href='#sect-miscellaneous'>Miscellaneous</a>
132 <ul>
133 <li> <a href='#const-kappa'><tt>+kappa+</tt></a>
134 </ul>
136 </ul>
138 <li> <a href='#sect-references'>References</a>
139 <li> <a href='#sect-acknowledgements'>Acknowledgements</a>
140 <li> <a href='#sect-feedback'>Feedback</a>
142 </ol>
144 <a name='sect-overview-and-limitations'><h3>Overview and Limitations</h3></a>
146 <p>Vecto is a library that provides a simple interface to the
147 the <a href="http://projects.tuxee.net/cl-vectors/">CL-VECTORS</a>
148 vector drawing library. It supports drawing on a canvas and saving the
149 results to a PNG file.
151 <p>Vecto depends on the following libraries:
153 <ul>
154 <li> <a href="http://projects.tuxee.net/cl-vectors/">CL-VECTORS</a>
155 <li> <a href="http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF</a>
156 <li> <a href="http://www.xach.com/lisp/salza2/">Salza2</a>
157 <li> <a href="http://www.xach.com/lisp/zpng/">ZPNG</a>
158 </ul>
160 <p>The easiest way to install Vecto and all its dependencies is
161 with <a href="http://www.quicklisp.org/">Quicklisp</a>.
163 <p>Vecto's function interface is similar to the
164 PDF vector description and painting interface: you create images by
165 describing vector paths, then using stroke or fill operations to paint
166 to the canvas.
168 <p>Vecto's color system uses red, green, blue, and alpha color
169 components for drawing. The results can be be saved to a PNG with an
170 alpha channel.
172 <p>Vecto's coordinate system starts at the lower-left corner of the
173 image, and increases rightwards along the X axis and upwards along the
174 Y axis.
176 <p>All measurements are in pixels.
178 <p>PDF is a feature-rich system. Vecto supports a small subset of
179 PDF-style operations. In particular, it does not support:
181 <ul>
182 <li> sampled images
183 <li> pattern or functional fill
184 <li> complex layout of text
185 <li> PostScript fonts
186 <li> non-RGB color spaces
187 </ul>
189 <p>Other limitations:
191 <ul>
192 <li> No output formats other than 8-bit, truecolor-alpha PNGs
193 <li> No access to underlying pixel data
194 </ul>
196 <p>Related libraries:
198 <ul>
199 <li> <a href="http://common-lisp.net/project/imago/">Imago</a>
201 <li> <a href="http://cyrusharmon.org/projects?project=ch-image">ch-image</a>
203 <li> <a href="http://ygingras.net/poly-pen">Poly-pen</a>
204 </ul>
207 <a name='sect-examples'><h3>Examples</h3></a>
209 <p>All examples are available in <tt>doc/examples.lisp</tt> in the Vecto
210 distribution. That file starts with:
212 <pre>
213 (defpackage #:vecto-examples
214 (:use #:cl #:vecto))
216 (in-package #:vecto-examples)
217 </pre>
220 <pre>
221 <img border=0 align=right src='lambda-example.png'
222 >(defun radiant-lambda (file)
223 (<a href='#with-canvas'>with-canvas</a> (:width 90 :height 90)
224 (let ((font (<a href='#get-font'>get-font</a> "times.ttf"))
225 (step (/ pi 7)))
226 (<a href='#set-font'>set-font</a> font 40)
227 (<a href='#translate'>translate</a> 45 45)
228 (<a href='#draw-centered-string'>draw-centered-string</a> 0 -10 #(#x3BB))
229 (<a href='#set-rgba-stroke'>set-rgb-stroke</a> 1 0 0)
230 (<a href='#centered-circle-path'>centered-circle-path</a> 0 0 35)
231 (<a href='#stroke'>stroke</a>)
232 (<a href='#set-rgba-stroke'>set-rgba-stroke</a> 0 0 1.0 0.5)
233 (<a href='#set-line-width'>set-line-width</a> 4)
234 (dotimes (i 14)
235 (<a href='#with-graphics-state'>with-graphics-state</a>
236 (<a href='#rotate'>rotate</a> (* i step))
237 (<a href='#move-to'>move-to</a> 30 0)
238 (<a href='#line-to'>line-to</a> 40 0)
239 (stroke)))
240 (<a href='#save-png'>save-png</a> file))))
241 </pre>
243 <pre>
244 <img align=right src='feedlike-icon.png'
245 >(defun feedlike-icon (file)
246 (with-canvas (:width 100 :height 100)
247 (set-rgb-fill 1.0 0.65 0.3)
248 (<a href='#rounded-rectangle'>rounded-rectangle</a> 0 0 100 100 10 10)
249 (<a href='#fill-path'>fill-path</a>)
250 (set-rgb-fill 1.0 1.0 1.0)
251 (centered-circle-path 20 20 10)
252 (fill-path)
253 (flet ((quarter-circle (x y radius)
254 (move-to (+ x radius) y)
255 (<a href='#arc'>arc</a> x y radius 0 (/ pi 2))))
256 (set-rgb-stroke 1.0 1.0 1.0)
257 (set-line-width 15)
258 (quarter-circle 20 20 30)
259 (stroke)
260 (quarter-circle 20 20 60)
261 (stroke))
262 (rounded-rectangle 5 5 90 90 7 7)
263 (<a href='#set-gradient-fill'>set-gradient-fill</a> 50 90
264 1.0 1.0 1.0 0.7
265 50 20
266 1.0 1.0 1.0 0.0)
267 (set-line-width 2)
268 (set-rgba-stroke 1.0 1.0 1.0 0.1)
269 (<a href='#fill-and-stroke'>fill-and-stroke</a>)
270 (save-png file)))
271 </pre>
273 <pre><div style='float: right' class='transparent'><img src='star-clipping.png'
274 ></div>(defun star-clipping (file)
275 (with-canvas (:width 200 :height 200)
276 (let ((size 100)
277 (angle 0)
278 (step (* 2 (/ (* pi 2) 5))))
279 (translate size size)
280 (move-to 0 size)
281 (dotimes (i 5)
282 (setf angle (+ angle step))
283 (line-to (* (sin angle) size)
284 (* (cos angle) size)))
285 (<a href='#even-odd-clip-path'><tt>even-odd-clip-path</tt></a>)
286 (<a href='#end-path-no-op'><tt>end-path-no-op</tt></a>)
287 (flet ((circle (distance)
288 (<a href='#set-rgba-fill'><tt>set-rgba-fill</tt></a> distance 0 0
289 (- 1.0 distance))
290 (centered-circle-path 0 0 (* size distance))
291 (fill-path)))
292 (loop for i downfrom 1.0 by 0.05
293 repeat 20 do
294 (circle i)))
295 (save-png file))))
296 </pre>
298 <a name='sect-dictionary'><h3>Dictionary</h3></a>
300 <p>The following symbols are exported from the <tt>VECTO</tt> package.
302 <a name='sect-canvases'><h4>Canvases</h4></a>
304 <p><a name='with-canvas'>[Macro]</a><br>
305 <b>with-canvas</b> (<tt>&amp;key</tt> <i>width</i> <i>height</i>)
306 <tt>&amp;body</tt> <i>body</i>
308 <blockquote>
309 Evaluates <i>body</i> with a canvas established with the specified
310 dimensions as the target for drawing commands. The canvas is initially
311 completely clear (all pixels have 0 alpha).
312 </blockquote>
315 <p><a name='clear-canvas'>[Function]</a><br>
316 <b>clear-canvas</b> => |
318 <blockquote>
319 Completely fills the canvas with the current fill color. Any marks on
320 the canvas are cleared.
321 </blockquote>
324 <p><a name='save-png'>[Function]</a><br>
325 <b>save-png</b> <i>file</i> => <i>truename</i>
327 <blockquote>
328 Writes the contents of the canvas as the PNG <i>file</i>, and returns
329 the truename of <i>file</i>.
330 </blockquote>
333 <p><a name='save-png-stream'>[Function]</a><br>
334 <b>save-png-stream</b> <i>stream</i> => |
336 <blockquote>
337 Writes the contents of the canvas as a PNG to <i>stream</i>, which
338 must accept <tt>(unsigned-byte&nbsp;8)</tt> data.
339 </blockquote>
342 <a name='sect-graphics-state'><h4>Graphics State</h4></a>
344 <p>The graphics state stores several parameters used for graphic
345 operations.
347 <p><a name='with-graphics-state'>[Macro]</a><br>
348 <b>with-graphics-state</b> <tt>&amp;body</tt> <i>body</i>
350 <blockquote>
351 Evaluates the forms of <i>body</i> with a copy of the current graphics
352 state. Any modifications to the state are undone at the end of the
353 form.
354 </blockquote>
357 <p><a name='set-rgba-fill'>[Functions]</a><br>
358 <b>set-rgba-fill</b> <i>r</i> <i>g</i> <i>b</i> <i>alpha</i> => |<br>
359 <b>set-rgb-fill</b> <i>r</i> <i>g</i> <i>b</i> => |
361 <blockquote>
362 Sets the fill color. <i>r</i>, <i>g</i>, <i>b</i>, and <i>alpha</i>
363 should be in the range of 0.0 to 1.0.
365 <p><tt>set-rgb-fill</tt> is the same as <tt>set-rgba-fill</tt> with an
366 implicit alpha value of 1.0.
368 <p>The fill color is used
369 for <a
370 href='#clear-canvas'><tt>CLEAR-CANVAS</tt></a>, <a
371 href='#fill-path'><tt>FILL-PATH</tt></a>, <a
372 href='#even-odd-fill'><tt>EVEN-ODD-FILL</tt></a>, <a
373 href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>, <a
374 href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>,
375 and <a href='#draw-string'><tt>DRAW-STRING</tt></a>.
377 </blockquote>
379 <p><a name='set-gradient-fill'>[Function]</a><br>
380 <b>set-gradient-fill</b>
381 <i>x0</i> <i>y0</i> <i>r0</i> <i>g0</i> <i>b0</i> <i>a0</i>
382 <i>x1</i> <i>y1</i> <i>r1</i> <i>g1</i> <i>b1</i> <i>a1</i>
383 <tt>&amp;key</tt> (<i>extend-start</i> <tt>t</tt>)
384 (<i>extend-end</i> <tt>t</tt>)
385 (<i>domain-function</i> <tt>'linear-domain</tt>)
387 <blockquote>
388 Set the fill color source to an axial gradient. The start point
389 is <i>x0,y0</i> and the start color is <i>r0,g0,b0,a0</i>. The end
390 point is <i>x1, y1</i> and the end color is <i>r1,g1,b1,a1</i>.
392 <p>Two domain functions are available:
394 <ul>
396 <li> <tt>LINEAR-DOMAIN</tt>, the default, makes a transition from the
397 start color to the end color along the axis between the start and end
398 points
400 <li> <tt>BILINEAR-DOMAIN</tt> makes a transition from the start color
401 to the end color from the start point to the midpoint, then back to
402 the start color from the midpoint to the end point
403 </ul>
405 <pre><img style='float: right' class='transparent'
406 src='linear-gradient.png'>(defun gradient-example (file)
407 (with-canvas (:width 200 :height 50)
408 (set-gradient-fill 25 0
409 1 0 0 1
410 175 0
411 1 0 0 0)
412 (rectangle 0 0 200 50)
413 (fill-path)
414 (save-png file)))
415 </pre>
417 <pre><img style='float: right' class='transparent'
418 src='bilinear-gradient.png'>(defun gradient-bilinear-example (file)
419 (with-canvas (:width 200 :height 50)
420 (set-gradient-fill 25 0
421 1 0 0 1
422 175 0
423 1 0 0 0
424 :domain-function 'bilinear-domain)
425 (rectangle 0 0 200 50)
426 (fill-path)
427 (save-png file)))
428 </pre>
432 </blockquote>
434 <p><a name='set-rgba-stroke'>[Functions]</a><br>
435 <b>set-rgba-stroke</b> <i>r</i> <i>g</i> <i>b</i> <i>alpha</i> => |<br>
436 <b>set-rgb-stroke</b> <i>r</i> <i>g</i> <i>b</i> => |
438 <blockquote>
439 Sets the stroke color. <i>r</i>, <i>g</i>, <i>b</i>, and <i>alpha</i>
440 should be in the range of 0.0 to 1.0.
442 <p><tt>set-rgb-stroke</tt> is the same as <tt>set-rgba-stroke</tt>
443 with an implicit alpha value of 1.0.
445 <p>The stroke color is used for <a href='#stroke'><tt>STROKE</tt></a>,
446 <a href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>,
447 and <a href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>.
448 </blockquote>
451 <p><a name='set-line-cap'>[Function]</a><br>
452 <b>set-line-cap</b> <i>style</i> => |
454 <blockquote>
455 Sets the line cap style to <i>style</i>, which must be one
456 of <tt>:BUTT</tt>, <tt>:SQUARE</tt>, or <tt>:ROUND</tt>. The initial
457 value is <tt>:BUTT</tt>.
459 <p><table cellspacing=5 id="line-cap">
460 <tr>
461 <td align=center><img src="cap-style-butt.png"></td>
462 <td align=center><img src="cap-style-square.png"></td>
463 <td align=center><img src="cap-style-round.png"></td>
464 </tr>
465 <tr>
466 <td align=center><tt>:BUTT</tt></td>
467 <td align=center><tt>:SQUARE</tt></td>
468 <td align=center><tt>:ROUND</tt></td>
469 </tr>
470 </table>
472 </blockquote>
475 <p><a name='set-line-join'>[Function]</a><br>
476 <b>set-line-join</b> <i>style</i> => |
478 <blockquote>
479 Sets the line join style to <i>style</i>, which must be one
480 of <tt>:MITER</tt>, <tt>:BEVEL</tt>, or <tt>:ROUND</tt>. The initial
481 value is <tt>:MITER</tt>.
483 <p><table cellspacing=5 id="line-join">
484 <tr>
485 <td align=center><img src="join-style-miter.png"></td>
486 <td align=center><img src="join-style-bevel.png"></td>
487 <td align=center><img src="join-style-round.png"></td>
488 </tr>
489 <tr>
490 <td align=center><tt>:MITER</tt></td>
491 <td align=center><tt>:BEVEL</tt></td>
492 <td align=center><tt>:ROUND</tt></td>
493 </tr>
494 </table>
496 </blockquote>
499 <p><a name='set-line-width'>[Function]</a><br>
500 <b>set-line-width</b> <i>width</i> => |
502 <blockquote>
503 Sets the line width for strokes to <i>width</i>.
504 </blockquote>
508 <p><a name='set-dash-pattern'>[Function]</a><br>
509 <b>set-dash-pattern</b> <i>dash-vector</i> <i>phase</i> => |
511 <blockquote>
512 Sets the dash pattern according to <i>dash-vector</i> and <i>phase</i>.
514 <p><i>dash-vector</i> should be a vector of numbers denoting on and
515 off patterns for a stroke. An empty <i>dash-vector</i> is the same as
516 having no dash pattern at all.
518 <p><i>phase</i> is how far along the dash pattern to proceed before
519 applying the pattern to the current stroke.
522 <table>
523 <tr>
524 <th>Appearance</th>
525 <th>Dash Vector and Phase</th>
526 </tr>
527 <tr>
528 <td align=center><img src="dash-pattern-none.png"></td>
529 <td align=left><tt>#() 0</tt></td>
530 </tr>
531 <tr>
532 <td align=center><img src="dash-pattern-a.png"></td>
533 <td align=left><tt>#(30 30) 0</tt></td>
534 </tr>
535 <tr>
536 <td align=center><img src="dash-pattern-b.png"></td>
537 <td align=left><tt>#(30 30) 15</tt></td>
538 </tr>
539 <tr>
540 <td align=center><img src="dash-pattern-c.png"></td>
541 <td align=left><tt>#(10 20 10 40) 0</tt></td>
542 </tr>
543 <tr>
544 <td align=center><img src="dash-pattern-d.png"></td>
545 <td align=left><tt>#(10 20 10 40) 13</tt></td>
546 </tr>
547 <tr>
548 <td align=center><img src="dash-pattern-e.png"></td>
549 <td align=left><tt>#(30 30) 0</tt>, <tt>:ROUND</tt> line caps</td>
550 </tr>
551 </table>
552 </blockquote>
555 <p><a name='translate'>[Function]</a><br>
556 <b>translate</b> <i>x</i> <i>y</i> => |
558 <blockquote>
559 Offsets the coordinate system by <i>x</i> units horizontally
560 and <i>y</i> units vertically.
561 </blockquote>
564 <p><a name='rotate'>[Function]</a><br>
565 <b>rotate</b> <i>radians</i> => |
567 <blockquote>
568 Rotates the coordinate system by <i>radians</i>.
569 </blockquote>
572 <p><a name='scale'>[Function]</a><br>
573 <b>scale</b> <i>sx</i> <i>sy</i> => |
575 <blockquote>
576 Scales the coordinate system by <i>sx</i> horizontally
577 and <i>sy</i> vertically.
578 </blockquote>
581 <p><a name='skew'>[Function]</a><br>
582 <b>skew</b> <i>ax</i> <i>ay</i> => |
584 <blockquote>
585 Skews the X axis of the coordinate system by <i>ax</i> radians and the
586 Y axis by <i>ay</i> radians.
587 </blockquote>
590 <p><a name='clip-path'>[Function]</a><br>
591 <b>clip-path</b> => |
593 <blockquote>
594 Defines a clipping path based on the current path. It is not applied
595 immediately, but is created after after the painting is done in the
596 next call to one
597 of <a
598 href='#fill-path'><tt>FILL-PATH</tt></a>, <a
599 href='#even-odd-fill'><tt>EVEN-ODD-FILL</tt></a>, <a
600 href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>, <a
601 href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>,
602 or <a href='#end-path-no-op'><tt>END-PATH-NO-OP</tt></a>.
604 <p>The clipping path initially covers the entire canvas; no clipping
605 is done. Subsequent calls to <tt>CLIP-PATH</tt> set the clipping path
606 to the intersection of the established clipping path and the new
607 clipping path, and all drawing will be done within the outline of the
608 clipping path.
610 <p>The outline of the clipping path is defined with the nonzero
611 winding rule, as with <a href='#fill-path'><tt>FILL-PATH</tt></a>.
613 <p>There is no way to enlarge the clipping path. However, the clipping
614 path is part of the graphics state, so changes may be localized by
615 using <a href='#with-graphics-state'><tt>WITH-GRAPHICS-STATE</tt></a>.
618 <p><table>
619 <tr>
620 <td><img src="clip-unclipped.png"></td>
621 <td>A filled red rectangle, not clipped</td>
622 </tr>
623 <tr>
624 <td><img src="clip-to-circle.png"></td>
625 <td>The same rectangle drawn with a circle clipping path in effect</td>
626 </tr>
627 <tr>
628 <td><img src="clip-to-rectangle.png"></td>
629 <td>Clipped to a rounded rectangle clipping path</td>
630 </tr>
631 <tr>
632 <td><img src="clip-to-both.png"></td>
633 <td>Clipped to the intersection of the circle and rounded rectangle clipping paths</td>
634 </tr>
635 </table>
639 </blockquote>
642 <p><a name='even-odd-clip-path'>[Function]</a><br>
643 <b>even-odd-clip-path</b> => |
645 <blockquote>
646 Like <a href='#clip-path'><tt>CLIP-PATH</tt></a>, but uses the
647 even/odd fill rule to determine the outline of the clipping path.
648 </blockquote>
651 <a name='sect-paths'><h4>Paths</h4></a>
653 <p>Paths are used to create lines for stroking or outlines for
654 filling. Paths consist of straight lines and curves. Paths consist of
655 one or more subpaths.
657 <p><a name='move-to'>[Function]</a><br>
658 <b>move-to</b> <i>x</i> <i>y</i> => |
660 <blockquote>
661 Starts a new subpath at (<i>x</i>,<i>y</i>). <tt>move-to</tt> must be the
662 first step of constructing a subpath.
663 </blockquote>
666 <p><a name='line-to'>[Function]</a><br>
667 <b>line-to</b> <i>x</i> <i>y</i> => |
669 <blockquote>
670 Appends a straight line ending at (<i>x</i>,<i>y</i>) to the
671 current subpath.
672 </blockquote>
675 <p><a name='curve-to'>[Function]</a><br>
676 <b>curve-to</b>
677 <i>cx1</i> <i>cy1</i>
678 <i>cx2</i> <i>cy2</i>
679 <i>x</i> <i>y</i> => |
681 <blockquote>
682 Appends a
683 cubic <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier
684 curve</a> ending at (<i>x</i>,<i>y</i>) and with control
685 points (<i>cx1</i>,<i>cy1</i>) and (<i>cx2</i>,<i>cy2</i>) to the current
686 subpath.
687 </blockquote>
690 <p><a name='quadratic-to'>[Function]</a><br>
691 <b>quadratic-to</b>
692 <i>cx</i> <i>cy</i>
693 <i>x</i> <i>y</i> => |
695 <blockquote>
696 Appends a quadratic B&eacute;zier curve ending at (<i>x</i>,<i>y</i>)
697 and with the control point (<i>cx</i>,<i>cy</i>) to the current
698 subpath.
699 </blockquote>
702 <p><a name='arc'>[Function]</a><br>
703 <b>arc</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
704 => |
706 <blockquote>
707 Appends an arc of a circle to the current path. The center of the arc is
708 at (<i>x</i>,<i>y</i>). The arc begins at point at a
709 distance <i>radius</i> from the center and with an angle <i>angle1</i>
710 radians from the positive x axis, and ends at the point
711 with <i>angle2</i> radians. If <i>angle2</i> is less
712 than <i>angle1</i>, it is increased by increasing multiples of 2&pi;
713 until it is greater than or equal to <i>angle1</i>.
715 <p><table cellpadding=5>
716 <tr><td align=center><img src="arc.png"></td></tr>
717 <tr><td><span style='color: #0f0'><i>radius</i></span>,
718 <span style='color: #f00'><i>angle1</i></span>,
719 <span style='color: #00f'><i>angle2</i></span></td></tr>
720 </table>
722 <p>If there is a current point, a straight line is added from the
723 current point to the start point of the arc. Otherwise, a new path
724 is started.
726 <pre><img class='transparent' style='float: right' src='pie-wedge.png'
727 >(defun pie-wedge (file)
728 (with-canvas (:width 80 :height 60)
729 (let ((x 0) (y 0)
730 (radius 70)
731 (angle1 (* (/ pi 180) 15))
732 (angle2 (* (/ pi 180) 45)))
733 (translate 5 5)
734 (set-rgb-fill 1 1 1)
735 (move-to 0 0)
736 (arc x y radius angle1 angle2)
737 (fill-and-stroke)
738 (save-png file))))
739 </pre>
741 </blockquote>
744 <p><a name='arcn'>[Function]</a><br>
745 <b>arcn</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
746 => |
748 <blockquote>
749 Like <a href='#arc'><tt>ARC</tt></a>, but draws the arc clockwise
750 instead of counterclockwise. If <i>angle2</i> is greater
751 than <i>angle1</i>, it is decreased by increasing multiples of 2&pi;
752 until it is less than or equal to <i>angle1</i>.
754 <pre><img class='transparent' style='float: right' src='wiper.png'
755 >(defun wiper (file)
756 (with-canvas (:width 70 :height 70)
757 (let ((x 0) (y 0)
758 (r1 40) (r2 60)
759 (angle1 0)
760 (angle2 (* (/ pi 180) 90)))
761 (translate 5 5)
762 (set-rgba-fill 1 1 1 0.75)
763 (arc x y r1 angle1 angle2)
764 (arcn x y r2 angle2 angle1)
765 (fill-and-stroke)
766 (save-png file))))
767 </pre>
769 </blockquote>
772 <p><a name='close-subpath'>[Function]</a><br>
773 <b>close-subpath</b> => |
775 <blockquote>
776 Closes the current subpath. If the current point is not the same as the
777 starting point for the subpath, appends a straight line from the
778 current point to the starting point of the current subpath.
780 <p>Subpaths with start and end points that coincidentally overlap are
781 not the same as closed subpaths. The distinction is important when
782 stroking:
784 <p><table cellpadding=5>
785 <tr>
786 <td align=center><img src="open-subpath.png"></td>
787 <td align=center><img src="closed-subpath.png"></td>
788 </tr>
789 <tr>
790 <td align=center>Open subpath</td>
791 <td align=center>Closed subpath</td>
792 </tr>
793 </table>
795 <p>If the subpath is not closed, the start and points of the subpath
796 will be drawn with the current line cap style. If the path is
797 closed, the start and endpoints will be treated as joined and drawn
798 with the line join style.
799 </blockquote>
802 <p><a name='stroke-to-paths'>[Function]</a><br>
803 <b>stroke-to-paths</b> => |
805 <blockquote>
806 Sets the current active paths to the paths that would result from
807 outlining a <a href='#stroke'><tt>STROKE</tt></a> operation.
808 </blockquote>
811 <p><a name='rectangle'>[Function]</a><br>
812 <b>rectangle</b> <i>x</i> <i>y</i> <i>width</i> <i>height</i> => |
814 <blockquote>
815 Creates a rectangular subpath with the given <i>width</i>
816 and <i>height</i> that has its lower-left corner at
817 (<i>x</i>,<i>y</i>). It is effectively the same as:
819 <pre>
820 (move-to x y)
821 (line-to (+ x width) y)
822 (line-to (+ x width) (+ y height))
823 (line-to x (+ y height))
824 (close-subpath)
825 </pre>
826 </blockquote>
828 <p><a name='rounded-rectangle'>[Function]</a><br>
829 <b>rounded-rectangle</b> <i>x</i> <i>y</i>
830 <i>width</i> <i>height</i> <i>rx</i> <i>ry</i> => |
832 <blockquote>
833 Like <a href='#rectangle'><tt>RECTANGLE</tt></a>, but rounds the
834 corners of the rectangle paths by the x radius <i>rx</i> and the y
835 radius <i>ry</i>.
836 </blockquote>
838 <p><a name='centered-ellipse-path'>[Function]</a><br>
839 <b>centered-ellipse-path</b>
840 <i>x</i> <i>y</i>
841 <i>rx</i> <i>ry</i>
843 <blockquote>
844 Adds a closed subpath that outlines an ellipse centered at
845 (<i>x</i>,<i>y</i>) with an X radius of <i>rx</i> and a Y radius
846 of <i>ry</i>.
847 </blockquote>
849 <p><a name='centered-circle-path'>[Function]</a><br>
850 <b>centered-circle-path</b> <i>x</i> <i>y</i> <i>radius</i> => |
852 <blockquote>
853 Adds a closed subpath that outlines a circle centered at
854 (<i>x</i>,<i>y</i>) with a radius of <i>radius</i>. It is effectively
855 the same as:
857 <pre>
858 (centered-ellipse-path x y radius radius)
859 </pre>
860 </blockquote>
864 <a name='sect-painting'><h4>Painting</h4></a>
866 <p>After a path is defined, filling, stroking, or both will use the
867 path to apply color to the canvas. After a path has been filled or
868 stroked, it is no longer active; it effectively disappears.
871 <p><a name='fill-path'>[Function]</a><br>
872 <b>fill-path</b> => |
874 <blockquote>
875 Fills the current path with the fill color or gradient. If the path
876 has not been explicitly closed
877 with <a href='#close-subpath'><tt>CLOSE-SUBPATH</tt></a>, it is
878 implicitly closed before filling. The non-zero winding rule is used
879 to determine what areas are considered inside the path.
880 </blockquote>
883 <p><a name='even-odd-fill'>[Function]</a><br>
884 <b>even-odd-fill</b> => |
886 <blockquote>
887 The same as <a href='#fill-path'><tt>FILL-PATH</tt></a>, but uses the
888 even/odd rule to determine what areas are considered inside the path.
889 </blockquote>
892 <p><a name='stroke'>[Function]</a><br>
893 <b>stroke</b> => |
895 <blockquote>
896 Strokes the current path. The line width, stroke color, line join
897 style, line cap style, and dash pattern and phase determine how the
898 stroked path will appear on the canvas.
899 </blockquote>
902 <p><a name='fill-and-stroke'>[Function]</a><br>
903 <b>fill-and-stroke</b> => |
905 <blockquote>
906 Fills the current path, then strokes it.
907 </blockquote>
910 <p><a name='even-odd-fill-and-stroke'>[Function]</a><br>
911 <b>even-odd-fill-and-stroke</b> => |
913 <blockquote>
914 Fills the current path using the even/odd rule, then strokes it.
915 </blockquote>
918 <p><a name='end-path-no-op'>[Function]</a><br>
919 <b>end-path-no-op</b> => |
921 <blockquote>
922 Ends the current path without painting anything. If a clipping path
923 has been specified with <a href='#clip-path'><tt>CLIP-PATH</tt></a>
924 or <a href='#even-odd-clip-path'><tt>EVEN-ODD-CLIP-PATH</tt></a>, it
925 will be created by <tt>end-path-no-op</tt>.
926 </blockquote>
930 <a name='sect-text'><h4>Text</h4></a>
932 <p>Vecto can draw text to a canvas. It loads glyph shapes from
933 TrueType font files
934 with <a href="http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF</a>.
936 <p><a name='get-font'>[Function]</a><br>
937 <b>get-font</b> <i>font-file</i> => <i>font-loader</i>
939 <blockquote>
940 Creates and returns a ZPB-TTF font loader object
941 from <i>font-file</i>. Any font loader created this way will
942 automatically be closed at the end of its
943 enclosing <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form.
944 </blockquote>
947 <p><a name='set-font'>[Function]</a><br>
948 <b>set-font</b> <i>font-loader</i> <i>size</i> => |
950 <blockquote>
951 Sets the active font to the font associated
952 with <i>font-loader</i>, scaled to <i>size</i> units per line.
954 <p>The first argument can be any ZPB-TTF font loader; it need not be
955 created via <a href='#get-font'><tt>GET-FONT</tt></a>. However, only
956 font loaders created via <tt>GET-FONT</tt> will be automatically
957 closed at the end of <a href='#with-canvas'><tt>WITH-CANVAS</tt></a>.
958 </blockquote>
961 <p><a name='set-character-spacing'>[Function]</a><br>
962 <b>set-character-spacing</b> <i>spacing</i> => |
964 <blockquote>
965 Sets the scale of the spacing used between characters when drawing
966 text with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
967 functions.
969 <p>Normally, the character spacing for drawing text is taken directly
970 from a font's advance-width and kerning
971 metrics. <tt>SET-CHARACTER-SPACING</tt> can be used to adjust this
972 spacing; for example, a character spacing of 2.0d0 would double the
973 normal space between characters, and 0.5d0 would halve it.
974 </blockquote>
976 <p><a name='*default-character-spacing*'>[Special variable]</a><br>
977 <b>*default-character-spacing*</b>
979 <blockquote>
980 The default scale for character spacing when drawing text
981 with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
982 functions. Initial value is 1.0d0.
984 <p>Changes to this variable affect the
985 next <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form. To affect
986 the spacing within the current <tt>WITH-CANVAS</tt> form,
987 use <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>.
988 </blockquote>
991 <p><a name='draw-string'>[Function]</a><br>
992 <b>draw-string</b> <i>x</i> <i>y</i> <i>string</i> => |
994 <blockquote>
995 Draws <i>string</i> on the canvas with the active font. The glyph
996 origin of the first character in the string is positioned at <i>x</i>
997 and the baseline of the string is positioned at <i>y</i>. The text is
998 filled with the current <a href='#set-rgba-fill'>fill color</a>.
1000 <p>The string may be a specialized vector of characters (a true CL
1001 string) or a vector containing characters, Unicode code-points, or both. For
1002 example, <tt>#(#\L #\a #\m #\b #\d #\a #\= #x3BB)</tt> is a valid
1003 argument for <tt>DRAW-STRING</tt>.
1005 <p>The horizontal space between characters is determined by the
1006 advance-width and kerning metrics of the font, then multiplied by
1007 the current character spacing. At the default character spacing of
1008 1.0d0, the spacing is not adjusted at
1009 all. <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>
1010 can be used to increase or decrease the character spacing.
1011 </blockquote>
1014 <p><a name='string-paths'>[Function]</a><br>
1015 <b>string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1017 <blockquote>
1018 Like <a href='#draw-string'><tt>DRAW-STRING</tt></a>, but instead of
1019 drawing the text, adds the subpaths that make up the string glyphs to
1020 the graphics state. This can be used to stroke, fill, or clip based on
1021 the outlines of a string.
1022 </blockquote>
1025 <p><a name='draw-centered-string'>[Function]</a><br>
1026 <b>draw-centered-string</b> <i>x</i> <i>y</i> <i>string</i> => |
1028 <blockquote>
1029 Draws <i>string</i> on the canvas with the active font. The horizontal
1030 center of the string is positioned at <i>x</i> and the baseline of the
1031 string is positioned at <i>y</i>.
1032 </blockquote>
1035 <p><a name='centered-string-paths'>[Function]</a><br>
1036 <b>centered-string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1038 <blockquote>
1039 Like <a href='#draw-centered-string'><tt>DRAW-CENTERED-STRING</tt></a>,
1040 but adds subpaths instead of painting. See
1041 also <a href='#string-paths'><tt>STRING-PATHS</tt></a>.
1042 </blockquote>
1045 <p><a name='string-bounding-box'>[Function]</a><br>
1046 <b>string-bounding-box</b> <i>string</i> <i>size</i> <i>loader</i>
1047 => <i>#(xmin ymin xmax ymax)</i>
1049 <blockquote>
1050 Calculates the bounding box of <i>string</i> for <i>font-loader</i>
1051 at <i>size</i>.
1052 </blockquote>
1055 <a name='sect-miscellaneous'><h3>Miscellaneous</h3></a>
1057 <p><a name='const-kappa'>[Constant]</a><br>
1058 <b>+kappa+</b> => 0.5522847498307936d0.
1060 <blockquote>
1061 This constant is useful to draw portions of a circle.
1062 </blockquote>
1065 <a name='sect-references'><h2>References</h2></a>
1067 <ul>
1068 <li> Adobe Systems Inc., <a href="http://www.adobe.com/devnet/pdf/pdf_reference.html">PDF Reference, Sixth Edition, Version 1.7</a>
1069 <li> Lawrence Kesteloot, <a href="http://www.teamten.com/lawrence/graphics/premultiplication/">Alpha Premultiplication</a>
1070 <li> Dr. Thomas Sederberg, <a href="http://www.tsplines.com/resources/class_notes/Bezier_curves.pdf">B&eacute;zier curves</a>
1071 <li> Alvy Ray Smith, <a href="http://alvyray.com/Memos/MemosMicrosoft.htm#ImageCompositing">Image Compositing Fundamentals</a>
1072 <li> G. Adam Stanislav, <a href="http://www.whizkidtech.redprince.net/bezier/circle/">Drawing a circle with B&eacute;zier curves</a>
1073 <li> Alexander Thomas, <a href="http://www.dr-lex.be/random/matrix_inv.html">The Inverse and Determinants of 2x2 and 3x3 Matrices</a>
1074 <li> Wikipedia, <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier curve</a>
1076 </ul>
1079 <a name='sect-acknowledgements'><h2>Acknowledgements</h2></a>
1081 <p>Many thanks to <a href="http://www.elbeno.com/">Ben Deane</a> for
1082 permission to adapt code from his curve library for drawing arcs.
1084 <p>Ryan Davis helped fix my adaptation of the arc drawing.
1086 <a name='sect-feedback'><h2>Feedback</h2></a>
1088 <p>If you have any questions, comments, bug reports, or other feedback
1089 regarding Vecto, please email <a href="mailto:xach@xach.com">Zach
1090 Beane</a>.
1093 </div>
1094 </body>