Blob


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