/* @(#)shape.h 9.4 88/01/19 SMI */ /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /*- Definitions for shapes shape.h, Thu Jun 27 09:38:35 1985 James Gosling, Sun Microsystems */ #ifndef sh_decref #ifndef major #ifdef SUN #include <sys/types.h> #endif #endif #ifndef pr_width #include <pixrect/pixrect.h> #endif #ifndef FRACT #include "fract.h" #endif /* * A path is a set of infinitly thin, possibly curved, lines. It can be * used as the trajectory of a pen or as the boundary of a region. */ struct path { short size, /* The amount of space available in the * path */ used; /* The amount of space used by the path */ int straight:1; /* True iff all elements of the path are * straight */ int eorule:1; /* true iff the boundary specifies a * region using the even/odd winding * number rule. False implies the nonzero * winding number rule */ short bottompos; /* The bottom position in the path element * list that is usable -- this get changed * by gsave/grestore */ short startpos; /* The position in the path element list * where the first entry in the path * starts. This can be different from * bottompos if a gsave is done when the * current path is non-empty */ struct path_element *element; /* The array of path elements */ }; /* * A shape is a possibly discretized version of a path. Besides * containing a path, it contains many alternate representations for the * path */ struct shape { struct spoint pos; /* position of bbox */ struct spoint size; /* size of bbox; size.x<0 => bbox not * known */ short refcnt; /* The number of references to this shape */ short is_rect:1; /* true iff this shape is rectangular, and * hence only the bbox is valid */ struct shape_trapezon *trapset; /* The set of trapezons that * define this shape (optional) */ #ifdef undef struct spoint pix_off; /* The coordinates of the upper left hand * corner of the pixrect */ struct pixrect *pixrect; /* The pixrect that defines this shape * (optional) */ struct shape_dcurve *curve; /* The unit-width stroke representation */ struct path path; /* The path that defines this shape * (optional) */ #endif }; #define sh_decref(sh) (--(sh)->refcnt <= 0 ? sh_freeshape(sh) : 0) #define sh_incref(sh) ((sh)->refcnt++) #define STATIC_OBJ (-0xfff) /* A segment in a trapezon */ struct shape_trapseg { short y; /* Y coordinate of segment */ short x1; /* X start of row */ short x2; /* X end of row - this pixel isnt to be * set - ie. the width is x2-x1 */ }; struct shape_trapezon { /* A trapezon describes a region that has * a flat top and bottom, but whose sides * may be curved -- they are are allowed * to be vertically concave -- for each * edge, there is a single x for each y */ struct shape_trapezon *next; short refcnt; /* The number of references to this * trapezon */ short top, /* Y coordinates of the top and bottom of * the trapezon */ bottom, left, right; short used, /* The number of segments used */ size; /* The number of segments for which space * is allocated */ struct shape_trapseg segs[1]; /* The scanlines that make up this * trapezon */ }; struct shape_arc { /* A conic arc from point A to point C * drawn towards point B with sharpness sh */ struct shape_arc *next; struct fpoint A, B, C; fract sh; }; struct shape_dcurve { /* A discrete representation of a curve. A * curve starts at point x0,y0 and ends at * point x1,y1. For each of the y1-y0+1 * rows there is exactly one x value, * contained in the x array. y0<=y1 */ short x0, y0, x1, y1; short left, /* The left and right edges of the bbox */ right; struct shape_dcurve *next; char direction; /* 1=>down, -1=>up */ short refcnt; short *x; }; struct path_element { fract variation; struct fpoint pos; /* The transformed point */ }; #define MOVE_TO_FLAG (1<<31) /* In a path_element, if variation equals * MOVE_TO_FLAG then that element is the * first point in a new loop */ #define CLOSEPATH_FLAG ((1<<31)+1) /* If a path_element has a * variation of CLOSEPATH_FLAG * then it closes off a path * segment and its x&y are * meaningless */ #define has_current_pos(path) ((path)->used > (path)->startpos) #define current_pos(path) ((path)->element[(path)->used-1].pos) /* * A fast test for the important special case of the current path being a * rectangle */ #define IS_RECT(path) (((path)->used - (path)->startpos == 4 \ || (path)->used - (path)->startpos == 5 && \ (path)->element[4].variation == CLOSEPATH_FLAG) \ && (path)->straight && \ (((path)->element[0].pos.x == (path)->element[1].pos.x && \ (path)->element[2].pos.x == (path)->element[3].pos.x && \ (path)->element[0].pos.y == (path)->element[3].pos.y && \ (path)->element[1].pos.y == (path)->element[2].pos.y) \ || ((path)->element[0].pos.y == (path)->element[1].pos.y && \ (path)->element[2].pos.y == (path)->element[3].pos.y && \ (path)->element[0].pos.x == (path)->element[3].pos.x && \ (path)->element[1].pos.x == (path)->element[2].pos.x))) typedef fract FMATRIX[3][2]; typedef float FLMATRIX[3][2]; enum TransformOpt { /* The kinds of transformation optimizations */ tro_none, /* No optimization */ tro_check, /* No opt, overflow possible */ tro_unit, /* [1 0 0 1 x y] */ tro_neg, /* [1 0 0 -1 x y] */ tro_scale, /* [a 0 0 b x y] */ tro_scalecheck, /* [a 0 0 b x y], overflow possible */ }; /* A transformation matrix: pt = xfact*x+yfact*y+offset */ struct transform { char well_behaved; /* true iff it maps a "small" range into * display coordinates */ char rigid; /* true iff this is a rigid transform, ie. * it consists of only rotations, * translations and scaling */ enum TransformOpt kind:8; /* 1=>matrix==[1 0 0 1 x y] (unit scaling) * -1=>matrix==[1 0 0 -1 x y] (unit scaling, * y inversion */ char floatexists; /* true iff the floating point form of the * transform exists */ char simplescale; /* true iff matrix==[s 0 0 -s x y] */ fract checklimit; /* Maximum input value that can be transformed without overflow */ int revision; /* The "revision level" of this matrix. Incremented each time the matrix is changed */ FMATRIX matrix; double rmatrix[3][2]; }; struct color { unsigned char red, green, blue, /* The color components */ hint; /* lookup hint */ }; enum cs_linejoin { cs_miterjoin, cs_roundjoin, cs_beveljoin, }; enum cs_linecap { cs_buttcap, cs_roundcap, cs_squarecap, }; /* A graphics context */ struct graphics_context { struct pixrect *canvas; /* The current output canvas */ struct path path; /* The current path */ struct shape *shape; /* The discrete form of the current path */ struct shape *clip; /* The clipping boundary */ fract linewidth; /* The width of a line */ short trlinewidth; /* Transformed line width */ char newwidth; /* True iff the line width has changed */ enum cs_linecap linecap:8; /* The style used to cap lines. 0=Butt, * 1=round, 2=projecting square cap */ enum cs_linejoin linejoin:8;/* The style used to join lines. 0=Miter, * 1=round, 2=bevel */ char hascurrentpoint;/* True if the currentpoint is valid */ char printermatch; /* True if printer font matching should be done */ char strokequality; /* 0->64 improving quality; -ve implies width is so narrow that quality doesn't matter */ char flatness; /* maximum acceptable pixel error in converting curves to straight lines */ fract miterlimit; /* limit for switching from mitered to * beveled line joins */ fract texture[5]; /* Line dash pattern */ fract offset; /* The offset into the dash pattern */ int textrevision; /* The transformation revision for which the texture has been revised */ fract ttexture[5]; /* Transformed texture */ fract toffset; /* Transformed texture offset */ struct psfont *font; /* The current text font */ struct color color; /* The current color */ struct fpoint currentpoint; /* The last point moved or drawn to */ struct graphics_context *gsaves; /* The set of graphics states in the gsave * stack */ short gsave_used; /* The number of stacked gsaves */ short gsave_size; /* The amount of space allocated in gsaves */ struct transform transform; /* The transformation to be applied to * points being added to the current path */ short func; /* The technique for applying the color. * Its actually the rasterop function * code. The useful values are PIX_SRC * |,&,^ PIX_DST. It may have a color * mixed in. */ struct pixrect *pattern; /* The pattern to be applied. NULL * implies the uniform pattern, in which * case func will be either PIX_SET or * PIX_CLR */ }; extern struct fpoint shape_point; /* The transformation & path building * operators sometimes communicate via * shape_point */ extern struct rpoint shape_rpoint; /* ditto here if the results are real */ struct fcorner_bbox { /* A bounding box specified by its corners */ struct fpoint ur, /* upper right */ ll; /* lower left */ }; /* Maps for converting from RGB colors to colormap indicies */ extern unsigned char red_inverse[]; extern unsigned char green_inverse[]; extern unsigned char blue_inverse[]; extern unsigned char grey_inverse[]; extern unsigned char grey_opcode[]; #define sh_colorhint(color) ((color)->red == (color)->green && (color)->green == (color)->blue \ ? grey_inverse[(color)->green] \ : red_inverse[(color)->red] + green_inverse[(color)->green] \ + blue_inverse[(color)->blue]) #define pixrectopcode(pr,color) \ ((pr)==0 ? PIX_SET \ : (pr)->pr_depth==1 \ ? grey_opcode[(color)->hint] \ : PIX_SRC | PIX_COLOR((color)->hint)) extern struct color black_color, white_color; struct color cs_frrgbcolor(); struct graphics_context *cs_newcontext(); struct color cs_frhsbcolor(); struct spoint cs_abscanvaslocation(); struct shape *sh_difference(); struct shape *sh_intersect(); struct shape *sh_copy(); struct shape *sh_translate(); struct shape *cv_pathtoshape(/*gc,mask*/); struct shape_arc *path_to_arc(); struct shape_trapezon *looptotrap(); struct pixrect *fake_bw2_make(); extern struct shape InfiniteShape; extern struct shape InvalidShape; extern struct graphics_context *temp_context; #define TOP(p) ((p)->pos.y) #define LEFT(p) ((p)->pos.x) #define BOTTOM(p) ((p)->pos.y+(p)->size.y) #define RIGHT(p) ((p)->pos.x+(p)->size.x) #define SETBOTTOM(p,b) ((p)->size.y = (b) - (p)->pos.y) #define SETRIGHT(p,b) ((p)->size.x = (b) - (p)->pos.x) #define SETTOP(p,t) ((p)->pos.y = (t)) #define SETLEFT(p,l) ((p)->pos.x = (l)) extern int ovl_state; /* -1=>overlay exists, but down; 0=>no overlay 1=>overlay exists and is up */ #define OVERLAYDOWN() (ovl_state>0 ? ovl_overlaydown() : 0) #define OVERLAYUP() (ovl_state<0 ? ovl_overlayup() : 0) #ifndef assert #ifdef DEBUG #define assert(x) (!(x) ? fprintf(stderr,"Assertion failed x [file %s, line %d]\n", __FILE__, __LINE__),abort(1) : 0) #else #define assert(x) (0) #endif #endif #ifndef abs #define abs(v) ((v)<0 ? -(v) : (v)) #endif #ifndef min #define min(a,b) ((a)<(b) ? (a) : (b)) #define max(a,b) ((a)>(b) ? (a) : (b)) #define sadd(a,b) ((short)(((short)(a))+((short)(b)))) #define ssub(a,b) ((short)(((short)(a))-((short)(b)))) #endif #endif