DRAW(2)                                                   DRAW(2)

     NAME
          Image, draw, drawop, gendraw, gendrawop, drawreplxy,
          drawrepl, replclipr, line, lineop, poly, polyop, fillpoly,
          fillpolyop, bezier, bezierop, bezspline, bezsplineop,
          bezsplinepts, fillbezier, fillbezierop, fillbezspline,
          fillbezsplineop, ellipse, ellipseop, fillellipse,
          fillellipseop, arc, arcop, fillarc, fillarcop, icossin,
          icossin2, border, string, stringop, stringn, stringnop,
          runestring, runestringop, runestringn, runestringnop,
          stringbg, stringbgop, stringnbg, stringnbgop, runestringbg,
          runestringbgop, runestringnbg, runestringnbgop, _string,
          ARROW, mousescrollsize, newwindow, drawsetdebug - graphics
          functions

     SYNOPSIS
          #include <u.h>
          #include <libc.h>
          #include <draw.h>

          typedef
          struct Image
          {
               Display   *display; /* display holding data */
               int       id;       /* id of system-held Image */
               Rectangle r;        /* rectangle in data area, local coords */
               Rectangle clipr;    /* clipping region */
               ulong     chan;     /* pixel channel format descriptor */
               int       depth;    /* number of bits per pixel */
               int       repl;     /* flag: data replicates to tile clipr */
               Screen    *screen;  /* 0 if not a window */
               Image     *next;    /* next in list of windows */
          } Image;

          typedef enum
          {
               /* Porter-Duff compositing operators */
               Clear     = 0,
               SinD = 8,
               DinS = 4,
               SoutD     = 2,
               DoutS     = 1,
               S         = SinD|SoutD,
               SoverD    = SinD|SoutD|DoutS,
               SatopD    = SinD|DoutS,
               SxorD     = SoutD|DoutS,
               D         = DinS|DoutS,
               DoverS    = DinS|DoutS|SoutD,
               DatopS    = DinS|SoutD,
               DxorS     = DoutS|SoutD, /* == SxorD */
               Ncomp = 12,

     Page 1                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

          } Drawop;

          void  draw(Image *dst, Rectangle r, Image *src,
                    Image *mask, Point p)
          void  drawop(Image *dst, Rectangle r, Image *src,
                    Image *mask, Point p, Drawop op)
          void  gendraw(Image *dst, Rectangle r, Image *src, Point sp,
                    Image *mask, Point mp)
          void  gendrawop(Image *dst, Rectangle r, Image *src, Point sp,
                    Image *mask, Point mp, Drawop op)
          int   drawreplxy(int min, int max, int x)
          Point drawrepl(Rectangle r, Point p)
          void  replclipr(Image *i, int repl, Rectangle clipr)
          void  line(Image *dst, Point p0, Point p1, int end0, int end1,
                    int radius, Image *src, Point sp)
          void  lineop(Image *dst, Point p0, Point p1, int end0, int end1,
                    int radius, Image *src, Point sp, Drawop op)
          void  poly(Image *dst, Point *p, int np, int end0, int end1,
                    int radius, Image *src, Point sp)
          void  polyop(Image *dst, Point *p, int np, int end0, int end1,
                    int radius, Image *src, Point sp, Drawop op)
          void  fillpoly(Image *dst, Point *p, int np, int wind,
                    Image *src, Point sp)
          void  fillpolyop(Image *dst, Point *p, int np, int wind,
                    Image *src, Point sp, Drawop op)
          int   bezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
                    int end0, int end1, int radius, Image *src, Point sp)
          int   bezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
                    int end0, int end1, int radius, Image *src, Point sp,
                    Drawop op)
          int   bezspline(Image *dst, Point *pt, int npt, int end0, int end1,
                    int radius, Image *src, Point sp)
          int   bezsplineop(Image *dst, Point *pt, int npt, int end0, int end1,
                    int radius, Image *src, Point sp, Drawop op)
          int   bezsplinepts(Point *pt, int npt, Point **pp)
          int   fillbezier(Image *dst, Point p0, Point p1, Point p2, Point p3,
                    int w, Image *src, Point sp)
          int   fillbezierop(Image *dst, Point p0, Point p1, Point p2, Point p3,
                    int w, Image *src, Point sp, Drawop op)
          int   fillbezspline(Image *dst, Point *pt, int npt, int w,
                    Image *src, Point sp)
          int   fillbezsplineop(Image *dst, Point *pt, int npt, int w,
                    Image *src, Point sp, Drawop op)
          void  ellipse(Image *dst, Point c, int a, int b, int thick,
                    Image *src, Point sp)
          void  ellipseop(Image *dst, Point c, int a, int b, int thick,
                    Image *src, Point sp, Drawop op)
          void  fillellipse(Image *dst, Point c, int a, int b,
                    Image *src, Point sp)
          void  fillellipseop(Image *dst, Point c, int a, int b,
                    Image *src, Point sp, Drawop op)
          void  arc(Image *dst, Point c, int a, int b, int thick,

     Page 2                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

                    Image *src, Point sp, int alpha, int phi)
          void  arcop(Image *dst, Point c, int a, int b, int thick,
                    Image *src, Point sp, int alpha, int phi, Drawop op)
          void  fillarc(Image *dst, Point c, int a, int b, Image *src,
                    Point sp, int alpha, int phi)
          void  fillarcop(Image *dst, Point c, int a, int b, Image *src,
                    Point sp, int alpha, int phi, Drawop op)
          int   icossin(int deg, int *cosp, int *sinp)
          int   icossin2(int x, int y, int *cosp, int *sinp)
          void  border(Image *dst, Rectangle r, int i, Image *color, Point sp)
          Point string(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s)
          Point stringop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s, Drawop op)
          Point stringn(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s, int len)
          Point stringnop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s, int len, Drawop op)
          Point runestring(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r)
          Point runestringop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r, Drawop op)
          Point runestringn(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r, int len)
          Point runestringnop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r, int len, Drawop op)
          Point stringbg(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s, Image *bg, Point bgp)
          Point stringbgop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s, Image *bg, Point bgp, Drawop op)
          Point stringnbg(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s, int len, Image *bg, Point bgp)
          Point stringnbgop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, char *s, int len, Image *bg, Point bgp, Drawop op)
          Point runestringbg(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r, Image *bg, Point bgp)
          Point runestringbgop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r, Image *bg, Point bgp, Drawop op)
          Point runestringnbg(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r, int len, Image *bg, Point bgp)
          Point runestringnbgop(Image *dst, Point p, Image *src, Point sp,
                    Font *f, Rune *r, int len, Image *bg, Point bgp, Drawop op)
          Point _string(Image *dst, Point p, Image *src,
                    Point sp, Font *f, char *s, Rune *r, int len,
                    Rectangle clipr, Image *bg, Point bgp, Drawop op)
          int   mousescrollsize(int maxlines)
          int   newwindow(char *wname)
          void  drawsetdebug(int on)

          enum
          {
                /* line ends */

     Page 3                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

                Endsquare = 0,
                Enddisc       = 1,
                Endarrow  = 2,
                Endmask       = 0x1F
          };

          #define ARROW(a, b, c) (Endarrow|((a)<<5)|((b)<<14)|((c)<<23))

     DESCRIPTION
          The Image type defines rectangular pictures and the methods
          to draw upon them; it is also the building block for higher
          level objects such as windows and fonts.  In particular, a
          window is represented as an Image; no special operators are
          needed to draw on a window.

          r         The coordinates of the rectangle in the plane for
                    which the Image has defined pixel values.  It
                    should not be modified after the image is created.

          clipr     The clipping rectangle: operations that read or
                    write the image will not access pixels outside
                    clipr.  Frequently, clipr is the same as r, but it
                    may differ; see in particular the discussion of
                    repl.  The clipping region may be modified dynami-
                    cally using replclipr (q.v.).

          chan      The pixel channel format descriptor, as described
                    in image(6). The value should not be modified
                    after the image is created.

          depth     The number of bits per pixel in the picture; it is
                    identically chantodepth(chan) (see graphics(2))
                    and is provided as a convenience.  The value
                    should not be modified after the image is created.

          repl      A boolean value specifying whether the image is
                    tiled to cover the plane when used as a source for
                    a drawing operation.  If repl is zero, operations
                    are restricted to the intersection of r and clipr.
                    If repl is set, r defines the tile to be repli-
                    cated and clipr defines the portion of the plane
                    covered by the tiling, in other words, r is repli-
                    cated to cover clipr; in such cases r and clipr
                    are independent.

                    For example, a replicated image with r set to
                    ((0, 0), (1, 1)) and clipr set to
                    ((0, 0), (100, 100)), with the single pixel of r
                    set to blue, behaves identically to an image with
                    r and clipr both set to ((0, 0), (100, 100)) and
                    all pixels set to blue.  However, the first image
                    requires far less memory.  The replication flag

     Page 4                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

                    may be modified dynamically using replclipr
                    (q.v.).

          Most of the drawing functions come in two forms: a basic
          form, and an extended form that takes an extra Drawop to
          specify a Porter-Duff compositing operator to use.  The
          basic forms assume the operator is SoverD, which suffices
          for the vast majority of applications.  The extended forms
          are named by adding an -op suffix to the basic form.  Only
          the basic forms are listed below.

          draw(dst, r, src, mask, p)
               Draw is the standard drawing function.  Only those pix-
               els within the intersection of dst->r and dst->clipr
               will be affected; draw ignores dst->repl.  The opera-
               tion proceeds as follows (this is a description of the
               behavior, not the implementation):

               1.   If repl is set in src or mask, replicate their
                    contents to fill their clip rectangles.

               2.   Translate src and mask so p is aligned with r.min.

               3.   Set r to the intersection of r and dst->r.

               4.   Intersect r with src->clipr.  If src->repl is
                    false, also intersect r with src->r.

               5.   Intersect r with mask->clipr.  If mask->repl is
                    false, also intersect r with mask->r.

               6.   For each location in r, combine the dst pixel with
                    the src pixel using the alpha value corresponding
                    to the mask pixel.  If the mask has an explicit
                    alpha channel, the alpha value corresponding to
                    the mask pixel is simply that pixel's alpha chan-
                    nel.  Otherwise, the alpha value is the NTSC
                    greyscale equivalent of the color value, with
                    white meaning opaque and black transparent.  In
                    terms of the Porter-Duff compositing algebra, draw
                    replaces the dst pixels with (src in mask) over
                    dst. (In the extended form, ``over'' is replaced
                    by op).

               The various pixel channel formats involved need not be
               identical.  If the channels involved are smaller than
               8-bits, they will be promoted before the calculation by
               replicating the extant bits; after the calculation,
               they will be truncated to their proper sizes.

          gendraw(dst, r, src, p0, mask, p1)
               Similar to draw except that gendraw aligns the source

     Page 5                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

               and mask differently: src is aligned so p0 corresponds
               to r.min and mask is aligned so p1 corresponds to
               r.min.  For most purposes with simple masks and source
               images, draw is sufficient, but gendraw is the general
               operator and the one all other drawing primitives are
               built upon.

          drawreplxy(min,max,x)
               Clips x to be in the half-open interval [min, max) by
               adding or subtracting a multiple of max-min.

          drawrepl(r,p)
               Clips the point p to be within the rectangle r by
               translating the point horizontally by an integer multi-
               ple of rectangle width and vertically by the height.

          replclipr(i,repl,clipr)
               Because the image data is stored on the server, local
               modifications to the Image data structure itself will
               have no effect.  Repclipr modifies the local Image data
               structure's repl and clipr fields, and notifies the
               server of their modification.

          line(dst, p0, p1, end0, end1, thick, src, sp)
               Line draws in dst a line of width 1+2*thick pixels
               joining points p0 and p1. The line is drawn using pix-
               els from the src image aligned so sp in the source cor-
               responds to p0 in the destination.  The line touches
               both p0 and p1, and end0 and end1 specify how the ends
               of the line are drawn.  Endsquare terminates the line
               perpendicularly to the direction of the line; a thick
               line with Endsquare on both ends will be a rectangle.
               Enddisc terminates the line by drawing a disc of diame-
               ter 1+2*thick centered on the end point.  Endarrow ter-
               minates the line with an arrowhead whose tip touches
               the endpoint.

               The macro ARROW permits explicit control of the shape
               of the arrow.  If all three parameters are zero, it
               produces the default arrowhead, otherwise, a sets the
               distance along line from end of the regular line to
               tip, b sets the distance along line from the barb to
               the tip, and c sets the distance perpendicular to the
               line from edge of line to the tip of the barb, all in
               pixels.

               Line and the other geometrical operators are equivalent
               to calls to gendraw using a mask produced by the geo-
               metric procedure.

          poly(dst, p, np, end0, end1, thick, src, sp)
               Poly draws a general polygon; it is conceptually

     Page 6                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

               equivalent to a series of calls to line joining adja-
               cent points in the array of Points p, which has np ele-
               ments.  The ends of the polygon are specified as in
               line; interior lines are terminated with Enddisc to
               make smooth joins.  The source is aligned so sp corre-
               sponds to p[0].

          fillpoly(dst, p, np, wind, src, sp)
               Fillpoly is like poly but fills in the resulting poly-
               gon rather than outlining it.  The source is aligned so
               sp corresponds to p[0].  The winding rule parameter
               wind resolves ambiguities about what to fill if the
               polygon is self-intersecting.  If wind is ~0, a pixel
               is inside the polygon if the polygon's winding number
               about the point is non-zero.  If wind is 1, a pixel is
               inside if the winding number is odd.  Complementary
               values (0 or ~1) cause outside pixels to be filled.
               The meaning of other values is undefined.  The polygon
               is closed with a line if necessary.

          bezier(dst, a, b, c, d, end0, end1, thick, src, sp)
               Bezier draws the cubic Bezier curve defined by Points
               a, b, c, and d. The end styles are determined by end0
               and end1; the thickness of the curve is 1+2*thick.  The
               source is aligned so sp in src corresponds to a in dst.

          bezspline(dst, p, end0, end1, thick, src, sp)
               Bezspline takes the same arguments as poly but draws a
               quadratic B-spline (despite its name) rather than a
               polygon.  If the first and last points in p are equal,
               the spline has periodic end conditions.

          bezsplinepts(pt, npt, pp)
               Bezsplinepts returns in pp a list of points making up
               the open polygon that bezspline would draw.  The caller
               is responsible for freeing *pp.

          fillbezier(dst, a, b, c, d, wind, src, sp)
               Fillbezier is to bezier as fillpoly is to poly.

          fillbezspline(dst, p, wind, src, sp)
               Fillbezspline is like fillpoly but fills the quadratic
               B-spline rather than the polygon outlined by p. The
               spline is closed with a line if necessary.

          ellipse(dst, c, a, b, thick, src, sp)
               Ellipse draws in dst an ellipse centered on c with hor-
               izontal and vertical semiaxes a and b. The source is
               aligned so sp in src corresponds to c in dst. The
               ellipse is drawn with thickness 1+2*thick.

          fillellipse(dst, c, a, b, src, sp)

     Page 7                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

               Fillellipse is like ellipse but fills the ellipse
               rather than outlining it.

          arc(dst, c, a, b, thick, src, sp, alpha, phi)
               Arc is like ellipse, but draws only that portion of the
               ellipse starting at angle alpha and extending through
               an angle of phi. The angles are measured in degrees
               counterclockwise from the positive x axis.

          fillarc(dst, c, a, b, src, sp, alpha, phi)
               Fillarc is like arc, but fills the sector with the
               source color.

          icossin(deg, cosp, sinp)
               Icossin stores in *cosp and *sinp scaled integers rep-
               resenting the cosine and sine of the angle deg, mea-
               sured in integer degrees.  The values are scaled so
               cos(0) is 1024.

          icossin2(x, y, cosp, sinp)
               Icossin2 is analogous to icossin, with the angle repre-
               sented not in degrees but implicitly by the point
               (x,y).  It is to icossin what atan2 is to atan (see
               sin(2)).

          border(dst, r, i, color, sp)
               Border draws an outline of rectangle r in the specified
               color. The outline has width i; if positive, the border
               goes inside the rectangle; negative, outside.  The
               source is aligned so sp corresponds to r.min.

          string(dst, p, src, sp, font, s)
               String draws in dst characters specified by the string
               s and font; it is equivalent to a series of calls to
               gendraw using source src and masks determined by the
               character shapes.  The text is positioned with the left
               of the first character at p.x and the top of the line
               of text at p.y.  The source is positioned so sp in src
               corresponds to p in dst. String returns a Point that is
               the position of the next character that would be drawn
               if the string were longer.

               For characters with undefined or zero-width images in
               the font, the character at font position 0 (NUL) is
               drawn.

               The other string routines are variants of this basic
               form, and have names that encode their variant behav-
               ior.  Routines whose names contain rune accept a string
               of Runes rather than UTF-encoded bytes.  Routines end-
               ing in n accept an argument, n, that defines the number
               of characters to draw rather than accepting a NUL-

     Page 8                       Plan 9            (printed 12/21/24)

     DRAW(2)                                                   DRAW(2)

               terminated string.  Routines containing bg draw the
               background behind the characters in the specified color
               (bg) and alignment (bgp); normally the text is drawn
               leaving the background intact.

               The routine _string captures all this behavior into a
               single operator.  Whether it draws a UTF string or Rune
               string depends on whether s or r is null (the string
               length is always determined by len). If bg is non-null,
               it is used as a background color.  The clipr argument
               allows further management of clipping when drawing the
               string; it is intersected with the usual clipping rect-
               angles to further limit the extent of the text.

          mousescrollsize(maxlines)
               Determine the number of lines to scroll.  The default
               is 1.  The environment variable mousescrollsize may
               either be set to an integer number of lines to scroll,
               or a floating point percentage of maxlines, indicated
               with a `%'.

          newwindow(wname)
               Connect to a new window if possible.

          drawsetdebug(on)
               Turns on or off debugging output (usually to a serial
               line) according to whether on is non-zero.

     SOURCE
          /sys/src/libdraw

     SEE ALSO
          graphics(2), stringsize(2), color(6), utf(6), addpt(2)

          T. Porter, T. Duff.  ``Compositing Digital Images'',
          Computer Graphics (Proc. SIGGRAPH), 18:3, pp. 253-259, 1984.

     DIAGNOSTICS
          These routines call the graphics error function on fatal
          errors.

     BUGS
          Anti-aliased characters can be drawn by defining a font with
          multiple bits per pixel, but there are no anti-aliasing geo-
          metric primitives.

     Page 9                       Plan 9            (printed 12/21/24)