Blob


1 .TH DRAW 3
2 .SH NAME
3 Image, draw, drawop, gendraw, gendrawop, drawreplxy, drawrepl,
4 replclipr, line, lineop, poly, polyop, fillpoly, fillpolyop, bezier, bezierop,
5 bezspline, bezsplineop, bezsplinepts, fillbezier, fillbezierop,
6 fillbezspline, fillbezsplineop, ellipse, ellipseop,
7 fillellipse, fillellipseop, arc, arcop, fillarc, fillarcop,
8 icossin, icossin2, border, string, stringop, stringn, stringnop,
9 runestring, runestringop, runestringn, runestringnop, stringbg,
10 stringbgop, stringnbg, stringnbgop, runestringbg, runestringbgop,
11 runestringnbg, runestringnbgop, _string, ARROW, drawsetdebug \- graphics functions
12 .de PB
13 .PP
14 .ft L
15 .nf
16 ..
17 .SH SYNOPSIS
18 .de PB
19 .PP
20 .ft L
21 .nf
22 ..
23 .PB
24 #include <u.h>
25 #include <libc.h>
26 #include <draw.h>
27 .PB
28 typedef
29 struct Image
30 {
31 Display *display; /* display holding data */
32 int id; /* id of system-held Image */
33 Rectangle r; /* rectangle in data area, local coords */
34 Rectangle clipr; /* clipping region */
35 ulong chan; /* pixel channel format descriptor */
36 int depth; /* number of bits per pixel */
37 int repl; /* flag: data replicates to tile clipr */
38 Screen *screen; /* 0 if not a window */
39 Image *next; /* next in list of windows */
40 } Image;
41 .PB
42 typedef enum
43 {
44 /* Porter-Duff compositing operators */
45 Clear = 0,
46 .sp 0.1
47 SinD = 8,
48 DinS = 4,
49 SoutD = 2,
50 DoutS = 1,
51 .sp 0.1
52 S = SinD|SoutD,
53 SoverD = SinD|SoutD|DoutS,
54 SatopD = SinD|DoutS,
55 SxorD = SoutD|DoutS,
56 .sp 0.1
57 D = DinS|DoutS,
58 DoverS = DinS|DoutS|SoutD,
59 DatopS = DinS|SoutD,
60 DxorS = DoutS|SoutD, /* == SxorD */
61 .sp 0.1
62 Ncomp = 12,
63 } Drawop;
64 .PB
65 .PD 0
66 .ta +\w'\fL 'u +\w'\fL 'u +6n +4n
67 void draw(Image *dst, Rectangle r, Image *src,
68 Image *mask, Point p)
69 .PB
70 void drawop(Image *dst, Rectangle r, Image *src,
71 Image *mask, Point p, Drawop op)
72 .PB
73 void gendraw(Image *dst, Rectangle r, Image *src, Point sp,
74 Image *mask, Point mp)
75 .PB
76 void gendrawop(Image *dst, Rectangle r, Image *src, Point sp,
77 Image *mask, Point mp, Drawop op)
78 .PB
79 int drawreplxy(int min, int max, int x)
80 .PB
81 Point drawrepl(Rectangle r, Point p)
82 .PB
83 void replclipr(Image *i, int repl, Rectangle clipr)
84 .PB
85 void line(Image *dst, Point p0, Point p1, int end0, int end1,
86 int radius, Image *src, Point sp)
87 .PB
88 void lineop(Image *dst, Point p0, Point p1, int end0, int end1,
89 int radius, Image *src, Point sp, Drawop op)
90 .PB
91 void poly(Image *dst, Point *p, int np, int end0, int end1,
92 int radius, Image *src, Point sp)
93 .PB
94 void polyop(Image *dst, Point *p, int np, int end0, int end1,
95 int radius, Image *src, Point sp, Drawop op)
96 .PB
97 void fillpoly(Image *dst, Point *p, int np, int wind,
98 Image *src, Point sp)
99 .PB
100 void fillpolyop(Image *dst, Point *p, int np, int wind,
101 Image *src, Point sp, Drawop op)
102 .PB
103 int bezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
104 int end0, int end1, int radius, Image *src, Point sp)
105 .PB
106 int bezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
107 int end0, int end1, int radius, Image *src, Point sp,
108 Drawop op)
109 .PB
110 int bezspline(Image *dst, Point *pt, int npt, int end0, int end1,
111 int radius, Image *src, Point sp)
112 .PB
113 int bezsplineop(Image *dst, Point *pt, int npt, int end0, int end1,
114 int radius, Image *src, Point sp, Drawop op)
115 .PB
116 int bezsplinepts(Point *pt, int npt, Point **pp)
117 .PB
118 int fillbezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
119 int w, Image *src, Point sp)
120 .PB
121 int fillbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
122 int w, Image *src, Point sp, Drawop op)
123 .PB
124 int fillbezspline(Image *dst, Point *pt, int npt, int w,
125 Image *src, Point sp)
126 .PB
127 int fillbezsplineop(Image *dst, Point *pt, int npt, int w,
128 Image *src, Point sp, Drawop op)
129 .PB
130 void ellipse(Image *dst, Point c, int a, int b, int thick,
131 Image *src, Point sp)
132 .PB
133 void ellipseop(Image *dst, Point c, int a, int b, int thick,
134 Image *src, Point sp, Drawop op)
135 .PB
136 void fillellipse(Image *dst, Point c, int a, int b,
137 Image *src, Point sp)
138 .PB
139 void fillellipseop(Image *dst, Point c, int a, int b,
140 Image *src, Point sp, Drawop op)
141 .PB
142 void arc(Image *dst, Point c, int a, int b, int thick,
143 Image *src, Point sp, int alpha, int phi)
144 .PB
145 void arcop(Image *dst, Point c, int a, int b, int thick,
146 Image *src, Point sp, int alpha, int phi, Drawop op)
147 .PB
148 void fillarc(Image *dst, Point c, int a, int b, Image *src,
149 Point sp, int alpha, int phi)
150 .PB
151 void fillarcop(Image *dst, Point c, int a, int b, Image *src,
152 Point sp, int alpha, int phi, Drawop op)
153 .PB
154 int icossin(int deg, int *cosp, int *sinp)
155 .PB
156 int icossin2(int x, int y, int *cosp, int *sinp)
157 .PB
158 void border(Image *dst, Rectangle r, int i, Image *color, Point sp)
159 .br
160 .PB
161 Point string(Image *dst, Point p, Image *src, Point sp,
162 Font *f, char *s)
163 .PB
164 Point stringop(Image *dst, Point p, Image *src, Point sp,
165 Font *f, char *s, Drawop op)
166 .PB
167 Point stringn(Image *dst, Point p, Image *src, Point sp,
168 Font *f, char *s, int len)
169 .PB
170 Point stringnop(Image *dst, Point p, Image *src, Point sp,
171 Font *f, char *s, int len, Drawop op)
172 .PB
173 Point runestring(Image *dst, Point p, Image *src, Point sp,
174 Font *f, Rune *r)
175 .PB
176 Point runestringop(Image *dst, Point p, Image *src, Point sp,
177 Font *f, Rune *r, Drawop op)
178 .PB
179 Point runestringn(Image *dst, Point p, Image *src, Point sp,
180 Font *f, Rune *r, int len)
181 .PB
182 Point runestringnop(Image *dst, Point p, Image *src, Point sp,
183 Font *f, Rune *r, int len, Drawop op)
184 .PB
185 Point stringbg(Image *dst, Point p, Image *src, Point sp,
186 Font *f, char *s, Image *bg, Point bgp)
187 .PB
188 Point stringbgop(Image *dst, Point p, Image *src, Point sp,
189 Font *f, char *s, Image *bg, Point bgp, Drawop op)
190 .PB
191 Point stringnbg(Image *dst, Point p, Image *src, Point sp,
192 Font *f, char *s, int len, Image *bg, Point bgp)
193 .PB
194 Point stringnbgop(Image *dst, Point p, Image *src, Point sp,
195 Font *f, char *s, int len, Image *bg, Point bgp, Drawop op)
196 .PB
197 Point runestringbg(Image *dst, Point p, Image *src, Point sp,
198 Font *f, Rune *r, Image *bg, Point bgp)
199 .PB
200 Point runestringbgop(Image *dst, Point p, Image *src, Point sp,
201 Font *f, Rune *r, Image *bg, Point bgp, Drawop op)
202 .PB
203 Point runestringnbg(Image *dst, Point p, Image *src, Point sp,
204 Font *f, Rune *r, int len, Image *bg, Point bgp)
205 .PB
206 Point runestringnbgop(Image *dst, Point p, Image *src, Point sp,
207 Font *f, Rune *r, int len, Image *bg, Point bgp, Drawop op)
208 .PB
209 Point _string(Image *dst, Point p, Image *src,
210 Point sp, Font *f, char *s, Rune *r, int len,
211 Rectangle clipr, Image *bg, Point bgp, Drawop op)
212 .PB
213 void drawsetdebug(int on)
214 .PD
215 .PB
216 enum
218 /* line ends */
219 Endsquare = 0,
220 Enddisc = 1,
221 Endarrow = 2,
222 Endmask = 0x1F
223 };
224 .PB
225 #define ARROW(a, b, c) (Endarrow|((a)<<5)|((b)<<14)|((c)<<23))
226 .SH DESCRIPTION
227 The
228 .B Image
229 type defines rectangular pictures and the methods to draw upon them;
230 it is also the building block for higher level objects such as
231 windows and fonts.
232 In particular, a window is represented as an
233 .BR Image ;
234 no special operators are needed to draw on a window.
235 .PP
236 .TP 10
237 .B r
238 The coordinates of the rectangle in the plane for which the
239 .B Image
240 has defined pixel values.
241 It should not be modified after the image is created.
242 .TP
243 .B clipr
244 The clipping rectangle: operations that read or write
245 the image will not access pixels outside
246 .BR clipr .
247 Frequently,
248 .B clipr
249 is the same as
250 .BR r ,
251 but it may differ; see in particular the discussion of
252 .BR repl .
253 The clipping region may be modified dynamically using
254 .I replclipr
255 .RI ( q.v. ).
256 .TP
257 .B chan
258 The pixel channel format descriptor, as described in
259 .IR image (7).
260 The value should not be modified after the image is created.
261 .TP
262 .B depth
263 The
264 number of bits per pixel in the picture;
265 it is identically
266 .B chantodepth(chan)
267 (see
268 .IR graphics (3))
269 and is provided as a convenience.
270 The value should not be modified after the image is created.
271 .TP
272 .B repl
273 A boolean value specifying whether the image is tiled to cover
274 the plane when used as a source for a drawing operation.
275 If
276 .B repl
277 is zero, operations are restricted to the intersection of
278 .B r
279 and
280 .BR clipr .
281 If
282 .B repl
283 is set,
284 .B r
285 defines the tile to be replicated and
286 .B clipr
287 defines the portion of the plane covered by the tiling, in other words,
288 .B r
289 is replicated to cover
290 .BR clipr ;
291 in such cases
292 .B r
293 and
294 .B clipr
295 are independent.
296 .IP
297 For example, a replicated image with
298 .B r
299 set to ((0,\ 0),\ (1,\ 1)) and
300 .B clipr
301 set to ((0,\ 0),\ (100,\ 100)),
302 with the single pixel of
303 .B r
304 set to blue,
305 behaves identically to an image with
306 .B r
307 and
308 .B clipr
309 both set to ((0,\ 0),\ (100,\ 100)) and all pixels set to blue.
310 However,
311 the first image requires far less memory.
312 The replication flag may be modified dynamically using
313 .I replclipr
314 .RI ( q.v. ).
315 .PP
316 Most of the drawing functions come in two forms:
317 a basic form, and an extended form that takes an extra
318 .B Drawop
319 to specify a Porter-Duff compositing operator to use.
320 The basic forms assume the operator is
321 .BR SoverD ,
322 which suffices for the vast majority of applications.
323 The extended forms are named by adding an
324 .RB - op
325 suffix to the basic form.
326 Only the basic forms are listed below.
327 .TP
328 .BI draw( dst\fP,\fP\ r\fP,\fP\ src\fP,\fP\ mask\fP,\fP\ p )
329 .I Draw
330 is the standard drawing function.
331 Only those pixels within the intersection of
332 .IB dst ->r
333 and
334 .IB dst ->clipr
335 will be affected;
336 .I draw
337 ignores
338 .IB dst ->repl\fR.
339 The operation proceeds as follows
340 (this is a description of the behavior, not the implementation):
341 .RS
342 .IP 1.
343 If
344 .B repl
345 is set in
346 .I src
347 or
348 .IR mask ,
349 replicate their contents to fill
350 their clip rectangles.
351 .IP 2.
352 Translate
353 .I src
354 and
355 .I mask
356 so
357 .I p
358 is aligned with
359 .IB r .min\fR.
360 .IP 3.
361 Set
362 .I r
363 to the intersection of
364 .I r
365 and
366 .IB dst ->r\fR.
367 .IP 4.
368 Intersect
369 .I r
370 with
371 .IB src ->clipr\fR.
372 If
373 .IB src ->repl
374 is false, also intersect
375 .I r
376 with
377 .IB src ->r\fR.
378 .IP 5.
379 Intersect
380 .I r
381 with
382 .IB mask ->clipr\fR.
383 If
384 .IB mask ->repl
385 is false, also intersect
386 .I r
387 with
388 .IB mask ->r\fR.
389 .IP 6.
390 For each location in
391 .IR r ,
392 combine the
393 .I dst
394 pixel with the
395 .I src
396 pixel using the alpha value
397 corresponding to the
398 .I mask
399 pixel.
400 If the
401 .I mask
402 has an explicit alpha channel, the alpha value
403 corresponding to the
404 .I mask
405 pixel is simply that pixel's alpha channel.
406 Otherwise, the alpha value is the NTSC greyscale equivalent
407 of the color value, with white meaning opaque and black transparent.
408 In terms of the Porter-Duff compositing algebra,
409 .I draw
410 replaces the
411 .I dst
412 pixels with
413 .RI ( src
414 in
415 .IR mask )
416 over
417 .IR dst .
418 (In the extended form,
419 ``over'' is replaced by
420 .IR op ).
421 .RE
422 .IP
423 The various
424 pixel channel formats
425 involved need not be identical.
426 If the channels involved are smaller than 8-bits, they will
427 be promoted before the calculation by replicating the extant bits;
428 after the calculation, they will be truncated to their proper sizes.
429 .TP
430 \f5gendraw(\f2dst\fP, \f2r\fP, \f2src\fP, \f2p0\fP, \f2mask\fP, \f2p1\f5)\fP
431 Similar to
432 .I draw
433 except that
434 .I gendraw
435 aligns the source and mask differently:
436 .I src
437 is aligned so
438 .I p0
439 corresponds to
440 .IB r .min
441 and
442 .I mask
443 is aligned so
444 .I p1
445 corresponds to
446 .IB r .min .
447 For most purposes with simple masks and source images,
448 .B draw
449 is sufficient, but
450 .B gendraw
451 is the general operator and the one all other drawing primitives are built upon.
452 .TP
453 .BI drawreplxy( min , max , x\f5)
454 Clips
455 .I x
456 to be in the half-open interval [\fImin\fP, \fImax\fP) by adding
457 or subtracting a multiple of \fImax-min\fP.
458 .TP
459 .BI drawrepl( r , p )
460 Clips the point \fIp\fP to be within the rectangle \fIr\fP
461 by translating the point horizontally by an integer multiple of rectangle width
462 and vertically by the height.
463 .TP
464 .BI replclipr( i , repl , clipr\f5)
465 Because the image data is stored on the server, local modifications to the
466 .B Image
467 data structure itself will have no effect.
468 .I Repclipr
469 modifies the local
470 .B Image
471 data structure's
472 .B repl
473 and
474 .B clipr
475 fields, and notifies the server of their modification.
476 .TP
477 \f5line(\f2dst\fP, \f2p0\fP, \f2p1\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
478 Line
479 draws in
480 .I dst
481 a line of width
482 .RI 1+2* thick
483 pixels joining points
484 .I p0
485 and
486 .IR p1 .
487 The line is drawn using pixels from the
488 .I src
489 image aligned so
490 .I sp
491 in the source corresponds to
492 .I p0
493 in the destination.
494 The line touches both
495 .I p0
496 and
497 .IR p1 ,
498 and
499 .I end0
500 and
501 .I end1
502 specify how the ends of the line are drawn.
503 .B Endsquare
504 terminates the line perpendicularly to the direction of the line; a thick line with
505 .B Endsquare
506 on both ends will be a rectangle.
507 .B Enddisc
508 terminates the line by drawing a disc of diameter
509 .RI 1+2* thick
510 centered on the end point.
511 .B Endarrow
512 terminates the line with an arrowhead whose tip touches the endpoint.
513 .IP
514 The macro
515 .B ARROW
516 permits explicit control of the shape of the arrow.
517 If all three parameters are zero, it produces the default arrowhead,
518 otherwise,
519 .I a
520 sets the distance along line from end of the regular line to tip,
521 .I b
522 sets the distance along line from the barb to the tip,
523 and
524 .I c
525 sets the distance perpendicular to the line from edge of line to the tip of the barb,
526 all in pixels.
527 .IP
528 .I Line
529 and the other geometrical operators are equivalent to calls to
530 .I gendraw
531 using a mask produced by the geometric procedure.
532 .TP
533 \f5poly(\f2dst\fP, \f2p\fP, \f2np\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
534 .I Poly
535 draws a general polygon; it
536 is conceptually equivalent to a series of calls to
537 .I line
538 joining adjacent points in the
539 array of
540 .B Points
541 .IR p ,
542 which has
543 .I np
544 elements.
545 The ends of the polygon are specified as in
546 .IR line ;
547 interior lines are terminated with
548 .B Enddisc
549 to make smooth joins.
550 The source is aligned so
551 .I sp
552 corresponds to
553 .IB p [0]\f1.
554 .TP
555 \f5fillpoly(\f2dst\fP, \f2p\fP, \f2np\fP, \f2wind\fP, \f2src\fP, \f2sp\fP)
556 .I Fillpoly
557 is like
558 .I poly
559 but fills in the resulting polygon rather than outlining it.
560 The source is aligned so
561 .I sp
562 corresponds to
563 .IB p [0]\f1.
564 The winding rule parameter
565 .I wind
566 resolves ambiguities about what to fill if the polygon is self-intersecting.
567 If
568 .I wind
569 is
570 .BR ~0 ,
571 a pixel is inside the polygon if the polygon's winding number about the point
572 is non-zero.
573 If
574 .I wind
575 is
576 .BR 1 ,
577 a pixel is inside if the winding number is odd.
578 Complementary values (0 or ~1) cause outside pixels to be filled.
579 The meaning of other values is undefined.
580 The polygon is closed with a line if necessary.
581 .TP
582 \f5bezier(\f2dst\fP, \f2a\fP, \f2b\fP, \f2c\fP, \f2d\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
583 .I Bezier
584 draws the
585 cubic Bezier curve defined by
586 .B Points
587 .IR a ,
588 .IR b ,
589 .IR c ,
590 and
591 .IR d .
592 The end styles are determined by
593 .I end0
594 and
595 .IR end1 ;
596 the thickness of the curve is
597 .RI 1+2* thick .
598 The source is aligned so
599 .I sp
600 in
601 .I src
602 corresponds to
603 .I a
604 in
605 .IR dst .
606 .TP
607 \f5bezspline(\f2dst\fP, \f2p\fP, \f2end0\fP, \f2end1\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
608 .I Bezspline
609 takes the same arguments as
610 .I poly
611 but draws a quadratic B-spline (despite its name) rather than a polygon.
612 If the first and last points in
613 .I p
614 are equal, the spline has periodic end conditions.
615 .TP
616 \f5bezsplinepts(\f2pt\fP, \f2npt\fP, \f2pp\fP)
617 .I Bezsplinepts
618 returns in
619 .I pp
620 a list of points making up the open polygon that
621 .I bezspline
622 would draw.
623 The caller is responsible for freeing
624 .IR *pp .
625 .TP
626 \f5fillbezier(\f2dst\fP, \f2a\fP, \f2b\fP, \f2c\fP, \f2d\fP, \f2wind\fP, \f2src\fP, \f2sp\fP)
627 .I Fillbezier
628 is to
629 .I bezier
630 as
631 .I fillpoly
632 is to
633 .IR poly .
634 .TP
635 \f5fillbezspline(\f2dst\fP, \f2p\fP, \f2wind\fP, \f2src\fP, \f2sp\fP)
636 .I Fillbezspline
637 is like
638 .I fillpoly
639 but fills the quadratic B-spline rather than the polygon outlined by
640 .IR p .
641 The spline is closed with a line if necessary.
642 .TP
643 \f5ellipse(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2thick\fP, \f2src\fP, \f2sp\fP)
644 .I Ellipse
645 draws in
646 .I dst
647 an ellipse centered on
648 .I c
649 with horizontal and vertical semiaxes
650 .I a
651 and
652 .IR b .
653 The source is aligned so
654 .I sp
655 in
656 .I src
657 corresponds to
658 .I c
659 in
660 .IR dst .
661 The ellipse is drawn with thickness
662 .RI 1+2* thick .
663 .TP
664 \f5fillellipse(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2src\fP, \f2sp\fP)
665 .I Fillellipse
666 is like
667 .I ellipse
668 but fills the ellipse rather than outlining it.
669 .TP
670 \f5arc(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2thick\fP, \f2src\fP, \f2sp\fP, \f2alpha\fP, \f2phi\fP)
671 .I Arc
672 is like
673 .IR ellipse ,
674 but draws only that portion of the ellipse starting at angle
675 .I alpha
676 and extending through an angle of
677 .IR phi .
678 The angles are measured in degrees counterclockwise from the positive
679 .I x
680 axis.
681 .TP
682 \f5fillarc(\f2dst\fP, \f2c\fP, \f2a\fP, \f2b\fP, \f2src\fP, \f2sp\fP, \f2alpha\fP, \f2phi\fP)
683 .I Fillarc
684 is like
685 .IR arc ,
686 but fills the sector with the source color.
687 .TP
688 \f5icossin(\f2deg\fP, \f2cosp\fP, \f2sinp\fP)
689 .I Icossin
690 stores in
691 .BI * cosp
692 and
693 .BI * sinp
694 scaled integers representing the cosine and sine of the angle
695 .IR deg ,
696 measured in integer degrees.
697 The values are scaled so cos(0) is 1024.
698 .TP
699 \f5icossin2(\f2x\fP, \f2y\fP, \f2cosp\fP, \f2sinp\fP)
700 .I Icossin2
701 is analogous to
702 .IR icossin,
703 with the angle represented not in degrees but implicitly by the point
704 .RI ( x , y ).
705 It is to
706 .I icossin
707 what
708 .B atan2
709 is to
710 .B atan
711 (see
712 .IR sin (3)).
713 .TP
714 .BI border( dst\fP,\fP\ r\fP,\fP\ i\fP,\fP\ color\fP,\fP\ sp\fP)
715 .I Border
716 draws an outline of rectangle
717 .I r
718 in the specified
719 .IR color .
720 The outline has width
721 .IR i ;
722 if positive, the border goes inside the rectangle; negative, outside.
723 The source is aligned so
724 .I sp
725 corresponds to
726 .IB r .min .
727 .TP
728 .BI string( dst\fP,\fP\ p\fP,\fP\ src\fP,\fP\ sp\fP,\fP\ font\fP,\fP\ s )
729 .I String
730 draws in
731 .I dst
732 characters specified by the string
733 .I s
734 and
735 .IR font ;
736 it is equivalent to a series of calls to
737 .I gendraw
738 using source
739 .I src
740 and masks determined by the character shapes.
741 The text is positioned with the left of the first character at
742 .IB p .x
743 and the top of the line of text at
744 .IB p .y\f1.
745 The source is positioned so
746 .I sp
747 in
748 .I src
749 corresponds to
750 .I p
751 in
752 .IR dst .
753 .I String
754 returns a
755 .B Point
756 that is the position of the next character that would be drawn if the string were longer.
757 .IP
758 For characters with undefined
759 or zero-width images in the font, the character at font position 0 (NUL) is drawn.
760 .IP
761 The other string routines are variants of this basic form, and
762 have names that encode their variant behavior.
763 Routines whose names contain
764 .B rune
765 accept a string of Runes rather than
766 .SM UTF\c
767 -encoded bytes.
768 Routines ending in
769 .B n
770 accept an argument,
771 .IR n ,
772 that defines the number of characters to draw rather than accepting a NUL-terminated
773 string.
774 Routines containing
775 .B bg
776 draw the background behind the characters in the specified color
777 .RI ( bg )
778 and
779 alignment
780 .RI ( bgp );
781 normally the text is drawn leaving the background intact.
782 .IP
783 The routine
784 .I _string
785 captures all this behavior into a single operator. Whether it draws a
786 .SM UTF
787 string
788 or Rune string depends on whether
789 .I s
790 or
791 .I r
792 is null (the string length is always determined by
793 .IR len ).
794 If
795 .I bg
796 is non-null, it is used as a background color.
797 The
798 .I clipr
799 argument allows further management of clipping when drawing the string;
800 it is intersected with the usual clipping rectangles to further limit the extent of the text.
801 .TP
802 .BI drawsetdebug( on )
803 Turns on or off debugging output (usually
804 to a serial line) according to whether
805 .I on
806 is non-zero.
807 .SH SOURCE
808 .B \*9/src/libdraw
809 .SH SEE ALSO
810 .IR graphics (3),
811 .IR stringsize (3),
812 .IR color (7),
813 .IR utf (7),
814 .IR addpt (3)
815 .PP
816 T. Porter, T. Duff.
817 ``Compositing Digital Images'',
818 .I "Computer Graphics
819 (Proc. SIGGRAPH), 18:3, pp. 253-259, 1984.
820 .SH DIAGNOSTICS
821 These routines call the graphics error function on fatal errors.
822 .SH BUGS
823 Anti-aliased characters can be drawn by defining a font
824 with multiple bits per pixel, but there are
825 no anti-aliasing geometric primitives.