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