[Commit] Xr/src Xr.h,1.21,1.22 xr.c,1.20,1.21 xrgstate.c,1.29,1.30 xrint.h,1.35,1.36 xrpath.c,1.14,1.15 xrtraps.c,1.19,1.20
Carl Worth
commit@keithp.com
Thu, 01 May 2003 08:18:28 -0700
Committed by: cworth
Update of /local/src/CVS/Xr/src
In directory home.keithp.com:/tmp/cvs-serv20145/src
Modified Files:
Xr.h xr.c xrgstate.c xrint.h xrpath.c xrtraps.c
Log Message:
Added several query functions. Experimental clip support (still incomplete)
Index: Xr.h
===================================================================
RCS file: /local/src/CVS/Xr/src/Xr.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- Xr.h 23 Apr 2003 14:20:00 -0000 1.21
+++ Xr.h 1 May 2003 15:18:25 -0000 1.22
@@ -116,6 +116,8 @@
void
XrSetOperator(XrState *xrs, XrOperator op);
+/* XXX: Probably want to bite the bullet and expose an XrColor object */
+
void
XrSetRGBColor(XrState *xrs, double red, double green, double blue);
@@ -164,11 +166,14 @@
double c, double d,
double tx, double ty);
+/* XXX: Probably want to expose an XrMatrix object here, with XrMatrixTransformPoint, etc.
+ That might make it easier to expand to projective transforms later */
+
void
XrSetMatrix(XrState *xrs,
- double a, double b,
- double c, double d,
- double tx, double ty);
+ double a, double b,
+ double c, double d,
+ double tx, double ty);
/* XXX: Postscript has both a defaultmatrix and an identmatrix. But
there, they do different things. Here, where they perform the same
@@ -218,6 +223,10 @@
void
XrFill(XrState *xrs);
+/* Clipping */
+void
+XrClip(XrState *xrs);
+
/* Font/Text functions */
void
XrSelectFont(XrState *xrs, const char *key);
@@ -278,6 +287,38 @@
int height);
/* Query functions */
+
+XrOperator
+XrGetOperator(XrState *xrs);
+
+double
+XrGetTolerance(XrState *xrs);
+
+void
+XrGetCurrentPoint(XrState *, double *x, double *y);
+
+XrFillRule
+XrGetFillRule(XrState *xrs);
+
+double
+XrGetLineWidth(XrState *xrs);
+
+XrLineCap
+XrGetLineCap(XrState *xrs);
+
+XrLineJoin
+XrGetLineJoin(XrState *xrs);
+
+double
+XrGetMiterLimit(XrState *xrs);
+
+/* XXX: How to do XrGetDash??? Do we want to switch to an XrDash object? */
+
+void
+XrGetMatrix(XrState *xrs,
+ double *a, double *b,
+ double *c, double *d,
+ double *tx, double *ty);
XrSurface *
XrGetTargetSurface (XrState *xrs);
Index: xr.c
===================================================================
RCS file: /local/src/CVS/Xr/src/xr.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- xr.c 23 Apr 2003 14:20:00 -0000 1.20
+++ xr.c 1 May 2003 15:18:25 -0000 1.21
@@ -99,6 +99,12 @@
xrs->status = _XrGStateSetTargetSurface (_XR_CURRENT_GSTATE (xrs), surface);
}
+XrSurface *
+XrGetTargetSurface (XrState *xrs)
+{
+ return _XrGStateGetTargetSurface (_XR_CURRENT_GSTATE (xrs));
+}
+
void
XrSetTargetDrawable (XrState *xrs,
Display *dpy,
@@ -122,6 +128,12 @@
xrs->status = _XrGStateSetOperator(_XR_CURRENT_GSTATE(xrs), op);
}
+XrOperator
+XrGetOperator(XrState *xrs)
+{
+ return _XrGStateGetOperator(_XR_CURRENT_GSTATE(xrs));
+}
+
void
XrSetRGBColor(XrState *xrs, double red, double green, double blue)
{
@@ -146,6 +158,12 @@
xrs->status = _XrGStateSetTolerance(_XR_CURRENT_GSTATE(xrs), tolerance);
}
+double
+XrGetTolerance(XrState *xrs)
+{
+ return _XrGStateGetTolerance(_XR_CURRENT_GSTATE(xrs));
+}
+
void
XrSetAlpha(XrState *xrs, double alpha)
{
@@ -175,6 +193,12 @@
xrs->status = _XrGStateSetLineWidth(_XR_CURRENT_GSTATE(xrs), width);
}
+double
+XrGetLineWidth(XrState *xrs)
+{
+ return _XrGStateGetLineWidth(_XR_CURRENT_GSTATE(xrs));
+}
+
void
XrSetLineCap(XrState *xrs, XrLineCap line_cap)
{
@@ -184,6 +208,12 @@
xrs->status = _XrGStateSetLineCap(_XR_CURRENT_GSTATE(xrs), line_cap);
}
+XrLineCap
+XrGetLineCap(XrState *xrs)
+{
+ return _XrGStateGetLineCap(_XR_CURRENT_GSTATE(xrs));
+}
+
void
XrSetLineJoin(XrState *xrs, XrLineJoin line_join)
{
@@ -193,6 +223,12 @@
xrs->status = _XrGStateSetLineJoin(_XR_CURRENT_GSTATE(xrs), line_join);
}
+XrLineJoin
+XrGetLineJoin(XrState *xrs)
+{
+ return _XrGStateGetLineJoin(_XR_CURRENT_GSTATE(xrs));
+}
+
void
XrSetDash(XrState *xrs, double *dashes, int ndash, double offset)
{
@@ -211,6 +247,12 @@
xrs->status = _XrGStateSetMiterLimit(_XR_CURRENT_GSTATE(xrs), limit);
}
+double
+XrGetMiterLimit(XrState *xrs)
+{
+ return _XrGStateGetMiterLimit(_XR_CURRENT_GSTATE(xrs));
+}
+
void
XrTranslate(XrState *xrs, double tx, double ty)
{
@@ -365,6 +407,16 @@
}
void
+XrGetCurrentPoint(XrState *xrs, double *x, double *y)
+{
+ /* XXX: Should we do anything with the return value in the error case? */
+ if (xrs->status)
+ return;
+
+ xrs->status = _XrGStateGetCurrentPoint(_XR_CURRENT_GSTATE(xrs), x, y);
+}
+
+void
XrStroke(XrState *xrs)
{
if (xrs->status)
@@ -383,6 +435,15 @@
}
void
+XrClip(XrState *xrs)
+{
+ if (xrs->status)
+ return;
+
+ xrs->status = _XrGStateClip(_XR_CURRENT_GSTATE(xrs));
+}
+
+void
XrSelectFont(XrState *xrs, const char *key)
{
if (xrs->status)
@@ -488,12 +549,6 @@
surface,
x, y,
width, height);
-}
-
-XrSurface *
-XrGetTargetSurface (XrState *xrs)
-{
- return _XrGStateGetTargetSurface (_XR_CURRENT_GSTATE (xrs));
}
XrStatus
Index: xrgstate.c
===================================================================
RCS file: /local/src/CVS/Xr/src/xrgstate.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- xrgstate.c 17 Apr 2003 20:24:29 -0000 1.29
+++ xrgstate.c 1 May 2003 15:18:25 -0000 1.30
@@ -28,6 +28,12 @@
#include "xrint.h"
+static void
+_XrGStateSetCurrentPt(XrGState *gstate, double x, double y);
+
+static XrStatus
+_XrGStateFillToSurface(XrGState *gstate, XrSurface *src, XrSurface *dst);
+
XrGState *
_XrGStateCreate()
{
@@ -64,7 +70,8 @@
gstate->surface = NULL;
gstate->solid = NULL;
gstate->pattern = NULL;
- gstate->mask = NULL;
+
+ gstate->clip.surface = NULL;
gstate->alpha = 1.0;
_XrColorInit(&gstate->color);
@@ -101,7 +108,7 @@
_XrSurfaceReference(gstate->surface);
_XrSurfaceReference(gstate->solid);
_XrSurfaceReference(gstate->pattern);
- _XrSurfaceReference(gstate->mask);
+ _XrSurfaceReference(gstate->clip.surface);
status = _XrPathInitCopy(&gstate->path, &other->path);
if (status)
@@ -130,9 +137,16 @@
_XrFontDeinit(&gstate->font);
XrSurfaceDestroy(gstate->surface);
+ gstate->surface = NULL;
+
XrSurfaceDestroy(gstate->solid);
+ gstate->solid = NULL;
+
XrSurfaceDestroy(gstate->pattern);
- XrSurfaceDestroy(gstate->mask);
+ gstate->pattern = NULL;
+
+ XrSurfaceDestroy(gstate->clip.surface);
+ gstate->clip.surface = NULL;
_XrColorDeinit(&gstate->color);
@@ -313,6 +327,12 @@
return XrStatusSuccess;
}
+XrOperator
+_XrGStateGetOperator(XrGState *gstate)
+{
+ return gstate->operator;
+}
+
XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{
@@ -336,6 +356,12 @@
return XrStatusSuccess;
}
+double
+_XrGStateGetTolerance(XrGState *gstate)
+{
+ return gstate->tolerance;
+}
+
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha)
{
@@ -372,6 +398,12 @@
return XrStatusSuccess;
}
+double
+_XrGStateGetLineWidth(XrGState *gstate)
+{
+ return gstate->line_width;
+}
+
XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap)
{
@@ -380,6 +412,12 @@
return XrStatusSuccess;
}
+XrLineCap
+_XrGStateGetLineCap(XrGState *gstate)
+{
+ return gstate->line_cap;
+}
+
XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join)
{
@@ -388,6 +426,12 @@
return XrStatusSuccess;
}
+XrLineJoin
+_XrGStateGetLineJoin(XrGState *gstate)
+{
+ return gstate->line_join;
+}
+
XrStatus
_XrGStateSetDash(XrGState *gstate, double *dash, int num_dashes, double offset)
{
@@ -419,6 +463,12 @@
return XrStatusSuccess;
}
+double
+_XrGStateGetMiterLimit(XrGState *gstate)
+{
+ return gstate->miter_limit;
+}
+
XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty)
{
@@ -652,6 +702,17 @@
}
XrStatus
+_XrGStateGetCurrentPoint(XrGState *gstate, double *x, double *y)
+{
+ *x = gstate->current_pt.x;
+ *y = gstate->current_pt.y;
+
+ _XrTransformPoint(&gstate->ctm_inverse, x, y);
+
+ return XrStatusSuccess;
+}
+
+XrStatus
_XrGStateStroke(XrGState *gstate)
{
XrStatus status;
@@ -686,12 +747,50 @@
return status;
}
- XcCompositeTrapezoids(gstate->operator,
- gstate->pattern ? gstate->pattern->xc_surface : gstate->solid->xc_surface,
- gstate->surface->xc_surface,
- 0, 0,
- traps.xtraps,
- traps.num_xtraps);
+ if (gstate->clip.surface) {
+ XrSurface *intermediate, *white;
+
+ white = XrSurfaceCreateNextToSolid(gstate->surface, XrFormatA8,
+ 1, 1,
+ 1.0, 1.0, 1.0, 1.0);
+ XrSurfaceSetRepeat(white, 1);
+
+ intermediate = XrSurfaceCreateNextToSolid(gstate->clip.surface,
+ XrFormatA8,
+ gstate->clip.width, gstate->clip.height,
+ 0.0, 0.0, 0.0, 0.0);
+ XcCompositeTrapezoids(XrOperatorAdd,
+ white->xc_surface,
+ intermediate->xc_surface,
+ 0, 0,
+ traps.xtraps,
+ traps.num_xtraps);
+ XcComposite(XrOperatorIn,
+ gstate->clip.surface->xc_surface,
+ NULL,
+ intermediate->xc_surface,
+ 0, 0, 0, 0, 0, 0,
+ gstate->clip.width, gstate->clip.height);
+ XcComposite(gstate->operator,
+ gstate->pattern ? gstate->pattern->xc_surface : gstate->solid->xc_surface,
+ intermediate->xc_surface,
+ gstate->surface->xc_surface,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ gstate->clip.width,
+ gstate->clip.height);
+ XrSurfaceDestroy(intermediate);
+ XrSurfaceDestroy (white);
+
+ } else {
+ XcCompositeTrapezoids(gstate->operator,
+ gstate->pattern ? gstate->pattern->xc_surface : gstate->solid->xc_surface,
+ gstate->surface->xc_surface,
+ 0, 0,
+ traps.xtraps,
+ traps.num_xtraps);
+ }
_XrStrokerDeinit(&stroker);
_XrTrapsDeinit(&traps);
@@ -704,6 +803,48 @@
XrStatus
_XrGStateFill(XrGState *gstate)
{
+ return _XrGStateFillToSurface(gstate,
+ gstate->pattern ? gstate->pattern : gstate->solid,
+ gstate->surface);
+}
+
+XrStatus
+_XrGStateClip(XrGState *gstate)
+{
+ XrStatus status;
+ XrSurface *alpha_one;
+
+ if (gstate->clip.surface == NULL) {
+ double x1, y1, x2, y2;
+ _XrPathBounds(&gstate->path,
+ &x1, &y1, &x2, &y2);
+ gstate->clip.x = floor(x1);
+ gstate->clip.y = floor(y1);
+ gstate->clip.width = ceil(x2 - gstate->clip.x);
+ gstate->clip.height = ceil(y2 - gstate->clip.y);
+ /* XXX: Should be able to make this work with XrFormatA8 */
+ gstate->clip.surface = XrSurfaceCreateNextToSolid(gstate->surface,
+ XrFormatA8,
+ gstate->clip.width,
+ gstate->clip.height,
+ 0.0, 0.0, 0.0, 0.0);
+ }
+
+ alpha_one = XrSurfaceCreateNextToSolid(gstate->surface, XrFormatA8,
+ 1, 1,
+ 0.0, 0.0, 0.0, 1.0);
+ XrSurfaceSetRepeat(alpha_one, 1);
+
+ status = _XrGStateFillToSurface(gstate, alpha_one, gstate->clip.surface);
+
+ XrSurfaceDestroy (alpha_one);
+
+ return status;
+}
+
+static XrStatus
+_XrGStateFillToSurface(XrGState *gstate, XrSurface *src, XrSurface *dst)
+{
XrStatus status;
static XrPathCallbacks cb = {
_XrFillerAddEdge,
@@ -726,8 +867,8 @@
}
XcCompositeTrapezoids(gstate->operator,
- gstate->pattern ? gstate->pattern->xc_surface : gstate->solid->xc_surface,
- gstate->surface->xc_surface,
+ src->xc_surface,
+ dst->xc_surface,
0, 0,
traps.xtraps,
traps.num_xtraps);
Index: xrint.h
===================================================================
RCS file: /local/src/CVS/Xr/src/xrint.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- xrint.h 17 Apr 2003 20:24:29 -0000 1.35
+++ xrint.h 1 May 2003 15:18:25 -0000 1.36
@@ -51,6 +51,15 @@
XrIntStatusDegenerate = 1000
} XrIntStatus;
+typedef struct _XrPathBounder {
+ int has_pt;
+
+ XFixed min_x;
+ XFixed min_y;
+ XFixed max_x;
+ XFixed max_y;
+} XrPathBounder;
+
typedef enum _XrPathOp {
XrPathOpMoveTo = 0,
XrPathOpLineTo = 1,
@@ -210,6 +219,15 @@
#define XR_GSTATE_LINE_JOIN_DEFAULT XrLineJoinMiter
#define XR_GSTATE_MITER_LIMIT_DEFAULT 10.0
+/* Need a name distinct from the XrClip function */
+typedef struct _XrClipRec {
+ int x;
+ int y;
+ int width;
+ int height;
+ XrSurface *surface;
+} XrClipRec;
+
typedef struct _XrGState {
XrOperator operator;
@@ -232,7 +250,8 @@
XrSurface *surface;
XrSurface *solid;
XrSurface *pattern;
- XrSurface *mask;
+
+ XrClipRec clip;
double alpha;
XrColor color;
@@ -355,12 +374,18 @@
XrStatus
_XrGStateSetOperator(XrGState *gstate, XrOperator operator);
+XrOperator
+_XrGStateGetOperator(XrGState *gstate);
+
XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue);
XrStatus
_XrGStateSetTolerance(XrGState *gstate, double tolerance);
+double
+_XrGStateGetTolerance(XrGState *gstate);
+
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha);
@@ -370,18 +395,30 @@
XrStatus
_XrGStateSetLineWidth(XrGState *gstate, double width);
+double
+_XrGStateGetLineWidth(XrGState *gstate);
+
XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap);
+XrLineCap
+_XrGStateGetLineCap(XrGState *gstate);
+
XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join);
+XrLineJoin
+_XrGStateGetLineJoin(XrGState *gstate);
+
XrStatus
_XrGStateSetDash(XrGState *gstate, double *dash, int num_dashes, double offset);
XrStatus
_XrGStateSetMiterLimit(XrGState *gstate, double limit);
+double
+_XrGStateGetMiterLimit(XrGState *gstate);
+
XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty);
@@ -437,10 +474,16 @@
_XrGStateClosePath(XrGState *gstate);
XrStatus
+_XrGStateGetCurrentPoint(XrGState *gstate, double *x, double *y);
+
+XrStatus
_XrGStateStroke(XrGState *gstate);
XrStatus
-_XrGStateFill(XrGState *fill);
+_XrGStateFill(XrGState *gstate);
+
+XrStatus
+_XrGStateClip(XrGState *gstate);
XrStatus
_XrGStateSelectFont(XrGState *gstate, const char *key);
@@ -555,6 +598,9 @@
XrStatus
_XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
+
+XrStatus
+_XrPathBounds(XrPath *path, double *x1, double *y1, double *x2, double *y2);
/* xrsurface.c */
Index: xrpath.c
===================================================================
RCS file: /local/src/CVS/Xr/src/xrpath.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- xrpath.c 26 Oct 2002 14:59:31 -0000 1.14
+++ xrpath.c 1 May 2003 15:18:25 -0000 1.15
@@ -60,6 +60,28 @@
static void
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
+static void
+_XrPathBounderInit(XrPathBounder *bounder);
+
+static void
+_XrPathBounderDeinit(XrPathBounder *bounder);
+
+static XrStatus
+_XrPathBounderAddPoint(XrPathBounder *bounder, XPointFixed *pt);
+
+static XrStatus
+_XrPathBounderAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
+
+static XrStatus
+_XrPathBounderAddSpline(void *closure,
+ XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d);
+
+static XrStatus
+_XrPathBounderDoneSubPath(void *closure, XrSubPathDone done);
+
+static XrStatus
+_XrPathBounderDonePath(void *closure);
+
void
_XrPathInit(XrPath *path)
{
@@ -430,3 +452,113 @@
return (*cb->DonePath)(closure);
}
+
+static void
+_XrPathBounderInit(XrPathBounder *bounder)
+{
+ bounder->has_pt = 0;
+}
+
+static void
+_XrPathBounderDeinit(XrPathBounder *bounder)
+{
+ bounder->has_pt = 0;
+}
+
+static XrStatus
+_XrPathBounderAddPoint(XrPathBounder *bounder, XPointFixed *pt)
+{
+ if (bounder->has_pt) {
+ if (pt->x < bounder->min_x)
+ bounder->min_x = pt->x;
+
+ if (pt->y < bounder->min_y)
+ bounder->min_y = pt->y;
+
+ if (pt->x > bounder->max_x)
+ bounder->max_x = pt->x;
+
+ if (pt->y > bounder->max_y)
+ bounder->max_y = pt->y;
+ } else {
+ bounder->min_x = pt->x;
+ bounder->min_y = pt->y;
+ bounder->max_x = pt->x;
+ bounder->max_y = pt->y;
+
+ bounder->has_pt = 1;
+ }
+
+ return XrStatusSuccess;
+}
+
+static XrStatus
+_XrPathBounderAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
+{
+ XrPathBounder *bounder = closure;
+
+ _XrPathBounderAddPoint(bounder, p1);
+ _XrPathBounderAddPoint(bounder, p2);
+
+ return XrStatusSuccess;
+}
+
+static XrStatus
+_XrPathBounderAddSpline(void *closure,
+ XPointFixed *a, XPointFixed *b, XPointFixed *c, XPointFixed *d)
+{
+ XrPathBounder *bounder = closure;
+
+ _XrPathBounderAddPoint(bounder, a);
+ _XrPathBounderAddPoint(bounder, b);
+ _XrPathBounderAddPoint(bounder, c);
+ _XrPathBounderAddPoint(bounder, d);
+
+ return XrStatusSuccess;
+}
+
+static XrStatus
+_XrPathBounderDoneSubPath(void *closure, XrSubPathDone done)
+{
+ return XrStatusSuccess;
+}
+
+static XrStatus
+_XrPathBounderDonePath(void *closure)
+{
+ return XrStatusSuccess;
+}
+
+/* XXX: Perhaps this should compute a PixRegion rather than 4 doubles */
+XrStatus
+_XrPathBounds(XrPath *path, double *x1, double *y1, double *x2, double *y2)
+{
+ XrStatus status;
+ static XrPathCallbacks cb = {
+ _XrPathBounderAddEdge,
+ _XrPathBounderAddSpline,
+ _XrPathBounderDoneSubPath,
+ _XrPathBounderDonePath
+ };
+
+ XrPathBounder bounder;
+
+ _XrPathBounderInit(&bounder);
+
+ status = _XrPathInterpret(path, XrPathDirectionForward, &cb, &bounder);
+ if (status) {
+ *x1 = *y1 = *x2 = *y2 = 0.0;
+ _XrPathBounderDeinit(&bounder);
+ return status;
+ }
+
+ *x1 = XFixedToDouble(bounder.min_x);
+ *y1 = XFixedToDouble(bounder.min_y);
+ *x2 = XFixedToDouble(bounder.max_x);
+ *y2 = XFixedToDouble(bounder.max_y);
+
+ _XrPathBounderDeinit(&bounder);
+
+ return XrStatusSuccess;
+}
+
Index: xrtraps.c
===================================================================
RCS file: /local/src/CVS/Xr/src/xrtraps.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- xrtraps.c 28 Jan 2003 21:49:57 -0000 1.19
+++ xrtraps.c 1 May 2003 15:18:25 -0000 1.20
@@ -223,7 +223,7 @@
return XrStatusSuccess;
}
-/* Warning: This function reorderd the elements of the array provided. */
+/* Warning: This function reorders the elements of the array provided. */
XrStatus
_XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4])
{