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.
STRING(2) STRING(2)
NAME
s_alloc, s_append, s_array, s_copy, s_error, s_free,
s_incref, s_memappend, s_nappend, s_new, s_newalloc,
s_parse, s_reset, s_restart, s_terminate, s_tolower, s_putc,
s_unique, s_grow, s_read, s_read_line, s_getline -
extensible strings
SYNOPSIS
#include <u.h>
#include <libc.h>
#include <String.h>
String* s_new(void)
void s_free(String *s)
String* s_newalloc(int n)
String* s_array(char *p, int n)
String* s_grow(String *s, int n)
void s_putc(String *s, int c)
void s_terminate(String *s)
String* s_reset(String *s)
String* s_restart(String *s)
String* s_append(String *s, char *p)
String* s_nappend(String *s, char *p, int n)
String* s_memappend(String *s, char *p, int n)
String* s_copy(char *p)
String* s_parse(String *s1, String *s2)
void s_tolower(String *s)
String* s_incref(String *s)
String* s_unique(String *s)
#include <bio.h>
int s_read(Biobuf *b, String *s, int n)
char* s_read_line(Biobuf *b, String *s)
char* s_getline(Biobuf *b, String *s)
DESCRIPTION
These routines manipulate extensible strings. The basic type
is String, which points to an array of characters. The
string maintains pointers to the beginning and end of the
allocated array. In addition a finger pointer keeps track
of where parsing will start (for s_parse) or new characters
will be added (for s_putc, s_append, and s_nappend). The
structure, and a few useful macros are:
typedef struct String {
Lock;
char *base; /* base of String */
char *end; /* end of allocated space+1 */
char *ptr; /* ptr into String */
...
} String;
#define s_to_c(s) ((s)->base)
#define s_len(s) ((s)->ptr-(s)->base)
#define s_clone(s) s_copy((s)->base)
S_to_c is used when code needs a reference to the character
array. Using s->base directly is frowned upon since it
exposes too much of the implementation.
allocation and freeing
A string must be allocated before it can be used. One nor-
mally does this using s_new, giving the string an initial
allocation of 128 bytes. If you know that the string will
need to grow much longer, you can use s_newalloc instead,
specifying the number of bytes in the initial allocation.
S_free causes both the string and its character array to be
freed.
S_grow grows a string's allocation by a fixed amount. It is
useful if you are reading directly into a string's character
array but should be avoided if possible.
S_array is used to create a constant array, that is, one
whose contents won't change. It points directly to the
character array given as an argument. Tread lightly when
using this call.
Filling the string
After its initial allocation, the string points to the
beginning of an allocated array of characters starting with
NUL.
S_putc writes a character into the string at the pointer and
advances the pointer to point after it.
S_terminate writes a NUL at the pointer but doesn't advance
it.
S_restart resets the pointer to the begining of the string
but doesn't change the contents.
S_reset is equivalent to s_restart followed by s_terminate.
S_append and s_nappend copy characters into the string at
the pointer and advance the pointer. They also write a NUL
at the pointer without advancing the pointer beyond it.
Both routines stop copying on encountering a NUL.
S_memappend is like s_nappend but doesn't stop at a NUL.
If you know the initial character array to be copied into a
string, you can allocate a string and copy in the bytes
using s_copy. This is the equivalent of a s_new followed by
an s_append.
S_parse copies the next white space terminated token from s1
to the end of s2. White space is defined as space, tab, and
newline. Both single and double quoted strings are treated
as a single token. The bounding quotes are not copied.
There is no escape mechanism.
S_tolower converts all ASCII characters in the string to
lower case.
Multithreading
S_incref is used by multithreaded programs to avoid having
the string memory released until the last user of the string
performs an s_free. S_unique returns a unique copy of the
string: if the reference count it 1 it returns the string,
otherwise it returns an s_clone of the string.
Bio interaction
S_read reads the requested number of characters through a
Biobuf into a string. The string is grown as necessary. An
eof or error terminates the read. The number of bytes read
is returned. The string is null terminated.
S_read_line reads up to and including the next newline and
returns a pointer to the beginning of the bytes read. An
eof or error terminates the read. The string is null ter-
minated.
S_getline reads up to the next newline and returns a pointer
to the beginning of the bytes read. Leading spaces and tabs
and the trailing newline are all discarded. S_getline will
recursively read through files included with #include and
discard all other lines beginning with #.
SOURCE
/sys/src/libString
SEE ALSO
bio(2)
/plan9/man/2/