mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-01 16:07:57 +02:00
Added error handling (Xr shutdown) for out-of-memory handling. Started adding spline functions.
This commit is contained in:
parent
ba3bce9d7e
commit
91f09687e5
18 changed files with 806 additions and 484 deletions
12
Xr.h
12
Xr.h
|
|
@ -151,12 +151,24 @@ XrMoveTo(XrState *xrs, double x, double y);
|
|||
void
|
||||
XrLineTo(XrState *xrs, double x, double y);
|
||||
|
||||
void
|
||||
XrCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3);
|
||||
|
||||
void
|
||||
XrRelMoveTo(XrState *xrs, double x, double y);
|
||||
|
||||
void
|
||||
XrRelLineTo(XrState *xrs, double x, double y);
|
||||
|
||||
void
|
||||
XrRelCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3);
|
||||
|
||||
void
|
||||
XrClosePath(XrState *xrs);
|
||||
|
||||
|
|
|
|||
12
src/Xr.h
12
src/Xr.h
|
|
@ -151,12 +151,24 @@ XrMoveTo(XrState *xrs, double x, double y);
|
|||
void
|
||||
XrLineTo(XrState *xrs, double x, double y);
|
||||
|
||||
void
|
||||
XrCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3);
|
||||
|
||||
void
|
||||
XrRelMoveTo(XrState *xrs, double x, double y);
|
||||
|
||||
void
|
||||
XrRelLineTo(XrState *xrs, double x, double y);
|
||||
|
||||
void
|
||||
XrRelCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3);
|
||||
|
||||
void
|
||||
XrClosePath(XrState *xrs);
|
||||
|
||||
|
|
|
|||
95
src/xr.c
95
src/xr.c
|
|
@ -40,7 +40,11 @@ XrDestroy(XrState *xrs)
|
|||
void
|
||||
XrSave(XrState *xrs)
|
||||
{
|
||||
XrStatePush(xrs);
|
||||
XrError err;
|
||||
|
||||
err = XrStatePush(xrs);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -136,43 +140,114 @@ XrNewPath(XrState *xrs)
|
|||
void
|
||||
XrMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
XrError err;
|
||||
XPointDouble pt[3];
|
||||
|
||||
pt[0].x = x1; pt[0].y = y1;
|
||||
pt[1].x = x2; pt[1].y = y2;
|
||||
pt[2].x = x3; pt[2].y = y3;
|
||||
|
||||
err = XrGStateAddPathOp(CURRENT_GSTATE(xrs), XrPathOpCurveTo, pt, 3);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrRelMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrRelLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelLineTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelLineTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrRelCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
XrError err;
|
||||
XPointDouble pt[3];
|
||||
|
||||
pt[0].x = x1; pt[0].y = y1;
|
||||
pt[1].x = x2; pt[1].y = y2;
|
||||
pt[2].x = x3; pt[2].y = y3;
|
||||
|
||||
err = XrGStateAddPathOp(CURRENT_GSTATE(xrs), XrPathOpRelCurveTo, pt, 3);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrClosePath(XrState *xrs)
|
||||
{
|
||||
XrGStateClosePath(CURRENT_GSTATE(xrs));
|
||||
XrError err;
|
||||
|
||||
err = XrGStateClosePath(CURRENT_GSTATE(xrs));
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrStroke(XrState *xrs)
|
||||
{
|
||||
XrGStateStroke(CURRENT_GSTATE(xrs));
|
||||
XrError err;
|
||||
|
||||
if (xrs->error)
|
||||
return;
|
||||
|
||||
err = XrGStateStroke(CURRENT_GSTATE(xrs));
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrFill(XrState *xrs)
|
||||
{
|
||||
XrClosePath(xrs);
|
||||
XrGStateFill(CURRENT_GSTATE(xrs));
|
||||
}
|
||||
XrError err;
|
||||
|
||||
if (xrs->error)
|
||||
return;
|
||||
|
||||
XrClosePath(xrs);
|
||||
|
||||
err = XrGStateFill(CURRENT_GSTATE(xrs));
|
||||
if (err) {
|
||||
xrs->error = err;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
116
src/xrgstate.c
116
src/xrgstate.c
|
|
@ -28,23 +28,16 @@
|
|||
|
||||
#include "xrint.h"
|
||||
|
||||
/* Private functions */
|
||||
static XrGState *
|
||||
_XrGStateAlloc(void);
|
||||
|
||||
static XrGState *
|
||||
_XrGStateAlloc(void)
|
||||
{
|
||||
return malloc(sizeof(XrGState));
|
||||
}
|
||||
|
||||
XrGState *
|
||||
XrGStateCreate(Display *dpy)
|
||||
{
|
||||
XrGState *gstate;
|
||||
|
||||
gstate = _XrGStateAlloc();
|
||||
XrGStateInit(gstate, dpy);
|
||||
gstate = malloc(sizeof(XrGState));
|
||||
|
||||
if (gstate) {
|
||||
XrGStateInit(gstate, dpy);
|
||||
}
|
||||
|
||||
return gstate;
|
||||
}
|
||||
|
|
@ -78,7 +71,7 @@ XrGStateInit(XrGState *gstate, Display *dpy)
|
|||
XrPathInit(&gstate->path);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateInitCopy(XrGState *gstate, XrGState *other)
|
||||
{
|
||||
*gstate = *other;
|
||||
|
|
@ -86,7 +79,7 @@ XrGStateInitCopy(XrGState *gstate, XrGState *other)
|
|||
XrSurfaceInit(&gstate->src, gstate->dpy);
|
||||
XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
|
||||
|
||||
XrPathInitCopy(&gstate->path, &other->path);
|
||||
return XrPathInitCopy(&gstate->path, &other->path);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -111,11 +104,18 @@ XrGStateDestroy(XrGState *gstate)
|
|||
XrGState*
|
||||
XrGStateClone(XrGState *gstate)
|
||||
{
|
||||
XrError err;
|
||||
XrGState *clone;
|
||||
|
||||
clone = _XrGStateAlloc();
|
||||
clone = malloc(sizeof(XrGState));
|
||||
if (clone) {
|
||||
err = XrGStateInitCopy(clone, gstate);
|
||||
if (err) {
|
||||
free(clone);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
XrGStateInitCopy(clone, gstate);
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
|
@ -223,44 +223,69 @@ XrGStateNewPath(XrGState *gstate)
|
|||
XrPathDeinit(&gstate->path);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
|
||||
XrError
|
||||
XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts)
|
||||
{
|
||||
XPointDouble pt;
|
||||
XPointFixed pt_fixed;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
int i;
|
||||
XrError err;
|
||||
XPointFixed *pt_fixed;
|
||||
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
case XrPathOpLineTo:
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
for (i=0; i < num_pts; i++) {
|
||||
XrTransformPoint(&gstate->ctm, &pt[i]);
|
||||
}
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
case XrPathOpRelLineTo:
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
for (i=0; i < num_pts; i++) {
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Invalid */
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
pt_fixed.x = XDoubleToFixed(pt.x);
|
||||
pt_fixed.y = XDoubleToFixed(pt.y);
|
||||
pt_fixed = malloc(num_pts * sizeof(XPointFixed));
|
||||
if (pt_fixed == NULL) {
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
|
||||
XrPathAdd(&gstate->path, op, &pt_fixed, 1);
|
||||
for (i=0; i < num_pts; i++) {
|
||||
pt_fixed[i].x = XDoubleToFixed(pt[i].x);
|
||||
pt_fixed[i].y = XDoubleToFixed(pt[i].y);
|
||||
}
|
||||
|
||||
err = XrPathAdd(&gstate->path, op, pt_fixed, num_pts);
|
||||
|
||||
free(pt_fixed);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
|
||||
{
|
||||
XPointDouble pt;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
return XrGStateAddPathOp(gstate, op, &pt, 1);
|
||||
}
|
||||
|
||||
XrError
|
||||
XrGStateClosePath(XrGState *gstate)
|
||||
{
|
||||
XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
|
||||
return XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateStroke(XrGState *gstate)
|
||||
{
|
||||
XrError err;
|
||||
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge, XrStrokerDoneSubPath };
|
||||
|
||||
XrStroker stroker;
|
||||
|
|
@ -269,7 +294,9 @@ XrGStateStroke(XrGState *gstate)
|
|||
XrStrokerInit(&stroker, gstate, &traps);
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &stroker);
|
||||
err = XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &stroker);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
|
|
@ -282,21 +309,34 @@ XrGStateStroke(XrGState *gstate)
|
|||
XrStrokerDeinit(&stroker);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateFill(XrGState *gstate)
|
||||
{
|
||||
XrError err;
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge, XrPolygonDoneSubPath };
|
||||
|
||||
XrPolygon polygon;
|
||||
XrTraps traps;
|
||||
|
||||
XrPolygonInit(&polygon);
|
||||
|
||||
err = XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &polygon);
|
||||
if (err) {
|
||||
XrPolygonDeinit(&polygon);
|
||||
return err;
|
||||
}
|
||||
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &polygon);
|
||||
XrTrapsTessellatePolygon(&traps, &polygon, gstate->fill_style.winding);
|
||||
err = XrTrapsTessellatePolygon(&traps, &polygon, gstate->fill_style.winding);
|
||||
if (err) {
|
||||
XrTrapsDeinit(&traps);
|
||||
return err;
|
||||
}
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
|
|
@ -309,5 +349,7 @@ XrGStateFill(XrGState *gstate)
|
|||
XrPolygonDeinit(&polygon);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
59
src/xrint.h
59
src/xrint.h
|
|
@ -42,11 +42,18 @@
|
|||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
typedef enum _XrError {
|
||||
XrErrorSuccess = 0,
|
||||
XrErrorNoMemory
|
||||
} XrError;
|
||||
|
||||
typedef enum _XrPathOp {
|
||||
XrPathOpMoveTo,
|
||||
XrPathOpLineTo,
|
||||
XrPathOpCurveTo,
|
||||
XrPathOpRelMoveTo,
|
||||
XrPathOpRelLineTo,
|
||||
XrPathOpRelCurveTo,
|
||||
XrPathOpClosePath
|
||||
} __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */
|
||||
|
||||
|
|
@ -61,8 +68,8 @@ typedef enum _XrSubPathDone {
|
|||
} XrSubPathDone;
|
||||
|
||||
typedef struct _XrPathCallbacks {
|
||||
void (*AddEdge)(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
void (*DoneSubPath) (void *closure, XrSubPathDone done);
|
||||
XrError (*AddEdge)(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
XrError (*DoneSubPath) (void *closure, XrSubPathDone done);
|
||||
} XrPathCallbacks;
|
||||
|
||||
#define XR_PATH_BUF_SZ 64
|
||||
|
|
@ -184,6 +191,7 @@ typedef struct _XrGState {
|
|||
struct _XrState {
|
||||
Display *dpy;
|
||||
XrGState *stack;
|
||||
XrError error;
|
||||
};
|
||||
|
||||
typedef struct _XrStrokeFace {
|
||||
|
|
@ -208,7 +216,7 @@ typedef struct _XrStroker {
|
|||
XrState *
|
||||
XrStateCreate(Display *dpy);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStateInit(XrState *state, Display *dpy);
|
||||
|
||||
void
|
||||
|
|
@ -217,7 +225,7 @@ XrStateDeinit(XrState *xrs);
|
|||
void
|
||||
XrStateDestroy(XrState *state);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStatePush(XrState *xrs);
|
||||
|
||||
void
|
||||
|
|
@ -230,7 +238,7 @@ XrGStateCreate(Display *dpy);
|
|||
void
|
||||
XrGStateInit(XrGState *gstate, Display *dpy);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateInitCopy(XrGState *gstate, XrGState *other);
|
||||
|
||||
void
|
||||
|
|
@ -284,16 +292,19 @@ XrGStateRotate(XrGState *gstate, double angle);
|
|||
void
|
||||
XrGStateNewPath(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts);
|
||||
|
||||
XrError
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateClosePath(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateStroke(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateFill(XrGState *fill);
|
||||
|
||||
/* xrcolor.c */
|
||||
|
|
@ -310,25 +321,19 @@ void
|
|||
XrColorSetAlpha(XrColor *color, double alpha);
|
||||
|
||||
/* xrpath.c */
|
||||
XrPath *
|
||||
XrPathCreate(void);
|
||||
|
||||
void
|
||||
XrPathInit(XrPath *path);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInitCopy(XrPath *path, XrPath *other);
|
||||
|
||||
void
|
||||
XrPathDeinit(XrPath *path);
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
|
||||
|
||||
/* xrsurface.c */
|
||||
|
|
@ -357,10 +362,10 @@ XrPolygonInit(XrPolygon *poly);
|
|||
void
|
||||
XrPolygonDeinit(XrPolygon *poly);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done);
|
||||
|
||||
/* xrstroke.c */
|
||||
|
|
@ -370,10 +375,10 @@ XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps);
|
|||
void
|
||||
XrStrokerDeinit(XrStroker *stroker);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerDoneSubPath (void *closure, XrSubPathDone done);
|
||||
|
||||
/* xrtransform.c */
|
||||
|
|
@ -420,22 +425,16 @@ void
|
|||
XrTransformPoint(XrTransform *transform, XPointDouble *pt);
|
||||
|
||||
/* xrtraps.c */
|
||||
XrTraps *
|
||||
XrTrapsCreate(void);
|
||||
|
||||
void
|
||||
XrTrapsInit(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrTrapsDeinit(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrTrapsDestroy(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4]);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellatePolygon (XrTraps *traps, XrPolygon *poly, int winding);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
124
src/xrpath.c
124
src/xrpath.c
|
|
@ -30,48 +30,37 @@
|
|||
static void
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewOpBuf(XrPath *path);
|
||||
|
||||
static void
|
||||
_XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg);
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewArgBuf(XrPath *path);
|
||||
|
||||
XrPathOpBuf *
|
||||
static XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *buf);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op);
|
||||
|
||||
XrPathArgBuf *
|
||||
static XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *buf);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
|
||||
|
||||
static void
|
||||
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
|
||||
XrPath *
|
||||
XrPathCreate(void)
|
||||
{
|
||||
XrPath *path;
|
||||
|
||||
path = malloc(sizeof(XrPath));
|
||||
XrPathInit(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInit(XrPath *path)
|
||||
{
|
||||
|
|
@ -82,7 +71,7 @@ XrPathInit(XrPath *path)
|
|||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInitCopy(XrPath *path, XrPath *other)
|
||||
{
|
||||
XrPathOpBuf *op, *other_op;
|
||||
|
|
@ -92,15 +81,23 @@ XrPathInitCopy(XrPath *path, XrPath *other)
|
|||
|
||||
for (other_op = other->op_head; other_op; other_op = other_op->next) {
|
||||
op = _XrPathOpBufCreate();
|
||||
if (op == NULL) {
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
*op = *other_op;
|
||||
_XrPathAddOpBuf(path, op);
|
||||
}
|
||||
|
||||
for (other_arg = other->arg_head; other_arg; other_arg = other_arg->next) {
|
||||
arg = _XrPathArgBufCreate();
|
||||
if (arg == NULL) {
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
*arg = *other_arg;
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
}
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -124,13 +121,6 @@ XrPathDeinit(XrPath *path)
|
|||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path)
|
||||
{
|
||||
XrPathDeinit(path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
|
||||
{
|
||||
|
|
@ -146,13 +136,18 @@ _XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
|
|||
path->op_tail = op;
|
||||
}
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewOpBuf(XrPath *path)
|
||||
{
|
||||
XrPathOpBuf *op;
|
||||
|
||||
op = _XrPathOpBufCreate();
|
||||
if (op == NULL)
|
||||
return XrErrorNoMemory;
|
||||
|
||||
_XrPathAddOpBuf(path, op);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -170,77 +165,95 @@ _XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg)
|
|||
path->arg_tail = arg;
|
||||
}
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewArgBuf(XrPath *path)
|
||||
{
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
arg = _XrPathArgBufCreate();
|
||||
|
||||
if (arg == NULL)
|
||||
return XrErrorNoMemory;
|
||||
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
XrError err;
|
||||
|
||||
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewOpBuf(path);
|
||||
err = _XrPathNewOpBuf(path);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
_XrPathOpBufAdd(path->op_tail, op);
|
||||
|
||||
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewArgBuf(path);
|
||||
err = _XrPathNewArgBuf(path);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
XrPathOpBuf *
|
||||
static XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void)
|
||||
{
|
||||
XrPathOpBuf *op;
|
||||
|
||||
op = malloc(sizeof(XrPathOpBuf));
|
||||
|
||||
op->num_ops = 0;
|
||||
op->next = NULL;
|
||||
if (op) {
|
||||
op->num_ops = 0;
|
||||
op->next = NULL;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *op)
|
||||
{
|
||||
op->num_ops = 0;
|
||||
free(op);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op)
|
||||
{
|
||||
op_buf->op[op_buf->num_ops++] = op;
|
||||
}
|
||||
|
||||
XrPathArgBuf *
|
||||
static XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void)
|
||||
{
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
arg = malloc(sizeof(XrPathArgBuf));
|
||||
|
||||
arg->num_pts = 0;
|
||||
arg->next = NULL;
|
||||
if (arg) {
|
||||
arg->num_pts = 0;
|
||||
arg->next = NULL;
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *arg)
|
||||
{
|
||||
arg->num_pts = 0;
|
||||
free(arg);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -287,9 +300,10 @@ _TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
|
|||
} \
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure)
|
||||
{
|
||||
XrError err;
|
||||
int i;
|
||||
XrPathOpBuf *op_buf;
|
||||
XrPathOp op;
|
||||
|
|
@ -322,8 +336,11 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
if (has_edge)
|
||||
(*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (has_edge) {
|
||||
err = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
|
|
@ -337,7 +354,9 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
err = (*cb->AddEdge)(closure, ¤t, &pt);
|
||||
if (err)
|
||||
return err;
|
||||
current = pt;
|
||||
has_edge = 1;
|
||||
} else {
|
||||
|
|
@ -347,8 +366,11 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
}
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
if (has_edge)
|
||||
(*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (has_edge) {
|
||||
err = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
|
|
@ -364,7 +386,9 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
END_ARGS(1);
|
||||
_TranslatePointFixed(&pt, ¤t);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
err = (*cb->AddEdge)(closure, ¤t, &pt);
|
||||
if (err)
|
||||
return err;
|
||||
current = pt;
|
||||
has_edge = 1;
|
||||
} else {
|
||||
|
|
@ -388,4 +412,6 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional);
|
||||
|
||||
void
|
||||
|
|
@ -52,7 +52,7 @@ XrPolygonDeinit(XrPolygon *poly)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional)
|
||||
{
|
||||
XrEdge *new_edges;
|
||||
|
|
@ -60,33 +60,39 @@ _XrPolygonGrowBy(XrPolygon *poly, int additional)
|
|||
int new_size = poly->num_edges + additional;
|
||||
|
||||
if (new_size <= poly->edges_size) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
poly->edges_size = new_size;
|
||||
new_edges = realloc(poly->edges, poly->edges_size * sizeof(XrEdge));
|
||||
|
||||
if (new_edges) {
|
||||
poly->edges = new_edges;
|
||||
} else {
|
||||
/* XXX: BUG: How do we really want to handle this out of memory error? */
|
||||
if (new_edges == NULL) {
|
||||
poly->edges_size = old_size;
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
|
||||
poly->edges = new_edges;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrError err;
|
||||
XrEdge *edge;
|
||||
XrPolygon *poly = closure;
|
||||
|
||||
/* drop horizontal edges */
|
||||
if (p1->y == p2->y) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
if (poly->num_edges >= poly->edges_size) {
|
||||
_XrPolygonGrowBy(poly, XR_POLYGON_GROWTH_INC);
|
||||
err = _XrPolygonGrowBy(poly, XR_POLYGON_GROWTH_INC);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
edge = &poly->edges[poly->num_edges];
|
||||
|
|
@ -101,10 +107,13 @@ XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
}
|
||||
|
||||
poly->num_edges++;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,21 +29,30 @@
|
|||
XrState *
|
||||
XrStateCreate(Display *dpy)
|
||||
{
|
||||
XrError err;
|
||||
XrState *xrs;
|
||||
|
||||
xrs = malloc(sizeof(XrState));
|
||||
|
||||
XrStateInit(xrs, dpy);
|
||||
if (xrs) {
|
||||
err = XrStateInit(xrs, dpy);
|
||||
if (err) {
|
||||
free(xrs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return xrs;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStateInit(XrState *xrs, Display *dpy)
|
||||
{
|
||||
xrs->dpy = dpy;
|
||||
xrs->stack = NULL;
|
||||
XrStatePush(xrs);
|
||||
xrs->error = XrErrorSuccess;
|
||||
|
||||
return XrStatePush(xrs);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -61,7 +70,7 @@ XrStateDestroy(XrState *xrs)
|
|||
free(xrs);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStatePush(XrState *xrs)
|
||||
{
|
||||
XrGState *top;
|
||||
|
|
@ -72,8 +81,13 @@ XrStatePush(XrState *xrs)
|
|||
top = XrGStateCreate(xrs->dpy);
|
||||
}
|
||||
|
||||
if (top == NULL)
|
||||
return XrErrorNoMemory;
|
||||
|
||||
top->next = xrs->stack;
|
||||
xrs->stack = top;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@
|
|||
static void
|
||||
_TranslatePoint(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
static int
|
||||
_XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out);
|
||||
|
||||
static XrError
|
||||
_XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out);
|
||||
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps)
|
||||
{
|
||||
|
|
@ -51,7 +57,7 @@ _TranslatePoint(XPointFixed *pt, XPointFixed *offset)
|
|||
}
|
||||
|
||||
static int
|
||||
XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
||||
_XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XPointFixed d_in, d_out;
|
||||
|
||||
|
|
@ -63,11 +69,12 @@ XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
|||
return d_out.y * d_in.x > d_in.y * d_out.x;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
||||
static XrError
|
||||
_XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XrError err;
|
||||
XrGState *gstate = stroker->gstate;
|
||||
int clockwise = XrStrokerFaceClockwise (in, out);
|
||||
int clockwise = _XrStrokerFaceClockwise (in, out);
|
||||
XrPolygon polygon;
|
||||
XPointFixed *inpt, *outpt;
|
||||
|
||||
|
|
@ -129,18 +136,22 @@ XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
|||
break;
|
||||
}
|
||||
}
|
||||
XrTrapsTessellatePolygon (stroker->traps, &polygon, 1);
|
||||
|
||||
err = XrTrapsTessellatePolygon (stroker->traps, &polygon, 1);
|
||||
XrPolygonDeinit (&polygon);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerCap(XrStroker *stroker, XrStrokeFace *f)
|
||||
static void
|
||||
_XrStrokerCap(XrStroker *stroker, XrStrokeFace *f)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrError err;
|
||||
XrStroker *stroker = closure;
|
||||
XrGState *gstate = stroker->gstate;
|
||||
XrStrokeStyle *style = &gstate->stroke_style;
|
||||
|
|
@ -159,7 +170,7 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
|
||||
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
|
||||
if (mag == 0) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
vector.x /= mag;
|
||||
|
|
@ -195,9 +206,11 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
face.ccw = quad[1];
|
||||
face.vector = user_vector;
|
||||
|
||||
if (stroker->have_prev)
|
||||
XrStrokerJoin (stroker, &stroker->prev, &face);
|
||||
else {
|
||||
if (stroker->have_prev) {
|
||||
err = _XrStrokerJoin (stroker, &stroker->prev, &face);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
stroker->have_prev = 1;
|
||||
stroker->first = face;
|
||||
}
|
||||
|
|
@ -207,63 +220,26 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
stroker->prev.cw = quad[3];
|
||||
stroker->prev.vector = user_vector;
|
||||
|
||||
XrTrapsTessellateRectangle(traps, quad);
|
||||
return XrTrapsTessellateRectangle(traps, quad);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
XrError err;
|
||||
XrStroker *stroker = closure;
|
||||
|
||||
switch (done) {
|
||||
case XrSubPathDoneCap:
|
||||
XrStrokerCap (stroker, &stroker->first);
|
||||
XrStrokerCap (stroker, &stroker->prev);
|
||||
_XrStrokerCap (stroker, &stroker->first);
|
||||
_XrStrokerCap (stroker, &stroker->prev);
|
||||
break;
|
||||
case XrSubPathDoneJoin:
|
||||
XrStrokerJoin (stroker, &stroker->prev, &stroker->first);
|
||||
err = _XrStrokerJoin (stroker, &stroker->prev, &stroker->first);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* These functions aren't written yet... */
|
||||
#if 0
|
||||
static void
|
||||
_XrGStateStrokerCap(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_cap) {
|
||||
case XrLineCapRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapSquare:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapButt:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokerJoin(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2, const XPointDouble *p3,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_join) {
|
||||
case XrLineJoinMiter:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinBevel:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,14 +30,14 @@
|
|||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrTrapsGrowBy(XrTraps *traps, int additional);
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right);
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
|
|
@ -60,18 +60,6 @@ _ComputeXIntercept (XLineFixed *l, double inverse_slope);
|
|||
static XFixed
|
||||
_ComputeIntersect (XLineFixed *l1, XLineFixed *l2);
|
||||
|
||||
XrTraps *
|
||||
XrTrapsCreate(void)
|
||||
{
|
||||
XrTraps *traps;
|
||||
|
||||
traps = Xmalloc(sizeof(XrTraps));
|
||||
|
||||
XrTrapsInit(traps);
|
||||
|
||||
return traps;
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsInit(XrTraps *traps)
|
||||
{
|
||||
|
|
@ -91,25 +79,21 @@ XrTrapsDeinit(XrTraps *traps)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsDestroy(XrTraps *traps)
|
||||
{
|
||||
XrTrapsDeinit(traps);
|
||||
Xfree(traps);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right)
|
||||
{
|
||||
XrError err;
|
||||
XTrapezoid *trap;
|
||||
|
||||
if (top == bottom) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
if (traps->num_xtraps >= traps->xtraps_size) {
|
||||
_XrTrapsGrowBy(traps, XR_TRAPS_GROWTH_INC);
|
||||
err = _XrTrapsGrowBy(traps, XR_TRAPS_GROWTH_INC);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
trap = &traps->xtraps[traps->num_xtraps];
|
||||
|
|
@ -119,9 +103,11 @@ _XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
trap->right = right;
|
||||
|
||||
traps->num_xtraps++;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
|
|
@ -135,10 +121,10 @@ _XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
right.p1 = right_p1;
|
||||
right.p2 = right_p2;
|
||||
|
||||
_XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
return _XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
}
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrTrapsGrowBy(XrTraps *traps, int additional)
|
||||
{
|
||||
XTrapezoid *new_xtraps;
|
||||
|
|
@ -146,18 +132,20 @@ _XrTrapsGrowBy(XrTraps *traps, int additional)
|
|||
int new_size = traps->num_xtraps + additional;
|
||||
|
||||
if (new_size <= traps->xtraps_size) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
traps->xtraps_size = new_size;
|
||||
new_xtraps = realloc(traps->xtraps, traps->xtraps_size * sizeof(XTrapezoid));
|
||||
|
||||
if (new_xtraps) {
|
||||
traps->xtraps = new_xtraps;
|
||||
} else {
|
||||
/* XXX: BUG: How do we really want to handle this out of memory error? */
|
||||
if (new_xtraps == NULL) {
|
||||
traps->xtraps_size = old_size;
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
|
||||
traps->xtraps = new_xtraps;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -172,20 +160,36 @@ _ComparePointFixedByY (const void *v1, const void *v2)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4])
|
||||
{
|
||||
XrError err;
|
||||
|
||||
qsort(q, 4, sizeof(XPointFixed), _ComparePointFixedByY);
|
||||
|
||||
if (q[1].x > q[2].x) {
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -241,11 +245,12 @@ _ComputeIntersect (XLineFixed *l1, XLineFixed *l2)
|
|||
return XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellatePolygon (XrTraps *traps,
|
||||
XrPolygon *poly,
|
||||
int winding)
|
||||
{
|
||||
XrError err;
|
||||
int inactive;
|
||||
XrEdge *active;
|
||||
XrEdge *e, *en, *ep, *next;
|
||||
|
|
@ -254,7 +259,7 @@ XrTrapsTessellatePolygon (XrTraps *traps,
|
|||
XrEdge *edges = poly->edges;
|
||||
|
||||
if (num_edges == 0)
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
|
||||
qsort (edges, num_edges, sizeof (XrEdge), _CompareXrEdgeByTop);
|
||||
|
||||
|
|
@ -384,7 +389,9 @@ XrTrapsTessellatePolygon (XrTraps *traps,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
_XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
err = _XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
y = next_y;
|
||||
|
|
@ -404,4 +411,5 @@ XrTrapsTessellatePolygon (XrTraps *traps,
|
|||
}
|
||||
}
|
||||
}
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
|
|
|||
95
xr.c
95
xr.c
|
|
@ -40,7 +40,11 @@ XrDestroy(XrState *xrs)
|
|||
void
|
||||
XrSave(XrState *xrs)
|
||||
{
|
||||
XrStatePush(xrs);
|
||||
XrError err;
|
||||
|
||||
err = XrStatePush(xrs);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -136,43 +140,114 @@ XrNewPath(XrState *xrs)
|
|||
void
|
||||
XrMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
XrError err;
|
||||
XPointDouble pt[3];
|
||||
|
||||
pt[0].x = x1; pt[0].y = y1;
|
||||
pt[1].x = x2; pt[1].y = y2;
|
||||
pt[2].x = x3; pt[2].y = y3;
|
||||
|
||||
err = XrGStateAddPathOp(CURRENT_GSTATE(xrs), XrPathOpCurveTo, pt, 3);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrRelMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrRelLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelLineTo, x, y);
|
||||
XrError err;
|
||||
|
||||
err = XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelLineTo, x, y);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrRelCurveTo(XrState *xrs,
|
||||
double x1, double y1,
|
||||
double x2, double y2,
|
||||
double x3, double y3)
|
||||
{
|
||||
XrError err;
|
||||
XPointDouble pt[3];
|
||||
|
||||
pt[0].x = x1; pt[0].y = y1;
|
||||
pt[1].x = x2; pt[1].y = y2;
|
||||
pt[2].x = x3; pt[2].y = y3;
|
||||
|
||||
err = XrGStateAddPathOp(CURRENT_GSTATE(xrs), XrPathOpRelCurveTo, pt, 3);
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrClosePath(XrState *xrs)
|
||||
{
|
||||
XrGStateClosePath(CURRENT_GSTATE(xrs));
|
||||
XrError err;
|
||||
|
||||
err = XrGStateClosePath(CURRENT_GSTATE(xrs));
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrStroke(XrState *xrs)
|
||||
{
|
||||
XrGStateStroke(CURRENT_GSTATE(xrs));
|
||||
XrError err;
|
||||
|
||||
if (xrs->error)
|
||||
return;
|
||||
|
||||
err = XrGStateStroke(CURRENT_GSTATE(xrs));
|
||||
if (err)
|
||||
xrs->error = err;
|
||||
}
|
||||
|
||||
void
|
||||
XrFill(XrState *xrs)
|
||||
{
|
||||
XrClosePath(xrs);
|
||||
XrGStateFill(CURRENT_GSTATE(xrs));
|
||||
}
|
||||
XrError err;
|
||||
|
||||
if (xrs->error)
|
||||
return;
|
||||
|
||||
XrClosePath(xrs);
|
||||
|
||||
err = XrGStateFill(CURRENT_GSTATE(xrs));
|
||||
if (err) {
|
||||
xrs->error = err;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
116
xrgstate.c
116
xrgstate.c
|
|
@ -28,23 +28,16 @@
|
|||
|
||||
#include "xrint.h"
|
||||
|
||||
/* Private functions */
|
||||
static XrGState *
|
||||
_XrGStateAlloc(void);
|
||||
|
||||
static XrGState *
|
||||
_XrGStateAlloc(void)
|
||||
{
|
||||
return malloc(sizeof(XrGState));
|
||||
}
|
||||
|
||||
XrGState *
|
||||
XrGStateCreate(Display *dpy)
|
||||
{
|
||||
XrGState *gstate;
|
||||
|
||||
gstate = _XrGStateAlloc();
|
||||
XrGStateInit(gstate, dpy);
|
||||
gstate = malloc(sizeof(XrGState));
|
||||
|
||||
if (gstate) {
|
||||
XrGStateInit(gstate, dpy);
|
||||
}
|
||||
|
||||
return gstate;
|
||||
}
|
||||
|
|
@ -78,7 +71,7 @@ XrGStateInit(XrGState *gstate, Display *dpy)
|
|||
XrPathInit(&gstate->path);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateInitCopy(XrGState *gstate, XrGState *other)
|
||||
{
|
||||
*gstate = *other;
|
||||
|
|
@ -86,7 +79,7 @@ XrGStateInitCopy(XrGState *gstate, XrGState *other)
|
|||
XrSurfaceInit(&gstate->src, gstate->dpy);
|
||||
XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
|
||||
|
||||
XrPathInitCopy(&gstate->path, &other->path);
|
||||
return XrPathInitCopy(&gstate->path, &other->path);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -111,11 +104,18 @@ XrGStateDestroy(XrGState *gstate)
|
|||
XrGState*
|
||||
XrGStateClone(XrGState *gstate)
|
||||
{
|
||||
XrError err;
|
||||
XrGState *clone;
|
||||
|
||||
clone = _XrGStateAlloc();
|
||||
clone = malloc(sizeof(XrGState));
|
||||
if (clone) {
|
||||
err = XrGStateInitCopy(clone, gstate);
|
||||
if (err) {
|
||||
free(clone);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
XrGStateInitCopy(clone, gstate);
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
|
@ -223,44 +223,69 @@ XrGStateNewPath(XrGState *gstate)
|
|||
XrPathDeinit(&gstate->path);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
|
||||
XrError
|
||||
XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts)
|
||||
{
|
||||
XPointDouble pt;
|
||||
XPointFixed pt_fixed;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
int i;
|
||||
XrError err;
|
||||
XPointFixed *pt_fixed;
|
||||
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
case XrPathOpLineTo:
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
for (i=0; i < num_pts; i++) {
|
||||
XrTransformPoint(&gstate->ctm, &pt[i]);
|
||||
}
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
case XrPathOpRelLineTo:
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
for (i=0; i < num_pts; i++) {
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Invalid */
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
pt_fixed.x = XDoubleToFixed(pt.x);
|
||||
pt_fixed.y = XDoubleToFixed(pt.y);
|
||||
pt_fixed = malloc(num_pts * sizeof(XPointFixed));
|
||||
if (pt_fixed == NULL) {
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
|
||||
XrPathAdd(&gstate->path, op, &pt_fixed, 1);
|
||||
for (i=0; i < num_pts; i++) {
|
||||
pt_fixed[i].x = XDoubleToFixed(pt[i].x);
|
||||
pt_fixed[i].y = XDoubleToFixed(pt[i].y);
|
||||
}
|
||||
|
||||
err = XrPathAdd(&gstate->path, op, pt_fixed, num_pts);
|
||||
|
||||
free(pt_fixed);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
|
||||
{
|
||||
XPointDouble pt;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
return XrGStateAddPathOp(gstate, op, &pt, 1);
|
||||
}
|
||||
|
||||
XrError
|
||||
XrGStateClosePath(XrGState *gstate)
|
||||
{
|
||||
XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
|
||||
return XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateStroke(XrGState *gstate)
|
||||
{
|
||||
XrError err;
|
||||
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge, XrStrokerDoneSubPath };
|
||||
|
||||
XrStroker stroker;
|
||||
|
|
@ -269,7 +294,9 @@ XrGStateStroke(XrGState *gstate)
|
|||
XrStrokerInit(&stroker, gstate, &traps);
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &stroker);
|
||||
err = XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &stroker);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
|
|
@ -282,21 +309,34 @@ XrGStateStroke(XrGState *gstate)
|
|||
XrStrokerDeinit(&stroker);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateFill(XrGState *gstate)
|
||||
{
|
||||
XrError err;
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge, XrPolygonDoneSubPath };
|
||||
|
||||
XrPolygon polygon;
|
||||
XrTraps traps;
|
||||
|
||||
XrPolygonInit(&polygon);
|
||||
|
||||
err = XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &polygon);
|
||||
if (err) {
|
||||
XrPolygonDeinit(&polygon);
|
||||
return err;
|
||||
}
|
||||
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &polygon);
|
||||
XrTrapsTessellatePolygon(&traps, &polygon, gstate->fill_style.winding);
|
||||
err = XrTrapsTessellatePolygon(&traps, &polygon, gstate->fill_style.winding);
|
||||
if (err) {
|
||||
XrTrapsDeinit(&traps);
|
||||
return err;
|
||||
}
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
|
|
@ -309,5 +349,7 @@ XrGStateFill(XrGState *gstate)
|
|||
XrPolygonDeinit(&polygon);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
59
xrint.h
59
xrint.h
|
|
@ -42,11 +42,18 @@
|
|||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
typedef enum _XrError {
|
||||
XrErrorSuccess = 0,
|
||||
XrErrorNoMemory
|
||||
} XrError;
|
||||
|
||||
typedef enum _XrPathOp {
|
||||
XrPathOpMoveTo,
|
||||
XrPathOpLineTo,
|
||||
XrPathOpCurveTo,
|
||||
XrPathOpRelMoveTo,
|
||||
XrPathOpRelLineTo,
|
||||
XrPathOpRelCurveTo,
|
||||
XrPathOpClosePath
|
||||
} __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */
|
||||
|
||||
|
|
@ -61,8 +68,8 @@ typedef enum _XrSubPathDone {
|
|||
} XrSubPathDone;
|
||||
|
||||
typedef struct _XrPathCallbacks {
|
||||
void (*AddEdge)(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
void (*DoneSubPath) (void *closure, XrSubPathDone done);
|
||||
XrError (*AddEdge)(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
XrError (*DoneSubPath) (void *closure, XrSubPathDone done);
|
||||
} XrPathCallbacks;
|
||||
|
||||
#define XR_PATH_BUF_SZ 64
|
||||
|
|
@ -184,6 +191,7 @@ typedef struct _XrGState {
|
|||
struct _XrState {
|
||||
Display *dpy;
|
||||
XrGState *stack;
|
||||
XrError error;
|
||||
};
|
||||
|
||||
typedef struct _XrStrokeFace {
|
||||
|
|
@ -208,7 +216,7 @@ typedef struct _XrStroker {
|
|||
XrState *
|
||||
XrStateCreate(Display *dpy);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStateInit(XrState *state, Display *dpy);
|
||||
|
||||
void
|
||||
|
|
@ -217,7 +225,7 @@ XrStateDeinit(XrState *xrs);
|
|||
void
|
||||
XrStateDestroy(XrState *state);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStatePush(XrState *xrs);
|
||||
|
||||
void
|
||||
|
|
@ -230,7 +238,7 @@ XrGStateCreate(Display *dpy);
|
|||
void
|
||||
XrGStateInit(XrGState *gstate, Display *dpy);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateInitCopy(XrGState *gstate, XrGState *other);
|
||||
|
||||
void
|
||||
|
|
@ -284,16 +292,19 @@ XrGStateRotate(XrGState *gstate, double angle);
|
|||
void
|
||||
XrGStateNewPath(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts);
|
||||
|
||||
XrError
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateClosePath(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateStroke(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrGStateFill(XrGState *fill);
|
||||
|
||||
/* xrcolor.c */
|
||||
|
|
@ -310,25 +321,19 @@ void
|
|||
XrColorSetAlpha(XrColor *color, double alpha);
|
||||
|
||||
/* xrpath.c */
|
||||
XrPath *
|
||||
XrPathCreate(void);
|
||||
|
||||
void
|
||||
XrPathInit(XrPath *path);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInitCopy(XrPath *path, XrPath *other);
|
||||
|
||||
void
|
||||
XrPathDeinit(XrPath *path);
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
|
||||
|
||||
/* xrsurface.c */
|
||||
|
|
@ -357,10 +362,10 @@ XrPolygonInit(XrPolygon *poly);
|
|||
void
|
||||
XrPolygonDeinit(XrPolygon *poly);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done);
|
||||
|
||||
/* xrstroke.c */
|
||||
|
|
@ -370,10 +375,10 @@ XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps);
|
|||
void
|
||||
XrStrokerDeinit(XrStroker *stroker);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerDoneSubPath (void *closure, XrSubPathDone done);
|
||||
|
||||
/* xrtransform.c */
|
||||
|
|
@ -420,22 +425,16 @@ void
|
|||
XrTransformPoint(XrTransform *transform, XPointDouble *pt);
|
||||
|
||||
/* xrtraps.c */
|
||||
XrTraps *
|
||||
XrTrapsCreate(void);
|
||||
|
||||
void
|
||||
XrTrapsInit(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrTrapsDeinit(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrTrapsDestroy(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4]);
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellatePolygon (XrTraps *traps, XrPolygon *poly, int winding);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
124
xrpath.c
124
xrpath.c
|
|
@ -30,48 +30,37 @@
|
|||
static void
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewOpBuf(XrPath *path);
|
||||
|
||||
static void
|
||||
_XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg);
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewArgBuf(XrPath *path);
|
||||
|
||||
XrPathOpBuf *
|
||||
static XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *buf);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op);
|
||||
|
||||
XrPathArgBuf *
|
||||
static XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *buf);
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
|
||||
|
||||
static void
|
||||
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
|
||||
XrPath *
|
||||
XrPathCreate(void)
|
||||
{
|
||||
XrPath *path;
|
||||
|
||||
path = malloc(sizeof(XrPath));
|
||||
XrPathInit(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInit(XrPath *path)
|
||||
{
|
||||
|
|
@ -82,7 +71,7 @@ XrPathInit(XrPath *path)
|
|||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInitCopy(XrPath *path, XrPath *other)
|
||||
{
|
||||
XrPathOpBuf *op, *other_op;
|
||||
|
|
@ -92,15 +81,23 @@ XrPathInitCopy(XrPath *path, XrPath *other)
|
|||
|
||||
for (other_op = other->op_head; other_op; other_op = other_op->next) {
|
||||
op = _XrPathOpBufCreate();
|
||||
if (op == NULL) {
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
*op = *other_op;
|
||||
_XrPathAddOpBuf(path, op);
|
||||
}
|
||||
|
||||
for (other_arg = other->arg_head; other_arg; other_arg = other_arg->next) {
|
||||
arg = _XrPathArgBufCreate();
|
||||
if (arg == NULL) {
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
*arg = *other_arg;
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
}
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -124,13 +121,6 @@ XrPathDeinit(XrPath *path)
|
|||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path)
|
||||
{
|
||||
XrPathDeinit(path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
|
||||
{
|
||||
|
|
@ -146,13 +136,18 @@ _XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
|
|||
path->op_tail = op;
|
||||
}
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewOpBuf(XrPath *path)
|
||||
{
|
||||
XrPathOpBuf *op;
|
||||
|
||||
op = _XrPathOpBufCreate();
|
||||
if (op == NULL)
|
||||
return XrErrorNoMemory;
|
||||
|
||||
_XrPathAddOpBuf(path, op);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -170,77 +165,95 @@ _XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg)
|
|||
path->arg_tail = arg;
|
||||
}
|
||||
|
||||
void
|
||||
static XrError
|
||||
_XrPathNewArgBuf(XrPath *path)
|
||||
{
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
arg = _XrPathArgBufCreate();
|
||||
|
||||
if (arg == NULL)
|
||||
return XrErrorNoMemory;
|
||||
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
XrError err;
|
||||
|
||||
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewOpBuf(path);
|
||||
err = _XrPathNewOpBuf(path);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
_XrPathOpBufAdd(path->op_tail, op);
|
||||
|
||||
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewArgBuf(path);
|
||||
err = _XrPathNewArgBuf(path);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
XrPathOpBuf *
|
||||
static XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void)
|
||||
{
|
||||
XrPathOpBuf *op;
|
||||
|
||||
op = malloc(sizeof(XrPathOpBuf));
|
||||
|
||||
op->num_ops = 0;
|
||||
op->next = NULL;
|
||||
if (op) {
|
||||
op->num_ops = 0;
|
||||
op->next = NULL;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *op)
|
||||
{
|
||||
op->num_ops = 0;
|
||||
free(op);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op)
|
||||
{
|
||||
op_buf->op[op_buf->num_ops++] = op;
|
||||
}
|
||||
|
||||
XrPathArgBuf *
|
||||
static XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void)
|
||||
{
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
arg = malloc(sizeof(XrPathArgBuf));
|
||||
|
||||
arg->num_pts = 0;
|
||||
arg->next = NULL;
|
||||
if (arg) {
|
||||
arg->num_pts = 0;
|
||||
arg->next = NULL;
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *arg)
|
||||
{
|
||||
arg->num_pts = 0;
|
||||
free(arg);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -287,9 +300,10 @@ _TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
|
|||
} \
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure)
|
||||
{
|
||||
XrError err;
|
||||
int i;
|
||||
XrPathOpBuf *op_buf;
|
||||
XrPathOp op;
|
||||
|
|
@ -322,8 +336,11 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
if (has_edge)
|
||||
(*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (has_edge) {
|
||||
err = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
|
|
@ -337,7 +354,9 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
err = (*cb->AddEdge)(closure, ¤t, &pt);
|
||||
if (err)
|
||||
return err;
|
||||
current = pt;
|
||||
has_edge = 1;
|
||||
} else {
|
||||
|
|
@ -347,8 +366,11 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
}
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
if (has_edge)
|
||||
(*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (has_edge) {
|
||||
err = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
|
|
@ -364,7 +386,9 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
END_ARGS(1);
|
||||
_TranslatePointFixed(&pt, ¤t);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
err = (*cb->AddEdge)(closure, ¤t, &pt);
|
||||
if (err)
|
||||
return err;
|
||||
current = pt;
|
||||
has_edge = 1;
|
||||
} else {
|
||||
|
|
@ -388,4 +412,6 @@ XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *cl
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
|
|
|||
31
xrpolygon.c
31
xrpolygon.c
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional);
|
||||
|
||||
void
|
||||
|
|
@ -52,7 +52,7 @@ XrPolygonDeinit(XrPolygon *poly)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional)
|
||||
{
|
||||
XrEdge *new_edges;
|
||||
|
|
@ -60,33 +60,39 @@ _XrPolygonGrowBy(XrPolygon *poly, int additional)
|
|||
int new_size = poly->num_edges + additional;
|
||||
|
||||
if (new_size <= poly->edges_size) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
poly->edges_size = new_size;
|
||||
new_edges = realloc(poly->edges, poly->edges_size * sizeof(XrEdge));
|
||||
|
||||
if (new_edges) {
|
||||
poly->edges = new_edges;
|
||||
} else {
|
||||
/* XXX: BUG: How do we really want to handle this out of memory error? */
|
||||
if (new_edges == NULL) {
|
||||
poly->edges_size = old_size;
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
|
||||
poly->edges = new_edges;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrError err;
|
||||
XrEdge *edge;
|
||||
XrPolygon *poly = closure;
|
||||
|
||||
/* drop horizontal edges */
|
||||
if (p1->y == p2->y) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
if (poly->num_edges >= poly->edges_size) {
|
||||
_XrPolygonGrowBy(poly, XR_POLYGON_GROWTH_INC);
|
||||
err = _XrPolygonGrowBy(poly, XR_POLYGON_GROWTH_INC);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
edge = &poly->edges[poly->num_edges];
|
||||
|
|
@ -101,10 +107,13 @@ XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
}
|
||||
|
||||
poly->num_edges++;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
22
xrstate.c
22
xrstate.c
|
|
@ -29,21 +29,30 @@
|
|||
XrState *
|
||||
XrStateCreate(Display *dpy)
|
||||
{
|
||||
XrError err;
|
||||
XrState *xrs;
|
||||
|
||||
xrs = malloc(sizeof(XrState));
|
||||
|
||||
XrStateInit(xrs, dpy);
|
||||
if (xrs) {
|
||||
err = XrStateInit(xrs, dpy);
|
||||
if (err) {
|
||||
free(xrs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return xrs;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStateInit(XrState *xrs, Display *dpy)
|
||||
{
|
||||
xrs->dpy = dpy;
|
||||
xrs->stack = NULL;
|
||||
XrStatePush(xrs);
|
||||
xrs->error = XrErrorSuccess;
|
||||
|
||||
return XrStatePush(xrs);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -61,7 +70,7 @@ XrStateDestroy(XrState *xrs)
|
|||
free(xrs);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStatePush(XrState *xrs)
|
||||
{
|
||||
XrGState *top;
|
||||
|
|
@ -72,8 +81,13 @@ XrStatePush(XrState *xrs)
|
|||
top = XrGStateCreate(xrs->dpy);
|
||||
}
|
||||
|
||||
if (top == NULL)
|
||||
return XrErrorNoMemory;
|
||||
|
||||
top->next = xrs->stack;
|
||||
xrs->stack = top;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
92
xrstroker.c
92
xrstroker.c
|
|
@ -29,6 +29,12 @@
|
|||
static void
|
||||
_TranslatePoint(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
static int
|
||||
_XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out);
|
||||
|
||||
static XrError
|
||||
_XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out);
|
||||
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps)
|
||||
{
|
||||
|
|
@ -51,7 +57,7 @@ _TranslatePoint(XPointFixed *pt, XPointFixed *offset)
|
|||
}
|
||||
|
||||
static int
|
||||
XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
||||
_XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XPointFixed d_in, d_out;
|
||||
|
||||
|
|
@ -63,11 +69,12 @@ XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
|||
return d_out.y * d_in.x > d_in.y * d_out.x;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
||||
static XrError
|
||||
_XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XrError err;
|
||||
XrGState *gstate = stroker->gstate;
|
||||
int clockwise = XrStrokerFaceClockwise (in, out);
|
||||
int clockwise = _XrStrokerFaceClockwise (in, out);
|
||||
XrPolygon polygon;
|
||||
XPointFixed *inpt, *outpt;
|
||||
|
||||
|
|
@ -129,18 +136,22 @@ XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
|||
break;
|
||||
}
|
||||
}
|
||||
XrTrapsTessellatePolygon (stroker->traps, &polygon, 1);
|
||||
|
||||
err = XrTrapsTessellatePolygon (stroker->traps, &polygon, 1);
|
||||
XrPolygonDeinit (&polygon);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerCap(XrStroker *stroker, XrStrokeFace *f)
|
||||
static void
|
||||
_XrStrokerCap(XrStroker *stroker, XrStrokeFace *f)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrError err;
|
||||
XrStroker *stroker = closure;
|
||||
XrGState *gstate = stroker->gstate;
|
||||
XrStrokeStyle *style = &gstate->stroke_style;
|
||||
|
|
@ -159,7 +170,7 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
|
||||
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
|
||||
if (mag == 0) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
vector.x /= mag;
|
||||
|
|
@ -195,9 +206,11 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
face.ccw = quad[1];
|
||||
face.vector = user_vector;
|
||||
|
||||
if (stroker->have_prev)
|
||||
XrStrokerJoin (stroker, &stroker->prev, &face);
|
||||
else {
|
||||
if (stroker->have_prev) {
|
||||
err = _XrStrokerJoin (stroker, &stroker->prev, &face);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
stroker->have_prev = 1;
|
||||
stroker->first = face;
|
||||
}
|
||||
|
|
@ -207,63 +220,26 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
stroker->prev.cw = quad[3];
|
||||
stroker->prev.vector = user_vector;
|
||||
|
||||
XrTrapsTessellateRectangle(traps, quad);
|
||||
return XrTrapsTessellateRectangle(traps, quad);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrStrokerDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
XrError err;
|
||||
XrStroker *stroker = closure;
|
||||
|
||||
switch (done) {
|
||||
case XrSubPathDoneCap:
|
||||
XrStrokerCap (stroker, &stroker->first);
|
||||
XrStrokerCap (stroker, &stroker->prev);
|
||||
_XrStrokerCap (stroker, &stroker->first);
|
||||
_XrStrokerCap (stroker, &stroker->prev);
|
||||
break;
|
||||
case XrSubPathDoneJoin:
|
||||
XrStrokerJoin (stroker, &stroker->prev, &stroker->first);
|
||||
err = _XrStrokerJoin (stroker, &stroker->prev, &stroker->first);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* These functions aren't written yet... */
|
||||
#if 0
|
||||
static void
|
||||
_XrGStateStrokerCap(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_cap) {
|
||||
case XrLineCapRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapSquare:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapButt:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokerJoin(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2, const XPointDouble *p3,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_join) {
|
||||
case XrLineJoinMiter:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinBevel:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
94
xrtraps.c
94
xrtraps.c
|
|
@ -30,14 +30,14 @@
|
|||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrTrapsGrowBy(XrTraps *traps, int additional);
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right);
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
|
|
@ -60,18 +60,6 @@ _ComputeXIntercept (XLineFixed *l, double inverse_slope);
|
|||
static XFixed
|
||||
_ComputeIntersect (XLineFixed *l1, XLineFixed *l2);
|
||||
|
||||
XrTraps *
|
||||
XrTrapsCreate(void)
|
||||
{
|
||||
XrTraps *traps;
|
||||
|
||||
traps = Xmalloc(sizeof(XrTraps));
|
||||
|
||||
XrTrapsInit(traps);
|
||||
|
||||
return traps;
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsInit(XrTraps *traps)
|
||||
{
|
||||
|
|
@ -91,25 +79,21 @@ XrTrapsDeinit(XrTraps *traps)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsDestroy(XrTraps *traps)
|
||||
{
|
||||
XrTrapsDeinit(traps);
|
||||
Xfree(traps);
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right)
|
||||
{
|
||||
XrError err;
|
||||
XTrapezoid *trap;
|
||||
|
||||
if (top == bottom) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
if (traps->num_xtraps >= traps->xtraps_size) {
|
||||
_XrTrapsGrowBy(traps, XR_TRAPS_GROWTH_INC);
|
||||
err = _XrTrapsGrowBy(traps, XR_TRAPS_GROWTH_INC);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
trap = &traps->xtraps[traps->num_xtraps];
|
||||
|
|
@ -119,9 +103,11 @@ _XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
trap->right = right;
|
||||
|
||||
traps->num_xtraps++;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
|
|
@ -135,10 +121,10 @@ _XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
right.p1 = right_p1;
|
||||
right.p2 = right_p2;
|
||||
|
||||
_XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
return _XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
}
|
||||
|
||||
static void
|
||||
static XrError
|
||||
_XrTrapsGrowBy(XrTraps *traps, int additional)
|
||||
{
|
||||
XTrapezoid *new_xtraps;
|
||||
|
|
@ -146,18 +132,20 @@ _XrTrapsGrowBy(XrTraps *traps, int additional)
|
|||
int new_size = traps->num_xtraps + additional;
|
||||
|
||||
if (new_size <= traps->xtraps_size) {
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
traps->xtraps_size = new_size;
|
||||
new_xtraps = realloc(traps->xtraps, traps->xtraps_size * sizeof(XTrapezoid));
|
||||
|
||||
if (new_xtraps) {
|
||||
traps->xtraps = new_xtraps;
|
||||
} else {
|
||||
/* XXX: BUG: How do we really want to handle this out of memory error? */
|
||||
if (new_xtraps == NULL) {
|
||||
traps->xtraps_size = old_size;
|
||||
return XrErrorNoMemory;
|
||||
}
|
||||
|
||||
traps->xtraps = new_xtraps;
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -172,20 +160,36 @@ _ComparePointFixedByY (const void *v1, const void *v2)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4])
|
||||
{
|
||||
XrError err;
|
||||
|
||||
qsort(q, 4, sizeof(XPointFixed), _ComparePointFixedByY);
|
||||
|
||||
if (q[1].x > q[2].x) {
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
if (err)
|
||||
return err;
|
||||
err = _XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -241,11 +245,12 @@ _ComputeIntersect (XLineFixed *l1, XLineFixed *l2)
|
|||
return XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
}
|
||||
|
||||
void
|
||||
XrError
|
||||
XrTrapsTessellatePolygon (XrTraps *traps,
|
||||
XrPolygon *poly,
|
||||
int winding)
|
||||
{
|
||||
XrError err;
|
||||
int inactive;
|
||||
XrEdge *active;
|
||||
XrEdge *e, *en, *ep, *next;
|
||||
|
|
@ -254,7 +259,7 @@ XrTrapsTessellatePolygon (XrTraps *traps,
|
|||
XrEdge *edges = poly->edges;
|
||||
|
||||
if (num_edges == 0)
|
||||
return;
|
||||
return XrErrorSuccess;
|
||||
|
||||
qsort (edges, num_edges, sizeof (XrEdge), _CompareXrEdgeByTop);
|
||||
|
||||
|
|
@ -384,7 +389,9 @@ XrTrapsTessellatePolygon (XrTraps *traps,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
_XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
err = _XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
y = next_y;
|
||||
|
|
@ -404,4 +411,5 @@ XrTrapsTessellatePolygon (XrTraps *traps,
|
|||
}
|
||||
}
|
||||
}
|
||||
return XrErrorSuccess;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue