Updated version to 1.4.10.
[vecto.git] / doc / index.html
blob9d690c40ba414c2521156c7fb578041da7834334
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.10, released on October 15th, 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='#ellipse-arc'><tt>ellipse-arc</tt></a>
101 <li> <a href='#ellipse-arcn'><tt>ellipse-arcn</tt></a>
102 <li> <a href='#close-subpath'><tt>close-subpath</tt></a>
103 <li> <a href='#stroke-to-paths'><tt>stroke-to-paths</tt></a>
104 <li> <a href='#rectangle'><tt>rectangle</tt></a>
105 <li> <a href='#rounded-rectangle'><tt>rounded-rectangle</tt></a>
106 <li> <a href='#centered-ellipse-path'><tt>centered-ellipse-path</tt></a>
107 <li> <a href='#centered-circle-path'><tt>centered-circle-path</tt></a>
108 </ul>
110 <li> <a href='#sect-painting'>Painting</a>
111 <ul>
112 <li> <a href='#fill-path'><tt>fill-path</tt></a>
113 <li> <a href='#even-odd-fill'><tt>even-odd-fill</tt></a>
114 <li> <a href='#stroke'><tt>stroke</tt></a>
115 <li> <a href='#fill-and-stroke'><tt>fill-and-stroke</tt></a>
116 <li> <a href='#even-odd-fill-and-stroke'><tt>even-odd-fill-and-stroke</tt></a>
117 <li> <a href='#end-path-no-op'><tt>end-path-no-op</tt></a>
118 </ul>
120 <li> <a href='#sect-text'>Text</a>
121 <ul>
122 <li> <a href='#get-font'><tt>get-font</tt></a>
123 <li> <a href='#set-font'><tt>set-font</tt></a>
124 <li> <a href='#set-character-spacing'><tt>set-character-spacing</tt></a>
125 <li> <a href='#*default-character-spacing*'><tt>*default-character-spacing*</tt></a>
126 <li> <a href='#draw-string'><tt>draw-string</tt></a>
127 <li> <a href='#string-paths'><tt>string-paths</tt></a>
128 <li> <a href='#draw-centered-string'><tt>draw-centered-string</tt></a>
129 <li> <a href='#centered-string-paths'><tt>centered-string-paths</tt></a>
130 <li> <a href='#string-bounding-box'><tt>string-bounding-box</tt></a>
131 </ul>
133 <li> <a href='#sect-miscellaneous'>Miscellaneous</a>
134 <ul>
135 <li> <a href='#const-kappa'><tt>+kappa+</tt></a>
136 </ul>
138 </ul>
140 <li> <a href='#sect-references'>References</a>
141 <li> <a href='#sect-acknowledgements'>Acknowledgements</a>
142 <li> <a href='#sect-feedback'>Feedback</a>
144 </ol>
146 <a name='sect-overview-and-limitations'><h3>Overview and Limitations</h3></a>
148 <p>Vecto is a library that provides a simple interface to the
149 the <a href="http://projects.tuxee.net/cl-vectors/">CL-VECTORS</a>
150 vector drawing library. It supports drawing on a canvas and saving the
151 results to a PNG file.
153 <p>Vecto depends on the following libraries:
155 <ul>
156 <li> <a href="http://projects.tuxee.net/cl-vectors/">CL-VECTORS</a>
157 <li> <a href="http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF</a>
158 <li> <a href="http://www.xach.com/lisp/salza2/">Salza2</a>
159 <li> <a href="http://www.xach.com/lisp/zpng/">ZPNG</a>
160 </ul>
162 <p>The easiest way to install Vecto and all its dependencies is
163 with <a href="http://www.quicklisp.org/">Quicklisp</a>.
165 <p>Vecto's function interface is similar to the
166 PDF vector description and painting interface: you create images by
167 describing vector paths, then using stroke or fill operations to paint
168 to the canvas.
170 <p>Vecto's color system uses red, green, blue, and alpha color
171 components for drawing. The results can be be saved to a PNG with an
172 alpha channel.
174 <p>Vecto's coordinate system starts at the lower-left corner of the
175 image, and increases rightwards along the X axis and upwards along the
176 Y axis.
178 <p>All measurements are in pixels.
180 <p>PDF is a feature-rich system. Vecto supports a small subset of
181 PDF-style operations. In particular, it does not support:
183 <ul>
184 <li> sampled images
185 <li> pattern or functional fill
186 <li> complex layout of text
187 <li> PostScript fonts
188 <li> non-RGB color spaces
189 </ul>
191 <p>Other limitations:
193 <ul>
194 <li> No output formats other than 8-bit, truecolor-alpha PNGs
195 <li> No access to underlying pixel data
196 </ul>
198 <p>Related libraries:
200 <ul>
201 <li> <a href="http://common-lisp.net/project/imago/">Imago</a>
203 <li> <a href="http://cyrusharmon.org/projects?project=ch-image">ch-image</a>
205 <li> <a href="http://ygingras.net/poly-pen">Poly-pen</a>
206 </ul>
209 <a name='sect-examples'><h3>Examples</h3></a>
211 <p>All examples are available in <tt>doc/examples.lisp</tt> in the Vecto
212 distribution. That file starts with:
214 <pre>
215 (defpackage #:vecto-examples
216 (:use #:cl #:vecto))
218 (in-package #:vecto-examples)
219 </pre>
222 <pre>
223 <img border=0 align=right src='lambda-example.png'
224 >(defun radiant-lambda (file)
225 (<a href='#with-canvas'>with-canvas</a> (:width 90 :height 90)
226 (let ((font (<a href='#get-font'>get-font</a> "times.ttf"))
227 (step (/ pi 7)))
228 (<a href='#set-font'>set-font</a> font 40)
229 (<a href='#translate'>translate</a> 45 45)
230 (<a href='#draw-centered-string'>draw-centered-string</a> 0 -10 #(#x3BB))
231 (<a href='#set-rgba-stroke'>set-rgb-stroke</a> 1 0 0)
232 (<a href='#centered-circle-path'>centered-circle-path</a> 0 0 35)
233 (<a href='#stroke'>stroke</a>)
234 (<a href='#set-rgba-stroke'>set-rgba-stroke</a> 0 0 1.0 0.5)
235 (<a href='#set-line-width'>set-line-width</a> 4)
236 (dotimes (i 14)
237 (<a href='#with-graphics-state'>with-graphics-state</a>
238 (<a href='#rotate'>rotate</a> (* i step))
239 (<a href='#move-to'>move-to</a> 30 0)
240 (<a href='#line-to'>line-to</a> 40 0)
241 (stroke)))
242 (<a href='#save-png'>save-png</a> file))))
243 </pre>
245 <pre>
246 <img align=right src='feedlike-icon.png'
247 >(defun feedlike-icon (file)
248 (with-canvas (:width 100 :height 100)
249 (set-rgb-fill 1.0 0.65 0.3)
250 (<a href='#rounded-rectangle'>rounded-rectangle</a> 0 0 100 100 10 10)
251 (<a href='#fill-path'>fill-path</a>)
252 (set-rgb-fill 1.0 1.0 1.0)
253 (centered-circle-path 20 20 10)
254 (fill-path)
255 (flet ((quarter-circle (x y radius)
256 (move-to (+ x radius) y)
257 (<a href='#arc'>arc</a> x y radius 0 (/ pi 2))))
258 (set-rgb-stroke 1.0 1.0 1.0)
259 (set-line-width 15)
260 (quarter-circle 20 20 30)
261 (stroke)
262 (quarter-circle 20 20 60)
263 (stroke))
264 (rounded-rectangle 5 5 90 90 7 7)
265 (<a href='#set-gradient-fill'>set-gradient-fill</a> 50 90
266 1.0 1.0 1.0 0.7
267 50 20
268 1.0 1.0 1.0 0.0)
269 (set-line-width 2)
270 (set-rgba-stroke 1.0 1.0 1.0 0.1)
271 (<a href='#fill-and-stroke'>fill-and-stroke</a>)
272 (save-png file)))
273 </pre>
275 <pre><div style='float: right' class='transparent'><img src='star-clipping.png'
276 ></div>(defun star-clipping (file)
277 (with-canvas (:width 200 :height 200)
278 (let ((size 100)
279 (angle 0)
280 (step (* 2 (/ (* pi 2) 5))))
281 (translate size size)
282 (move-to 0 size)
283 (dotimes (i 5)
284 (setf angle (+ angle step))
285 (line-to (* (sin angle) size)
286 (* (cos angle) size)))
287 (<a href='#even-odd-clip-path'><tt>even-odd-clip-path</tt></a>)
288 (<a href='#end-path-no-op'><tt>end-path-no-op</tt></a>)
289 (flet ((circle (distance)
290 (<a href='#set-rgba-fill'><tt>set-rgba-fill</tt></a> distance 0 0
291 (- 1.0 distance))
292 (centered-circle-path 0 0 (* size distance))
293 (fill-path)))
294 (loop for i downfrom 1.0 by 0.05
295 repeat 20 do
296 (circle i)))
297 (save-png file))))
298 </pre>
300 <a name='sect-dictionary'><h3>Dictionary</h3></a>
302 <p>The following symbols are exported from the <tt>VECTO</tt> package.
304 <a name='sect-canvases'><h4>Canvases</h4></a>
306 <p><a name='with-canvas'>[Macro]</a><br>
307 <b>with-canvas</b> (<tt>&amp;key</tt> <i>width</i> <i>height</i>)
308 <tt>&amp;body</tt> <i>body</i>
310 <blockquote>
311 Evaluates <i>body</i> with a canvas established with the specified
312 dimensions as the target for drawing commands. The canvas is initially
313 completely clear (all pixels have 0 alpha).
314 </blockquote>
317 <p><a name='clear-canvas'>[Function]</a><br>
318 <b>clear-canvas</b> => |
320 <blockquote>
321 Completely fills the canvas with the current fill color. Any marks on
322 the canvas are cleared.
323 </blockquote>
326 <p><a name='save-png'>[Function]</a><br>
327 <b>save-png</b> <i>file</i> => <i>truename</i>
329 <blockquote>
330 Writes the contents of the canvas as the PNG <i>file</i>, and returns
331 the truename of <i>file</i>.
332 </blockquote>
335 <p><a name='save-png-stream'>[Function]</a><br>
336 <b>save-png-stream</b> <i>stream</i> => |
338 <blockquote>
339 Writes the contents of the canvas as a PNG to <i>stream</i>, which
340 must accept <tt>(unsigned-byte&nbsp;8)</tt> data.
341 </blockquote>
344 <a name='sect-graphics-state'><h4>Graphics State</h4></a>
346 <p>The graphics state stores several parameters used for graphic
347 operations.
349 <p><a name='with-graphics-state'>[Macro]</a><br>
350 <b>with-graphics-state</b> <tt>&amp;body</tt> <i>body</i>
352 <blockquote>
353 Evaluates the forms of <i>body</i> with a copy of the current graphics
354 state. Any modifications to the state are undone at the end of the
355 form.
356 </blockquote>
359 <p><a name='set-rgba-fill'>[Functions]</a><br>
360 <b>set-rgba-fill</b> <i>r</i> <i>g</i> <i>b</i> <i>alpha</i> => |<br>
361 <b>set-rgb-fill</b> <i>r</i> <i>g</i> <i>b</i> => |
363 <blockquote>
364 Sets the fill color. <i>r</i>, <i>g</i>, <i>b</i>, and <i>alpha</i>
365 should be in the range of 0.0 to 1.0.
367 <p><tt>set-rgb-fill</tt> is the same as <tt>set-rgba-fill</tt> with an
368 implicit alpha value of 1.0.
370 <p>The fill color is used
371 for <a
372 href='#clear-canvas'><tt>CLEAR-CANVAS</tt></a>, <a
373 href='#fill-path'><tt>FILL-PATH</tt></a>, <a
374 href='#even-odd-fill'><tt>EVEN-ODD-FILL</tt></a>, <a
375 href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>, <a
376 href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>,
377 and <a href='#draw-string'><tt>DRAW-STRING</tt></a>.
379 </blockquote>
381 <p><a name='set-gradient-fill'>[Function]</a><br>
382 <b>set-gradient-fill</b>
383 <i>x0</i> <i>y0</i> <i>r0</i> <i>g0</i> <i>b0</i> <i>a0</i>
384 <i>x1</i> <i>y1</i> <i>r1</i> <i>g1</i> <i>b1</i> <i>a1</i>
385 <tt>&amp;key</tt> (<i>extend-start</i> <tt>t</tt>)
386 (<i>extend-end</i> <tt>t</tt>)
387 (<i>domain-function</i> <tt>'linear-domain</tt>)
389 <blockquote>
390 Set the fill color source to an axial gradient. The start point
391 is <i>x0,y0</i> and the start color is <i>r0,g0,b0,a0</i>. The end
392 point is <i>x1, y1</i> and the end color is <i>r1,g1,b1,a1</i>.
394 <p>Two domain functions are available:
396 <ul>
398 <li> <tt>LINEAR-DOMAIN</tt>, the default, makes a transition from the
399 start color to the end color along the axis between the start and end
400 points
402 <li> <tt>BILINEAR-DOMAIN</tt> makes a transition from the start color
403 to the end color from the start point to the midpoint, then back to
404 the start color from the midpoint to the end point
405 </ul>
407 <pre><img style='float: right' class='transparent'
408 src='linear-gradient.png'>(defun gradient-example (file)
409 (with-canvas (:width 200 :height 50)
410 (set-gradient-fill 25 0
411 1 0 0 1
412 175 0
413 1 0 0 0)
414 (rectangle 0 0 200 50)
415 (fill-path)
416 (save-png file)))
417 </pre>
419 <pre><img style='float: right' class='transparent'
420 src='bilinear-gradient.png'>(defun gradient-bilinear-example (file)
421 (with-canvas (:width 200 :height 50)
422 (set-gradient-fill 25 0
423 1 0 0 1
424 175 0
425 1 0 0 0
426 :domain-function 'bilinear-domain)
427 (rectangle 0 0 200 50)
428 (fill-path)
429 (save-png file)))
430 </pre>
434 </blockquote>
436 <p><a name='set-rgba-stroke'>[Functions]</a><br>
437 <b>set-rgba-stroke</b> <i>r</i> <i>g</i> <i>b</i> <i>alpha</i> => |<br>
438 <b>set-rgb-stroke</b> <i>r</i> <i>g</i> <i>b</i> => |
440 <blockquote>
441 Sets the stroke color. <i>r</i>, <i>g</i>, <i>b</i>, and <i>alpha</i>
442 should be in the range of 0.0 to 1.0.
444 <p><tt>set-rgb-stroke</tt> is the same as <tt>set-rgba-stroke</tt>
445 with an implicit alpha value of 1.0.
447 <p>The stroke color is used for <a href='#stroke'><tt>STROKE</tt></a>,
448 <a href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>,
449 and <a href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>.
450 </blockquote>
453 <p><a name='set-line-cap'>[Function]</a><br>
454 <b>set-line-cap</b> <i>style</i> => |
456 <blockquote>
457 Sets the line cap style to <i>style</i>, which must be one
458 of <tt>:BUTT</tt>, <tt>:SQUARE</tt>, or <tt>:ROUND</tt>. The initial
459 value is <tt>:BUTT</tt>.
461 <p><table cellspacing=5 id="line-cap">
462 <tr>
463 <td align=center><img src="cap-style-butt.png"></td>
464 <td align=center><img src="cap-style-square.png"></td>
465 <td align=center><img src="cap-style-round.png"></td>
466 </tr>
467 <tr>
468 <td align=center><tt>:BUTT</tt></td>
469 <td align=center><tt>:SQUARE</tt></td>
470 <td align=center><tt>:ROUND</tt></td>
471 </tr>
472 </table>
474 </blockquote>
477 <p><a name='set-line-join'>[Function]</a><br>
478 <b>set-line-join</b> <i>style</i> => |
480 <blockquote>
481 Sets the line join style to <i>style</i>, which must be one
482 of <tt>:MITER</tt>, <tt>:BEVEL</tt>, or <tt>:ROUND</tt>. The initial
483 value is <tt>:MITER</tt>.
485 <p><table cellspacing=5 id="line-join">
486 <tr>
487 <td align=center><img src="join-style-miter.png"></td>
488 <td align=center><img src="join-style-bevel.png"></td>
489 <td align=center><img src="join-style-round.png"></td>
490 </tr>
491 <tr>
492 <td align=center><tt>:MITER</tt></td>
493 <td align=center><tt>:BEVEL</tt></td>
494 <td align=center><tt>:ROUND</tt></td>
495 </tr>
496 </table>
498 </blockquote>
501 <p><a name='set-line-width'>[Function]</a><br>
502 <b>set-line-width</b> <i>width</i> => |
504 <blockquote>
505 Sets the line width for strokes to <i>width</i>.
506 </blockquote>
510 <p><a name='set-dash-pattern'>[Function]</a><br>
511 <b>set-dash-pattern</b> <i>dash-vector</i> <i>phase</i> => |
513 <blockquote>
514 Sets the dash pattern according to <i>dash-vector</i> and <i>phase</i>.
516 <p><i>dash-vector</i> should be a vector of numbers denoting on and
517 off patterns for a stroke. An empty <i>dash-vector</i> is the same as
518 having no dash pattern at all.
520 <p><i>phase</i> is how far along the dash pattern to proceed before
521 applying the pattern to the current stroke.
524 <table>
525 <tr>
526 <th>Appearance</th>
527 <th>Dash Vector and Phase</th>
528 </tr>
529 <tr>
530 <td align=center><img src="dash-pattern-none.png"></td>
531 <td align=left><tt>#() 0</tt></td>
532 </tr>
533 <tr>
534 <td align=center><img src="dash-pattern-a.png"></td>
535 <td align=left><tt>#(30 30) 0</tt></td>
536 </tr>
537 <tr>
538 <td align=center><img src="dash-pattern-b.png"></td>
539 <td align=left><tt>#(30 30) 15</tt></td>
540 </tr>
541 <tr>
542 <td align=center><img src="dash-pattern-c.png"></td>
543 <td align=left><tt>#(10 20 10 40) 0</tt></td>
544 </tr>
545 <tr>
546 <td align=center><img src="dash-pattern-d.png"></td>
547 <td align=left><tt>#(10 20 10 40) 13</tt></td>
548 </tr>
549 <tr>
550 <td align=center><img src="dash-pattern-e.png"></td>
551 <td align=left><tt>#(30 30) 0</tt>, <tt>:ROUND</tt> line caps</td>
552 </tr>
553 </table>
554 </blockquote>
557 <p><a name='translate'>[Function]</a><br>
558 <b>translate</b> <i>x</i> <i>y</i> => |
560 <blockquote>
561 Offsets the coordinate system by <i>x</i> units horizontally
562 and <i>y</i> units vertically.
563 </blockquote>
566 <p><a name='rotate'>[Function]</a><br>
567 <b>rotate</b> <i>radians</i> => |
569 <blockquote>
570 Rotates the coordinate system by <i>radians</i>.
571 </blockquote>
574 <p><a name='scale'>[Function]</a><br>
575 <b>scale</b> <i>sx</i> <i>sy</i> => |
577 <blockquote>
578 Scales the coordinate system by <i>sx</i> horizontally
579 and <i>sy</i> vertically.
580 </blockquote>
583 <p><a name='skew'>[Function]</a><br>
584 <b>skew</b> <i>ax</i> <i>ay</i> => |
586 <blockquote>
587 Skews the X axis of the coordinate system by <i>ax</i> radians and the
588 Y axis by <i>ay</i> radians.
589 </blockquote>
592 <p><a name='clip-path'>[Function]</a><br>
593 <b>clip-path</b> => |
595 <blockquote>
596 Defines a clipping path based on the current path. It is not applied
597 immediately, but is created after after the painting is done in the
598 next call to one
599 of <a
600 href='#fill-path'><tt>FILL-PATH</tt></a>, <a
601 href='#even-odd-fill'><tt>EVEN-ODD-FILL</tt></a>, <a
602 href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>, <a
603 href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>,
604 or <a href='#end-path-no-op'><tt>END-PATH-NO-OP</tt></a>.
606 <p>The clipping path initially covers the entire canvas; no clipping
607 is done. Subsequent calls to <tt>CLIP-PATH</tt> set the clipping path
608 to the intersection of the established clipping path and the new
609 clipping path, and all drawing will be done within the outline of the
610 clipping path.
612 <p>The outline of the clipping path is defined with the nonzero
613 winding rule, as with <a href='#fill-path'><tt>FILL-PATH</tt></a>.
615 <p>There is no way to enlarge the clipping path. However, the clipping
616 path is part of the graphics state, so changes may be localized by
617 using <a href='#with-graphics-state'><tt>WITH-GRAPHICS-STATE</tt></a>.
620 <p><table>
621 <tr>
622 <td><img src="clip-unclipped.png"></td>
623 <td>A filled red rectangle, not clipped</td>
624 </tr>
625 <tr>
626 <td><img src="clip-to-circle.png"></td>
627 <td>The same rectangle drawn with a circle clipping path in effect</td>
628 </tr>
629 <tr>
630 <td><img src="clip-to-rectangle.png"></td>
631 <td>Clipped to a rounded rectangle clipping path</td>
632 </tr>
633 <tr>
634 <td><img src="clip-to-both.png"></td>
635 <td>Clipped to the intersection of the circle and rounded rectangle clipping paths</td>
636 </tr>
637 </table>
641 </blockquote>
644 <p><a name='even-odd-clip-path'>[Function]</a><br>
645 <b>even-odd-clip-path</b> => |
647 <blockquote>
648 Like <a href='#clip-path'><tt>CLIP-PATH</tt></a>, but uses the
649 even/odd fill rule to determine the outline of the clipping path.
650 </blockquote>
653 <a name='sect-paths'><h4>Paths</h4></a>
655 <p>Paths are used to create lines for stroking or outlines for
656 filling. Paths consist of straight lines and curves. Paths consist of
657 one or more subpaths.
659 <p><a name='move-to'>[Function]</a><br>
660 <b>move-to</b> <i>x</i> <i>y</i> => |
662 <blockquote>
663 Starts a new subpath at (<i>x</i>,<i>y</i>). <tt>move-to</tt> must be the
664 first step of constructing a subpath.
665 </blockquote>
668 <p><a name='line-to'>[Function]</a><br>
669 <b>line-to</b> <i>x</i> <i>y</i> => |
671 <blockquote>
672 Appends a straight line ending at (<i>x</i>,<i>y</i>) to the
673 current subpath.
674 </blockquote>
677 <p><a name='curve-to'>[Function]</a><br>
678 <b>curve-to</b>
679 <i>cx1</i> <i>cy1</i>
680 <i>cx2</i> <i>cy2</i>
681 <i>x</i> <i>y</i> => |
683 <blockquote>
684 Appends a
685 cubic <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier
686 curve</a> ending at (<i>x</i>,<i>y</i>) and with control
687 points (<i>cx1</i>,<i>cy1</i>) and (<i>cx2</i>,<i>cy2</i>) to the current
688 subpath.
689 </blockquote>
692 <p><a name='quadratic-to'>[Function]</a><br>
693 <b>quadratic-to</b>
694 <i>cx</i> <i>cy</i>
695 <i>x</i> <i>y</i> => |
697 <blockquote>
698 Appends a quadratic B&eacute;zier curve ending at (<i>x</i>,<i>y</i>)
699 and with the control point (<i>cx</i>,<i>cy</i>) to the current
700 subpath.
701 </blockquote>
704 <p><a name='arc'>[Function]</a><br>
705 <b>arc</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
706 => |
708 <blockquote>
709 Appends an arc of a circle to the current path. The center of the arc is
710 at (<i>x</i>,<i>y</i>). The arc begins at point at a
711 distance <i>radius</i> from the center and with an angle <i>angle1</i>
712 radians from the positive x axis, and ends at the point
713 with <i>angle2</i> radians. If <i>angle2</i> is less
714 than <i>angle1</i>, it is increased by increasing multiples of 2&pi;
715 until it is greater than or equal to <i>angle1</i>.
717 <p><table cellpadding=5>
718 <tr><td align=center><img src="arc.png"></td></tr>
719 <tr><td><span style='color: #0f0'><i>radius</i></span>,
720 <span style='color: #f00'><i>angle1</i></span>,
721 <span style='color: #00f'><i>angle2</i></span></td></tr>
722 </table>
724 <p>If there is a current point, a straight line is added from the
725 current point to the start point of the arc. Otherwise, a new path
726 is started.
728 <pre><img class='transparent' style='float: right' src='pie-wedge.png'
729 >(defun pie-wedge (file)
730 (with-canvas (:width 80 :height 60)
731 (let ((x 0) (y 0)
732 (radius 70)
733 (angle1 (* (/ pi 180) 15))
734 (angle2 (* (/ pi 180) 45)))
735 (translate 5 5)
736 (set-rgb-fill 1 1 1)
737 (move-to 0 0)
738 (arc x y radius angle1 angle2)
739 (fill-and-stroke)
740 (save-png file))))
741 </pre>
743 </blockquote>
746 <p><a name='arcn'>[Function]</a><br>
747 <b>arcn</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
748 => |
750 <blockquote>
751 Like <a href='#arc'><tt>ARC</tt></a>, but draws the arc clockwise
752 instead of counterclockwise. If <i>angle2</i> is greater
753 than <i>angle1</i>, it is decreased by increasing multiples of 2&pi;
754 until it is less than or equal to <i>angle1</i>.
756 <pre><img class='transparent' style='float: right' src='wiper.png'
757 >(defun wiper (file)
758 (with-canvas (:width 70 :height 70)
759 (let ((x 0) (y 0)
760 (r1 40) (r2 60)
761 (angle1 0)
762 (angle2 (* (/ pi 180) 90)))
763 (translate 5 5)
764 (set-rgba-fill 1 1 1 0.75)
765 (arc x y r1 angle1 angle2)
766 (arcn x y r2 angle2 angle1)
767 (fill-and-stroke)
768 (save-png file))))
769 </pre>
771 </blockquote>
773 <p><a name='ellipse-arc'>[Function]</a><br>
774 <b>ellipse-arc</b> <i>cx</i> <i>cy</i> <i>radius-x</i> <i>radius-y</i>
775 <i>rotation-angle</i> <i>angle1</i> <i>angle2</i> => |
777 <blockquote>
778 Like <a href='#arc'><tt>ARC</TT></a>, but draws an arc from an
779 ellipse. The arc is drawn counterclockwise.
780 </blockquote>
783 <p><a name='ellipse-arcn'>[Function]</a><br>
784 <b>ellipse-arcn</b> <i>cx</i> <i>cy</i> <i>radius-x</i> <i>radius-y</i>
785 <i>rotation-angle</i> <i>angle1</i> <i>angle2</i> => |
787 <blockquote>
788 Like <a href='#ellipse-arcn'><tt>ELLIPSE-ARCN</TT></a>, but draws the
789 arc clockwise.
790 </blockquote>
793 <p><a name='close-subpath'>[Function]</a><br>
794 <b>close-subpath</b> => |
796 <blockquote>
797 Closes the current subpath. If the current point is not the same as the
798 starting point for the subpath, appends a straight line from the
799 current point to the starting point of the current subpath.
801 <p>Subpaths with start and end points that coincidentally overlap are
802 not the same as closed subpaths. The distinction is important when
803 stroking:
805 <p><table cellpadding=5>
806 <tr>
807 <td align=center><img src="open-subpath.png"></td>
808 <td align=center><img src="closed-subpath.png"></td>
809 </tr>
810 <tr>
811 <td align=center>Open subpath</td>
812 <td align=center>Closed subpath</td>
813 </tr>
814 </table>
816 <p>If the subpath is not closed, the start and points of the subpath
817 will be drawn with the current line cap style. If the path is
818 closed, the start and endpoints will be treated as joined and drawn
819 with the line join style.
820 </blockquote>
823 <p><a name='stroke-to-paths'>[Function]</a><br>
824 <b>stroke-to-paths</b> => |
826 <blockquote>
827 Sets the current active paths to the paths that would result from
828 outlining a <a href='#stroke'><tt>STROKE</tt></a> operation.
829 </blockquote>
832 <p><a name='rectangle'>[Function]</a><br>
833 <b>rectangle</b> <i>x</i> <i>y</i> <i>width</i> <i>height</i> => |
835 <blockquote>
836 Creates a rectangular subpath with the given <i>width</i>
837 and <i>height</i> that has its lower-left corner at
838 (<i>x</i>,<i>y</i>). It is effectively the same as:
840 <pre>
841 (move-to x y)
842 (line-to (+ x width) y)
843 (line-to (+ x width) (+ y height))
844 (line-to x (+ y height))
845 (close-subpath)
846 </pre>
847 </blockquote>
849 <p><a name='rounded-rectangle'>[Function]</a><br>
850 <b>rounded-rectangle</b> <i>x</i> <i>y</i>
851 <i>width</i> <i>height</i> <i>rx</i> <i>ry</i> => |
853 <blockquote>
854 Like <a href='#rectangle'><tt>RECTANGLE</tt></a>, but rounds the
855 corners of the rectangle paths by the x radius <i>rx</i> and the y
856 radius <i>ry</i>.
857 </blockquote>
859 <p><a name='centered-ellipse-path'>[Function]</a><br>
860 <b>centered-ellipse-path</b>
861 <i>x</i> <i>y</i>
862 <i>rx</i> <i>ry</i>
864 <blockquote>
865 Adds a closed subpath that outlines an ellipse centered at
866 (<i>x</i>,<i>y</i>) with an X radius of <i>rx</i> and a Y radius
867 of <i>ry</i>.
868 </blockquote>
870 <p><a name='centered-circle-path'>[Function]</a><br>
871 <b>centered-circle-path</b> <i>x</i> <i>y</i> <i>radius</i> => |
873 <blockquote>
874 Adds a closed subpath that outlines a circle centered at
875 (<i>x</i>,<i>y</i>) with a radius of <i>radius</i>. It is effectively
876 the same as:
878 <pre>
879 (centered-ellipse-path x y radius radius)
880 </pre>
881 </blockquote>
885 <a name='sect-painting'><h4>Painting</h4></a>
887 <p>After a path is defined, filling, stroking, or both will use the
888 path to apply color to the canvas. After a path has been filled or
889 stroked, it is no longer active; it effectively disappears.
892 <p><a name='fill-path'>[Function]</a><br>
893 <b>fill-path</b> => |
895 <blockquote>
896 Fills the current path with the fill color or gradient. If the path
897 has not been explicitly closed
898 with <a href='#close-subpath'><tt>CLOSE-SUBPATH</tt></a>, it is
899 implicitly closed before filling. The non-zero winding rule is used
900 to determine what areas are considered inside the path.
901 </blockquote>
904 <p><a name='even-odd-fill'>[Function]</a><br>
905 <b>even-odd-fill</b> => |
907 <blockquote>
908 The same as <a href='#fill-path'><tt>FILL-PATH</tt></a>, but uses the
909 even/odd rule to determine what areas are considered inside the path.
910 </blockquote>
913 <p><a name='stroke'>[Function]</a><br>
914 <b>stroke</b> => |
916 <blockquote>
917 Strokes the current path. The line width, stroke color, line join
918 style, line cap style, and dash pattern and phase determine how the
919 stroked path will appear on the canvas.
920 </blockquote>
923 <p><a name='fill-and-stroke'>[Function]</a><br>
924 <b>fill-and-stroke</b> => |
926 <blockquote>
927 Fills the current path, then strokes it.
928 </blockquote>
931 <p><a name='even-odd-fill-and-stroke'>[Function]</a><br>
932 <b>even-odd-fill-and-stroke</b> => |
934 <blockquote>
935 Fills the current path using the even/odd rule, then strokes it.
936 </blockquote>
939 <p><a name='end-path-no-op'>[Function]</a><br>
940 <b>end-path-no-op</b> => |
942 <blockquote>
943 Ends the current path without painting anything. If a clipping path
944 has been specified with <a href='#clip-path'><tt>CLIP-PATH</tt></a>
945 or <a href='#even-odd-clip-path'><tt>EVEN-ODD-CLIP-PATH</tt></a>, it
946 will be created by <tt>end-path-no-op</tt>.
947 </blockquote>
951 <a name='sect-text'><h4>Text</h4></a>
953 <p>Vecto can draw text to a canvas. It loads glyph shapes from
954 TrueType font files
955 with <a href="http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF</a>.
957 <p><a name='get-font'>[Function]</a><br>
958 <b>get-font</b> <i>font-file</i> => <i>font-loader</i>
960 <blockquote>
961 Creates and returns a ZPB-TTF font loader object
962 from <i>font-file</i>. Any font loader created this way will
963 automatically be closed at the end of its
964 enclosing <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form.
965 </blockquote>
968 <p><a name='set-font'>[Function]</a><br>
969 <b>set-font</b> <i>font-loader</i> <i>size</i> => |
971 <blockquote>
972 Sets the active font to the font associated
973 with <i>font-loader</i>, scaled to <i>size</i> units per line.
975 <p>The first argument can be any ZPB-TTF font loader; it need not be
976 created via <a href='#get-font'><tt>GET-FONT</tt></a>. However, only
977 font loaders created via <tt>GET-FONT</tt> will be automatically
978 closed at the end of <a href='#with-canvas'><tt>WITH-CANVAS</tt></a>.
979 </blockquote>
982 <p><a name='set-character-spacing'>[Function]</a><br>
983 <b>set-character-spacing</b> <i>spacing</i> => |
985 <blockquote>
986 Sets the scale of the spacing used between characters when drawing
987 text with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
988 functions.
990 <p>Normally, the character spacing for drawing text is taken directly
991 from a font's advance-width and kerning
992 metrics. <tt>SET-CHARACTER-SPACING</tt> can be used to adjust this
993 spacing; for example, a character spacing of 2.0d0 would double the
994 normal space between characters, and 0.5d0 would halve it.
995 </blockquote>
997 <p><a name='*default-character-spacing*'>[Special variable]</a><br>
998 <b>*default-character-spacing*</b>
1000 <blockquote>
1001 The default scale for character spacing when drawing text
1002 with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
1003 functions. Initial value is 1.0d0.
1005 <p>Changes to this variable affect the
1006 next <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form. To affect
1007 the spacing within the current <tt>WITH-CANVAS</tt> form,
1008 use <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>.
1009 </blockquote>
1012 <p><a name='draw-string'>[Function]</a><br>
1013 <b>draw-string</b> <i>x</i> <i>y</i> <i>string</i> => |
1015 <blockquote>
1016 Draws <i>string</i> on the canvas with the active font. The glyph
1017 origin of the first character in the string is positioned at <i>x</i>
1018 and the baseline of the string is positioned at <i>y</i>. The text is
1019 filled with the current <a href='#set-rgba-fill'>fill color</a>.
1021 <p>The string may be a specialized vector of characters (a true CL
1022 string) or a vector containing characters, Unicode code-points, or both. For
1023 example, <tt>#(#\L #\a #\m #\b #\d #\a #\= #x3BB)</tt> is a valid
1024 argument for <tt>DRAW-STRING</tt>.
1026 <p>The horizontal space between characters is determined by the
1027 advance-width and kerning metrics of the font, then multiplied by
1028 the current character spacing. At the default character spacing of
1029 1.0d0, the spacing is not adjusted at
1030 all. <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>
1031 can be used to increase or decrease the character spacing.
1032 </blockquote>
1035 <p><a name='string-paths'>[Function]</a><br>
1036 <b>string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1038 <blockquote>
1039 Like <a href='#draw-string'><tt>DRAW-STRING</tt></a>, but instead of
1040 drawing the text, adds the subpaths that make up the string glyphs to
1041 the graphics state. This can be used to stroke, fill, or clip based on
1042 the outlines of a string.
1043 </blockquote>
1046 <p><a name='draw-centered-string'>[Function]</a><br>
1047 <b>draw-centered-string</b> <i>x</i> <i>y</i> <i>string</i> => |
1049 <blockquote>
1050 Draws <i>string</i> on the canvas with the active font. The horizontal
1051 center of the string is positioned at <i>x</i> and the baseline of the
1052 string is positioned at <i>y</i>.
1053 </blockquote>
1056 <p><a name='centered-string-paths'>[Function]</a><br>
1057 <b>centered-string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1059 <blockquote>
1060 Like <a href='#draw-centered-string'><tt>DRAW-CENTERED-STRING</tt></a>,
1061 but adds subpaths instead of painting. See
1062 also <a href='#string-paths'><tt>STRING-PATHS</tt></a>.
1063 </blockquote>
1066 <p><a name='string-bounding-box'>[Function]</a><br>
1067 <b>string-bounding-box</b> <i>string</i> <i>size</i> <i>loader</i>
1068 => <i>#(xmin ymin xmax ymax)</i>
1070 <blockquote>
1071 Calculates the bounding box of <i>string</i> for <i>font-loader</i>
1072 at <i>size</i>.
1073 </blockquote>
1076 <a name='sect-miscellaneous'><h3>Miscellaneous</h3></a>
1078 <p><a name='const-kappa'>[Constant]</a><br>
1079 <b>+kappa+</b> => 0.5522847498307936d0.
1081 <blockquote>
1082 This constant is useful to draw portions of a circle.
1083 </blockquote>
1086 <a name='sect-references'><h2>References</h2></a>
1088 <ul>
1089 <li> Adobe Systems Inc., <a href="http://www.adobe.com/devnet/pdf/pdf_reference.html">PDF Reference, Sixth Edition, Version 1.7</a>
1090 <li> Lawrence Kesteloot, <a href="http://www.teamten.com/lawrence/graphics/premultiplication/">Alpha Premultiplication</a>
1091 <li> Dr. Thomas Sederberg, <a href="http://www.tsplines.com/resources/class_notes/Bezier_curves.pdf">B&eacute;zier curves</a>
1092 <li> Alvy Ray Smith, <a href="http://alvyray.com/Memos/MemosMicrosoft.htm#ImageCompositing">Image Compositing Fundamentals</a>
1093 <li> G. Adam Stanislav, <a href="http://www.whizkidtech.redprince.net/bezier/circle/">Drawing a circle with B&eacute;zier curves</a>
1094 <li> Alexander Thomas, <a href="http://www.dr-lex.be/random/matrix_inv.html">The Inverse and Determinants of 2x2 and 3x3 Matrices</a>
1095 <li> Wikipedia, <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier curve</a>
1097 </ul>
1100 <a name='sect-acknowledgements'><h2>Acknowledgements</h2></a>
1102 <p>Many thanks to <a href="http://www.elbeno.com/">Ben Deane</a> for
1103 permission to adapt code from his curve library for drawing arcs.
1105 <p>Ryan Davis helped fix my adaptation of the arc drawing.
1107 <a name='sect-feedback'><h2>Feedback</h2></a>
1109 <p>If you have any questions, comments, bug reports, or other feedback
1110 regarding Vecto, please email <a href="mailto:xach@xach.com">Zach
1111 Beane</a>.
1114 </div>
1115 </body>