Updated version to 1.6.
[vecto.git] / doc / index.html
blobd3bac092f5c66db3ed1875efba339e408a51ff23
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='#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>
408 <p>Two coordinate functions are available:
410 <ul>
412 <li> <tt>CARTESIAN-COORDINATES</tt>, the default, creates a linear
413 gradient.
415 <li> <tt>POLAR-COORDINATES</tt> creates a radial gradient with the
416 start point denoting the start of the circle and the end point
417 denoting the ending circle.
418 </ul>
421 <pre><img style='float: right' class='transparent'
422 src='linear-gradient.png'>(defun gradient-example (file)
423 (with-canvas (:width 200 :height 50)
424 (set-gradient-fill 25 0
425 1 0 0 1
426 175 0
427 1 0 0 0)
428 (rectangle 0 0 200 50)
429 (fill-path)
430 (save-png file)))
431 </pre>
433 <pre><img style='float: right' class='transparent'
434 src='bilinear-gradient.png'>(defun gradient-bilinear-example (file)
435 (with-canvas (:width 200 :height 50)
436 (set-gradient-fill 25 0
437 1 0 0 1
438 175 0
439 1 0 0 0
440 :domain-function 'bilinear-domain)
441 (rectangle 0 0 200 50)
442 (fill-path)
443 (save-png file)))
444 </pre>
448 </blockquote>
450 <p><a name='set-rgba-stroke'>[Functions]</a><br>
451 <b>set-rgba-stroke</b> <i>r</i> <i>g</i> <i>b</i> <i>alpha</i> => |<br>
452 <b>set-rgb-stroke</b> <i>r</i> <i>g</i> <i>b</i> => |
454 <blockquote>
455 Sets the stroke color. <i>r</i>, <i>g</i>, <i>b</i>, and <i>alpha</i>
456 should be in the range of 0.0 to 1.0.
458 <p><tt>set-rgb-stroke</tt> is the same as <tt>set-rgba-stroke</tt>
459 with an implicit alpha value of 1.0.
461 <p>The stroke color is used for <a href='#stroke'><tt>STROKE</tt></a>,
462 <a href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>,
463 and <a href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>.
464 </blockquote>
467 <p><a name='set-line-cap'>[Function]</a><br>
468 <b>set-line-cap</b> <i>style</i> => |
470 <blockquote>
471 Sets the line cap style to <i>style</i>, which must be one
472 of <tt>:BUTT</tt>, <tt>:SQUARE</tt>, or <tt>:ROUND</tt>. The initial
473 value is <tt>:BUTT</tt>.
475 <p><table cellspacing=5 id="line-cap">
476 <tr>
477 <td align=center><img src="cap-style-butt.png"></td>
478 <td align=center><img src="cap-style-square.png"></td>
479 <td align=center><img src="cap-style-round.png"></td>
480 </tr>
481 <tr>
482 <td align=center><tt>:BUTT</tt></td>
483 <td align=center><tt>:SQUARE</tt></td>
484 <td align=center><tt>:ROUND</tt></td>
485 </tr>
486 </table>
488 </blockquote>
491 <p><a name='set-line-join'>[Function]</a><br>
492 <b>set-line-join</b> <i>style</i> => |
494 <blockquote>
495 Sets the line join style to <i>style</i>, which must be one
496 of <tt>:MITER</tt>, <tt>:BEVEL</tt>, or <tt>:ROUND</tt>. The initial
497 value is <tt>:MITER</tt>.
499 <p><table cellspacing=5 id="line-join">
500 <tr>
501 <td align=center><img src="join-style-miter.png"></td>
502 <td align=center><img src="join-style-bevel.png"></td>
503 <td align=center><img src="join-style-round.png"></td>
504 </tr>
505 <tr>
506 <td align=center><tt>:MITER</tt></td>
507 <td align=center><tt>:BEVEL</tt></td>
508 <td align=center><tt>:ROUND</tt></td>
509 </tr>
510 </table>
512 </blockquote>
515 <p><a name='set-line-width'>[Function]</a><br>
516 <b>set-line-width</b> <i>width</i> => |
518 <blockquote>
519 Sets the line width for strokes to <i>width</i>.
520 </blockquote>
524 <p><a name='set-dash-pattern'>[Function]</a><br>
525 <b>set-dash-pattern</b> <i>dash-vector</i> <i>phase</i> => |
527 <blockquote>
528 Sets the dash pattern according to <i>dash-vector</i> and <i>phase</i>.
530 <p><i>dash-vector</i> should be a vector of numbers denoting on and
531 off patterns for a stroke. An empty <i>dash-vector</i> is the same as
532 having no dash pattern at all.
534 <p><i>phase</i> is how far along the dash pattern to proceed before
535 applying the pattern to the current stroke.
538 <table>
539 <tr>
540 <th>Appearance</th>
541 <th>Dash Vector and Phase</th>
542 </tr>
543 <tr>
544 <td align=center><img src="dash-pattern-none.png"></td>
545 <td align=left><tt>#() 0</tt></td>
546 </tr>
547 <tr>
548 <td align=center><img src="dash-pattern-a.png"></td>
549 <td align=left><tt>#(30 30) 0</tt></td>
550 </tr>
551 <tr>
552 <td align=center><img src="dash-pattern-b.png"></td>
553 <td align=left><tt>#(30 30) 15</tt></td>
554 </tr>
555 <tr>
556 <td align=center><img src="dash-pattern-c.png"></td>
557 <td align=left><tt>#(10 20 10 40) 0</tt></td>
558 </tr>
559 <tr>
560 <td align=center><img src="dash-pattern-d.png"></td>
561 <td align=left><tt>#(10 20 10 40) 13</tt></td>
562 </tr>
563 <tr>
564 <td align=center><img src="dash-pattern-e.png"></td>
565 <td align=left><tt>#(30 30) 0</tt>, <tt>:ROUND</tt> line caps</td>
566 </tr>
567 </table>
568 </blockquote>
571 <p><a name='translate'>[Function]</a><br>
572 <b>translate</b> <i>x</i> <i>y</i> => |
574 <blockquote>
575 Offsets the coordinate system by <i>x</i> units horizontally
576 and <i>y</i> units vertically.
577 </blockquote>
580 <p><a name='rotate'>[Function]</a><br>
581 <b>rotate</b> <i>radians</i> => |
583 <blockquote>
584 Rotates the coordinate system by <i>radians</i>.
585 </blockquote>
588 <p><a name='scale'>[Function]</a><br>
589 <b>scale</b> <i>sx</i> <i>sy</i> => |
591 <blockquote>
592 Scales the coordinate system by <i>sx</i> horizontally
593 and <i>sy</i> vertically.
594 </blockquote>
597 <p><a name='skew'>[Function]</a><br>
598 <b>skew</b> <i>ax</i> <i>ay</i> => |
600 <blockquote>
601 Skews the X axis of the coordinate system by <i>ax</i> radians and the
602 Y axis by <i>ay</i> radians.
603 </blockquote>
606 <p><a name='clip-path'>[Function]</a><br>
607 <b>clip-path</b> => |
609 <blockquote>
610 Defines a clipping path based on the current path. It is not applied
611 immediately, but is created after after the painting is done in the
612 next call to one
613 of <a
614 href='#fill-path'><tt>FILL-PATH</tt></a>, <a
615 href='#even-odd-fill'><tt>EVEN-ODD-FILL</tt></a>, <a
616 href='#fill-and-stroke'><tt>FILL-AND-STROKE</tt></a>, <a
617 href='#even-odd-fill-and-stroke'><tt>EVEN-ODD-FILL-AND-STROKE</tt></a>,
618 or <a href='#end-path-no-op'><tt>END-PATH-NO-OP</tt></a>.
620 <p>The clipping path initially covers the entire canvas; no clipping
621 is done. Subsequent calls to <tt>CLIP-PATH</tt> set the clipping path
622 to the intersection of the established clipping path and the new
623 clipping path, and all drawing will be done within the outline of the
624 clipping path.
626 <p>The outline of the clipping path is defined with the nonzero
627 winding rule, as with <a href='#fill-path'><tt>FILL-PATH</tt></a>.
629 <p>There is no way to enlarge the clipping path. However, the clipping
630 path is part of the graphics state, so changes may be localized by
631 using <a href='#with-graphics-state'><tt>WITH-GRAPHICS-STATE</tt></a>.
634 <p><table>
635 <tr>
636 <td><img src="clip-unclipped.png"></td>
637 <td>A filled red rectangle, not clipped</td>
638 </tr>
639 <tr>
640 <td><img src="clip-to-circle.png"></td>
641 <td>The same rectangle drawn with a circle clipping path in effect</td>
642 </tr>
643 <tr>
644 <td><img src="clip-to-rectangle.png"></td>
645 <td>Clipped to a rounded rectangle clipping path</td>
646 </tr>
647 <tr>
648 <td><img src="clip-to-both.png"></td>
649 <td>Clipped to the intersection of the circle and rounded rectangle clipping paths</td>
650 </tr>
651 </table>
655 </blockquote>
658 <p><a name='even-odd-clip-path'>[Function]</a><br>
659 <b>even-odd-clip-path</b> => |
661 <blockquote>
662 Like <a href='#clip-path'><tt>CLIP-PATH</tt></a>, but uses the
663 even/odd fill rule to determine the outline of the clipping path.
664 </blockquote>
667 <a name='sect-paths'><h4>Paths</h4></a>
669 <p>Paths are used to create lines for stroking or outlines for
670 filling. Paths consist of straight lines and curves. Paths consist of
671 one or more subpaths.
673 <p><a name='move-to'>[Function]</a><br>
674 <b>move-to</b> <i>x</i> <i>y</i> => |
676 <blockquote>
677 Starts a new subpath at (<i>x</i>,<i>y</i>). <tt>move-to</tt> must be the
678 first step of constructing a subpath.
679 </blockquote>
682 <p><a name='line-to'>[Function]</a><br>
683 <b>line-to</b> <i>x</i> <i>y</i> => |
685 <blockquote>
686 Appends a straight line ending at (<i>x</i>,<i>y</i>) to the
687 current subpath.
688 </blockquote>
691 <p><a name='curve-to'>[Function]</a><br>
692 <b>curve-to</b>
693 <i>cx1</i> <i>cy1</i>
694 <i>cx2</i> <i>cy2</i>
695 <i>x</i> <i>y</i> => |
697 <blockquote>
698 Appends a
699 cubic <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier
700 curve</a> ending at (<i>x</i>,<i>y</i>) and with control
701 points (<i>cx1</i>,<i>cy1</i>) and (<i>cx2</i>,<i>cy2</i>) to the current
702 subpath.
703 </blockquote>
706 <p><a name='quadratic-to'>[Function]</a><br>
707 <b>quadratic-to</b>
708 <i>cx</i> <i>cy</i>
709 <i>x</i> <i>y</i> => |
711 <blockquote>
712 Appends a quadratic B&eacute;zier curve ending at (<i>x</i>,<i>y</i>)
713 and with the control point (<i>cx</i>,<i>cy</i>) to the current
714 subpath.
715 </blockquote>
718 <p><a name='arc'>[Function]</a><br>
719 <b>arc</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
720 => |
722 <blockquote>
723 Appends an arc of a circle to the current path. The center of the arc is
724 at (<i>x</i>,<i>y</i>). The arc begins at point at a
725 distance <i>radius</i> from the center and with an angle <i>angle1</i>
726 radians from the positive x axis, and ends at the point
727 with <i>angle2</i> radians. If <i>angle2</i> is less
728 than <i>angle1</i>, it is increased by increasing multiples of 2&pi;
729 until it is greater than or equal to <i>angle1</i>.
731 <p><table cellpadding=5>
732 <tr><td align=center><img src="arc.png"></td></tr>
733 <tr><td><span style='color: #0f0'><i>radius</i></span>,
734 <span style='color: #f00'><i>angle1</i></span>,
735 <span style='color: #00f'><i>angle2</i></span></td></tr>
736 </table>
738 <p>If there is a current point, a straight line is added from the
739 current point to the start point of the arc. Otherwise, a new path
740 is started.
742 <pre><img class='transparent' style='float: right' src='pie-wedge.png'
743 >(defun pie-wedge (file)
744 (with-canvas (:width 80 :height 60)
745 (let ((x 0) (y 0)
746 (radius 70)
747 (angle1 (* (/ pi 180) 15))
748 (angle2 (* (/ pi 180) 45)))
749 (translate 5 5)
750 (set-rgb-fill 1 1 1)
751 (move-to 0 0)
752 (arc x y radius angle1 angle2)
753 (fill-and-stroke)
754 (save-png file))))
755 </pre>
757 </blockquote>
760 <p><a name='arcn'>[Function]</a><br>
761 <b>arcn</b> <i>x</i> <i>y</i> <i>radius</i> <i>angle1</i> <i>angle2</i>
762 => |
764 <blockquote>
765 Like <a href='#arc'><tt>ARC</tt></a>, but draws the arc clockwise
766 instead of counterclockwise. If <i>angle2</i> is greater
767 than <i>angle1</i>, it is decreased by increasing multiples of 2&pi;
768 until it is less than or equal to <i>angle1</i>.
770 <pre><img class='transparent' style='float: right' src='wiper.png'
771 >(defun wiper (file)
772 (with-canvas (:width 70 :height 70)
773 (let ((x 0) (y 0)
774 (r1 40) (r2 60)
775 (angle1 0)
776 (angle2 (* (/ pi 180) 90)))
777 (translate 5 5)
778 (set-rgba-fill 1 1 1 0.75)
779 (arc x y r1 angle1 angle2)
780 (arcn x y r2 angle2 angle1)
781 (fill-and-stroke)
782 (save-png file))))
783 </pre>
785 </blockquote>
787 <p><a name='ellipse-arc'>[Function]</a><br>
788 <b>ellipse-arc</b> <i>cx</i> <i>cy</i> <i>radius-x</i> <i>radius-y</i>
789 <i>rotation-angle</i> <i>angle1</i> <i>angle2</i> => |
791 <blockquote>
792 Like <a href='#arc'><tt>ARC</TT></a>, but draws an arc from an
793 ellipse. The arc is drawn counterclockwise.
794 </blockquote>
797 <p><a name='ellipse-arcn'>[Function]</a><br>
798 <b>ellipse-arcn</b> <i>cx</i> <i>cy</i> <i>radius-x</i> <i>radius-y</i>
799 <i>rotation-angle</i> <i>angle1</i> <i>angle2</i> => |
801 <blockquote>
802 Like <a href='#ellipse-arcn'><tt>ELLIPSE-ARCN</TT></a>, but draws the
803 arc clockwise.
804 </blockquote>
807 <p><a name='close-subpath'>[Function]</a><br>
808 <b>close-subpath</b> => |
810 <blockquote>
811 Closes the current subpath. If the current point is not the same as the
812 starting point for the subpath, appends a straight line from the
813 current point to the starting point of the current subpath.
815 <p>Subpaths with start and end points that coincidentally overlap are
816 not the same as closed subpaths. The distinction is important when
817 stroking:
819 <p><table cellpadding=5>
820 <tr>
821 <td align=center><img src="open-subpath.png"></td>
822 <td align=center><img src="closed-subpath.png"></td>
823 </tr>
824 <tr>
825 <td align=center>Open subpath</td>
826 <td align=center>Closed subpath</td>
827 </tr>
828 </table>
830 <p>If the subpath is not closed, the start and points of the subpath
831 will be drawn with the current line cap style. If the path is
832 closed, the start and endpoints will be treated as joined and drawn
833 with the line join style.
834 </blockquote>
837 <p><a name='stroke-to-paths'>[Function]</a><br>
838 <b>stroke-to-paths</b> => |
840 <blockquote>
841 Sets the current active paths to the paths that would result from
842 outlining a <a href='#stroke'><tt>STROKE</tt></a> operation.
843 </blockquote>
846 <p><a name='rectangle'>[Function]</a><br>
847 <b>rectangle</b> <i>x</i> <i>y</i> <i>width</i> <i>height</i> => |
849 <blockquote>
850 Creates a rectangular subpath with the given <i>width</i>
851 and <i>height</i> that has its lower-left corner at
852 (<i>x</i>,<i>y</i>). It is effectively the same as:
854 <pre>
855 (move-to x y)
856 (line-to (+ x width) y)
857 (line-to (+ x width) (+ y height))
858 (line-to x (+ y height))
859 (close-subpath)
860 </pre>
861 </blockquote>
863 <p><a name='rounded-rectangle'>[Function]</a><br>
864 <b>rounded-rectangle</b> <i>x</i> <i>y</i>
865 <i>width</i> <i>height</i> <i>rx</i> <i>ry</i> => |
867 <blockquote>
868 Like <a href='#rectangle'><tt>RECTANGLE</tt></a>, but rounds the
869 corners of the rectangle paths by the x radius <i>rx</i> and the y
870 radius <i>ry</i>.
871 </blockquote>
873 <p><a name='centered-ellipse-path'>[Function]</a><br>
874 <b>centered-ellipse-path</b>
875 <i>x</i> <i>y</i>
876 <i>rx</i> <i>ry</i>
878 <blockquote>
879 Adds a closed subpath that outlines an ellipse centered at
880 (<i>x</i>,<i>y</i>) with an X radius of <i>rx</i> and a Y radius
881 of <i>ry</i>.
882 </blockquote>
884 <p><a name='centered-circle-path'>[Function]</a><br>
885 <b>centered-circle-path</b> <i>x</i> <i>y</i> <i>radius</i> => |
887 <blockquote>
888 Adds a closed subpath that outlines a circle centered at
889 (<i>x</i>,<i>y</i>) with a radius of <i>radius</i>. It is effectively
890 the same as:
892 <pre>
893 (centered-ellipse-path x y radius radius)
894 </pre>
895 </blockquote>
899 <a name='sect-painting'><h4>Painting</h4></a>
901 <p>After a path is defined, filling, stroking, or both will use the
902 path to apply color to the canvas. After a path has been filled or
903 stroked, it is no longer active; it effectively disappears.
906 <p><a name='fill-path'>[Function]</a><br>
907 <b>fill-path</b> => |
909 <blockquote>
910 Fills the current path with the fill color or gradient. If the path
911 has not been explicitly closed
912 with <a href='#close-subpath'><tt>CLOSE-SUBPATH</tt></a>, it is
913 implicitly closed before filling. The non-zero winding rule is used
914 to determine what areas are considered inside the path.
915 </blockquote>
918 <p><a name='even-odd-fill'>[Function]</a><br>
919 <b>even-odd-fill</b> => |
921 <blockquote>
922 The same as <a href='#fill-path'><tt>FILL-PATH</tt></a>, but uses the
923 even/odd rule to determine what areas are considered inside the path.
924 </blockquote>
927 <p><a name='stroke'>[Function]</a><br>
928 <b>stroke</b> => |
930 <blockquote>
931 Strokes the current path. The line width, stroke color, line join
932 style, line cap style, and dash pattern and phase determine how the
933 stroked path will appear on the canvas.
934 </blockquote>
937 <p><a name='fill-and-stroke'>[Function]</a><br>
938 <b>fill-and-stroke</b> => |
940 <blockquote>
941 Fills the current path, then strokes it.
942 </blockquote>
945 <p><a name='even-odd-fill-and-stroke'>[Function]</a><br>
946 <b>even-odd-fill-and-stroke</b> => |
948 <blockquote>
949 Fills the current path using the even/odd rule, then strokes it.
950 </blockquote>
953 <p><a name='end-path-no-op'>[Function]</a><br>
954 <b>end-path-no-op</b> => |
956 <blockquote>
957 Ends the current path without painting anything. If a clipping path
958 has been specified with <a href='#clip-path'><tt>CLIP-PATH</tt></a>
959 or <a href='#even-odd-clip-path'><tt>EVEN-ODD-CLIP-PATH</tt></a>, it
960 will be created by <tt>end-path-no-op</tt>.
961 </blockquote>
965 <a name='sect-text'><h4>Text</h4></a>
967 <p>Vecto can draw text to a canvas. It loads glyph shapes from
968 TrueType font files
969 with <a href="http://www.xach.com/lisp/zpb-ttf/">ZPB-TTF</a>.
971 <p><a name='get-font'>[Function]</a><br>
972 <b>get-font</b> <i>font-file</i> => <i>font-loader</i>
974 <blockquote>
975 Creates and returns a ZPB-TTF font loader object
976 from <i>font-file</i>. Any font loader created this way will
977 automatically be closed at the end of its
978 enclosing <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form.
979 </blockquote>
982 <p><a name='set-font'>[Function]</a><br>
983 <b>set-font</b> <i>font-loader</i> <i>size</i> => |
985 <blockquote>
986 Sets the active font to the font associated
987 with <i>font-loader</i>, scaled to <i>size</i> units per line.
989 <p>The first argument can be any ZPB-TTF font loader; it need not be
990 created via <a href='#get-font'><tt>GET-FONT</tt></a>. However, only
991 font loaders created via <tt>GET-FONT</tt> will be automatically
992 closed at the end of <a href='#with-canvas'><tt>WITH-CANVAS</tt></a>.
993 </blockquote>
996 <p><a name='set-character-spacing'>[Function]</a><br>
997 <b>set-character-spacing</b> <i>spacing</i> => |
999 <blockquote>
1000 Sets the scale of the spacing used between characters when drawing
1001 text with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
1002 functions.
1004 <p>Normally, the character spacing for drawing text is taken directly
1005 from a font's advance-width and kerning
1006 metrics. <tt>SET-CHARACTER-SPACING</tt> can be used to adjust this
1007 spacing; for example, a character spacing of 2.0d0 would double the
1008 normal space between characters, and 0.5d0 would halve it.
1009 </blockquote>
1011 <p><a name='*default-character-spacing*'>[Special variable]</a><br>
1012 <b>*default-character-spacing*</b>
1014 <blockquote>
1015 The default scale for character spacing when drawing text
1016 with <a href='#draw-string'><tt>DRAW-STRING</tt></a> and related
1017 functions. Initial value is 1.0d0.
1019 <p>Changes to this variable affect the
1020 next <a href='#with-canvas'><tt>WITH-CANVAS</tt></a> form. To affect
1021 the spacing within the current <tt>WITH-CANVAS</tt> form,
1022 use <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>.
1023 </blockquote>
1026 <p><a name='draw-string'>[Function]</a><br>
1027 <b>draw-string</b> <i>x</i> <i>y</i> <i>string</i> => |
1029 <blockquote>
1030 Draws <i>string</i> on the canvas with the active font. The glyph
1031 origin of the first character in the string is positioned at <i>x</i>
1032 and the baseline of the string is positioned at <i>y</i>. The text is
1033 filled with the current <a href='#set-rgba-fill'>fill color</a>.
1035 <p>The string may be a specialized vector of characters (a true CL
1036 string) or a vector containing characters, Unicode code-points, or both. For
1037 example, <tt>#(#\L #\a #\m #\b #\d #\a #\= #x3BB)</tt> is a valid
1038 argument for <tt>DRAW-STRING</tt>.
1040 <p>The horizontal space between characters is determined by the
1041 advance-width and kerning metrics of the font, then multiplied by
1042 the current character spacing. At the default character spacing of
1043 1.0d0, the spacing is not adjusted at
1044 all. <a href='#set-character-spacing'><tt>SET-CHARACTER-SPACING</tt></a>
1045 can be used to increase or decrease the character spacing.
1046 </blockquote>
1049 <p><a name='string-paths'>[Function]</a><br>
1050 <b>string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1052 <blockquote>
1053 Like <a href='#draw-string'><tt>DRAW-STRING</tt></a>, but instead of
1054 drawing the text, adds the subpaths that make up the string glyphs to
1055 the graphics state. This can be used to stroke, fill, or clip based on
1056 the outlines of a string.
1057 </blockquote>
1060 <p><a name='draw-centered-string'>[Function]</a><br>
1061 <b>draw-centered-string</b> <i>x</i> <i>y</i> <i>string</i> => |
1063 <blockquote>
1064 Draws <i>string</i> on the canvas with the active font. The horizontal
1065 center of the string is positioned at <i>x</i> and the baseline of the
1066 string is positioned at <i>y</i>.
1067 </blockquote>
1070 <p><a name='centered-string-paths'>[Function]</a><br>
1071 <b>centered-string-paths</b> <i>x</i> <i>y</i> <i>string</i> => |
1073 <blockquote>
1074 Like <a href='#draw-centered-string'><tt>DRAW-CENTERED-STRING</tt></a>,
1075 but adds subpaths instead of painting. See
1076 also <a href='#string-paths'><tt>STRING-PATHS</tt></a>.
1077 </blockquote>
1080 <p><a name='string-bounding-box'>[Function]</a><br>
1081 <b>string-bounding-box</b> <i>string</i> <i>size</i> <i>loader</i>
1082 => <i>#(xmin ymin xmax ymax)</i>
1084 <blockquote>
1085 Calculates the bounding box of <i>string</i> for <i>font-loader</i>
1086 at <i>size</i>.
1087 </blockquote>
1090 <a name='sect-miscellaneous'><h3>Miscellaneous</h3></a>
1092 <p><a name='const-kappa'>[Constant]</a><br>
1093 <b>+kappa+</b> => 0.5522847498307936d0.
1095 <blockquote>
1096 This constant is useful to draw portions of a circle.
1097 </blockquote>
1100 <a name='sect-references'><h2>References</h2></a>
1102 <ul>
1103 <li> Adobe Systems Inc., <a href="http://www.adobe.com/devnet/pdf/pdf_reference.html">PDF Reference, Sixth Edition, Version 1.7</a>
1104 <li> Lawrence Kesteloot, <a href="http://www.teamten.com/lawrence/graphics/premultiplication/">Alpha Premultiplication</a>
1105 <li> Dr. Thomas Sederberg, <a href="http://www.tsplines.com/resources/class_notes/Bezier_curves.pdf">B&eacute;zier curves</a>
1106 <li> Alvy Ray Smith, <a href="http://alvyray.com/Memos/MemosMicrosoft.htm#ImageCompositing">Image Compositing Fundamentals</a>
1107 <li> G. Adam Stanislav, <a href="http://www.whizkidtech.redprince.net/bezier/circle/">Drawing a circle with B&eacute;zier curves</a>
1108 <li> Alexander Thomas, <a href="http://www.dr-lex.be/random/matrix_inv.html">The Inverse and Determinants of 2x2 and 3x3 Matrices</a>
1109 <li> Wikipedia, <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">B&eacute;zier curve</a>
1111 </ul>
1114 <a name='sect-acknowledgements'><h2>Acknowledgements</h2></a>
1116 <p>Many thanks to <a href="http://www.elbeno.com/">Ben Deane</a> for
1117 permission to adapt code from his curve library for drawing arcs.
1119 <p>Ryan Davis helped fix my adaptation of the arc drawing.
1121 <a name='sect-feedback'><h2>Feedback</h2></a>
1123 <p>If you have any questions, comments, bug reports, or other feedback
1124 regarding Vecto, please email <a href="mailto:xach@xach.com">Zach
1125 Beane</a>.
1128 </div>
1129 </body>