DRAW(2)						       DRAW(2)

     NAME
	  Image, draw, gendraw,	drawreplxy, drawrepl, replclipr, line,
	  poly,	fillpoly, bezier, bezspline, fillbezier,
	  fillbezspline, ellipse, fillellipse, arc, fillarc, icossin,
	  icossin2, border, mkwarp, affinewarp,	string,	stringn,
	  runestring, runestringn, stringbg, stringnbg,	runestringbg,
	  runestringnbg, _string, ARROW, 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
	  struct Warp
	  {
	       long	 m[3][3];
	       int	 flags;
	  } Warp;

	  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,
	  } 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	bezierpts(Point	p0, Point p1, Point p2,	Point p3, Point	**pp)
	  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,
		    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)
	  void	icossin(int deg, int *cosp, int	*sinp)
	  void	icossin2(int x,	int y, int *cosp, int *sinp)
	  void	border(Image *dst, Rectangle r,	int i, Image *color, Point sp)
	  void	borderop(Image *dst, Rectangle r, int i, Image *color, Point sp,
		    Drawop op)
	  Warp	mkwarp(double m[3][3])
	  void	affinewarp(Image *dst, Rectangle r, Image *src,	Point p, Warp *w,
		    int	smooth)
	  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)
	  void	drawsetdebug(int on)

	  enum
	  {
		/* line	ends */
		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
		    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
	       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.	Replclipr 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
	       corresponds 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
	       geometric procedure.

	  poly(dst, p, np, end0, end1, thick, src, sp)
	       Poly draws a general polygon; it	is conceptually
	       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
	       corresponds to p[0].

	  fillpoly(dst,	p, np, wind, src, sp)
	       Fillpoly	is like	poly but fills in the resulting
	       polygon 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.  Comple-
	       mentary 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.

	  bezierpts(a, b, c, d,	pp)
	       Bezierpts returns in pp a list of points	making up the
	       open polygon that bezier	would draw.  The caller	is
	       responsible for freeing *pp.

	  bezspline(dst, p, np,	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,	np, 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)
	       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
	       representing the	cosine and sine	of the angle deg,
	       measured	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
	       represented 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.

	  mkwarp(m)
	       Mkwarp converts a 3×3 row-major	matrix of doubles (usu-
	       ally a geometry(2) Matrix) into the fixed-point
	       representation required by affinewarp and returns it,
	       ignoring	the last row which is always set to [0 0 1]
	       for affine transformations.

	  affinewarp(dst, r, src, p, w,	smooth)
	       Affinewarp applies an affine transformation defined by
	       w to src, and stores the	result in dst. It follows the
	       behavior	of draw	regarding the use of clipr and the
	       repl bit, but applied to	the affine mappings.  The
	       source is positioned so p in src	corresponds to
	       dst->r.min, which is treated as the origin for the
	       affine transformation.  If smooth is set, a bilinear
	       interpolation filter will be used to sample src.

	  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
	       behavior.  Routines whose names contain rune accept a
	       string of Runes rather than UTF-encoded bytes.  Rou-
	       tines ending in n accept	an argument, n,	that defines
	       the number of characters	to draw	rather than accepting
	       a NUL-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 rec-
	       tangles to further limit	the extent of the text.

	  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
	  geometric primitives.



/plan9/man/2/