Moved current point state to XrGState and dropped relative operators from XrPath. This is all in preparation for XrShowText, (which needs access to the current point)

This commit is contained in:
Carl Worth 2002-10-26 07:59:31 +00:00
parent 0b6fd5b4d1
commit 06ddeffeb7
19 changed files with 1026 additions and 539 deletions

View file

@ -1,13 +1,64 @@
2002-10-24 Carl Worth <cworth@brudder>
2002-10-26 Carl Worth <cworth@isi.edu>
* xrtransform.c (_XrTransformDistance):
(_XrTransformPoint): changed to use individual X/Y arguments
rather tha an XPointDouble. This improves readability since
_XrTransformDistance is now always called with arguments of dx/dy
rather than pt.x/pt.y.
* xrpath.c (_XrPathMoveTo):
(_XrPathLineTo):
(_XrPathCurveTo):
(_XrPathClosePath): replaced public _XrPathAdd with explicit named
functions. This cleans up the implementation since _XrPathAdd,
which is unsafe with respect to argument consistency, is now
private. Also, since the _XrGState now maintains the current
point, I dropped all relative path operators from the XrPath data
structures.
* xrgstate.c (_XrGStateMoveTo):
(_XrGStateLineTo):
(_XrGStateCurveTo):
(_XrGStateRelMoveTo):
(_XrGStateRelLineTo):
(_XrGStateRelCurveTo): Replaces _XrGStateAddPathOp and
_XrGStateAddUnaryPathOp with explicit named functions for each
operator type. This change introduces the current point state into
the XrGState structure rather than postponing its calculation
until path interpretation.
* xrgstate.c (_XrGStateSetDrawable):
(_XrGStateSetVisual):
(_XrGStateSetFormat):
(_XrGStateSetOperator):
(_XrGStateSetRGBColor):
(_XrGStateSetTolerance):
(_XrGStateSetAlpha):
(_XrGStateSetFillRule):
(_XrGStateSetLineWidth):
(_XrGStateSetLineCap):
(_XrGStateSetLineJoin):
(_XrGStateSetMiterLimit):
(_XrGStateTranslate):
(_XrGStateScale):
(_XrGStateRotate):
(_XrGStateConcatMatrix):
(_XrGStateNewPath): : Added XrStatus return values to many
functions -- just for consistency, these functions can not return
errors in any case.
* xr.c (XrShowText): Started to ass XrShowText, (still not functional)
2002-10-24 Carl Worth <cworth@isi.edu>
* xr.c (XrSetFillRule): Added support to set fill rule.
2002-10-23 Carl Worth <cworth@brudder>
2002-10-23 Carl Worth <cworth@isi.edu>
* xrtraps.c (_XrTrapsTessellatePolygon): Fix for polygon with
multiple sub-polygons that are disjoint in Y.
2002-07-16 Carl Worth <cworth@brudder>
2002-07-16 Carl Worth <cworth@isi.edu>
* Xr.h: Renamed xrpicture.c to xrsurface.c as part of the move.
Added XrSetFormat, XrSetOperator, XrSetLineCap, XrSetLineJoin, and

8
Xr.h
View file

@ -154,7 +154,7 @@ XrConcatMatrix(XrState *xrs,
double c, double d,
double tx, double ty);
/* Path creation */
/* Path creation functions */
void
XrNewPath(XrState *xrs);
@ -185,13 +185,17 @@ XrRelCurveTo(XrState *xrs,
void
XrClosePath(XrState *xrs);
/* Render current path */
/* Painting functions */
void
XrStroke(XrState *xrs);
void
XrFill(XrState *xrs);
/* Text functions */
void
XrShowText(XrState *xrs, const char *utf8);
/* Error status queries */
typedef enum _XrStatus {

View file

@ -154,7 +154,7 @@ XrConcatMatrix(XrState *xrs,
double c, double d,
double tx, double ty);
/* Path creation */
/* Path creation functions */
void
XrNewPath(XrState *xrs);
@ -185,13 +185,17 @@ XrRelCurveTo(XrState *xrs,
void
XrClosePath(XrState *xrs);
/* Render current path */
/* Painting functions */
void
XrStroke(XrState *xrs);
void
XrFill(XrState *xrs);
/* Text functions */
void
XrShowText(XrState *xrs, const char *utf8);
/* Error status queries */
typedef enum _XrStatus {

192
src/xr.c
View file

@ -47,11 +47,10 @@ XrDestroy(XrState *xrs)
void
XrSave(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrStatePush(xrs);
if (status)
xrs->status = status;
xrs->status = _XrStatePush(xrs);
}
void
@ -60,114 +59,162 @@ XrRestore(XrState *xrs)
/* XXX: BUG: Calling XrRestore without a matching XrSave shoud
flag an error. Also, in order to prevent crashes, XrStatePop
should not be called in that case. */
_XrStatePop(xrs);
if (xrs->status)
return;
xrs->status = _XrStatePop(xrs);
}
void
XrSetDrawable(XrState *xrs, Drawable drawable)
{
_XrGStateSetDrawable(_XR_CURRENT_GSTATE(xrs), drawable);
if (xrs->status)
return;
xrs->status = _XrGStateSetDrawable(_XR_CURRENT_GSTATE(xrs), drawable);
}
void
XrSetVisual(XrState *xrs, Visual *visual)
{
_XrGStateSetVisual(_XR_CURRENT_GSTATE(xrs), visual);
if (xrs->status)
return;
xrs->status = _XrGStateSetVisual(_XR_CURRENT_GSTATE(xrs), visual);
}
void
XrSetFormat(XrState *xrs, XrFormat format)
{
_XrGStateSetFormat(_XR_CURRENT_GSTATE(xrs), format);
if (xrs->status)
return;
xrs->status = _XrGStateSetFormat(_XR_CURRENT_GSTATE(xrs), format);
}
void
XrSetOperator(XrState *xrs, XrOperator operator)
{
_XrGStateSetOperator(_XR_CURRENT_GSTATE(xrs), operator);
if (xrs->status)
return;
xrs->status = _XrGStateSetOperator(_XR_CURRENT_GSTATE(xrs), operator);
}
void
XrSetRGBColor(XrState *xrs, double red, double green, double blue)
{
if (xrs->status)
return;
_XrClipValue(&red, 0.0, 1.0);
_XrClipValue(&green, 0.0, 1.0);
_XrClipValue(&blue, 0.0, 1.0);
_XrGStateSetRGBColor(_XR_CURRENT_GSTATE(xrs), red, green, blue);
xrs->status = _XrGStateSetRGBColor(_XR_CURRENT_GSTATE(xrs), red, green, blue);
}
void
XrSetTolerance(XrState *xrs, double tolerance)
{
if (xrs->status)
return;
_XrClipValue(&tolerance, XR_TOLERANCE_MINIMUM, tolerance);
_XrGStateSetTolerance(_XR_CURRENT_GSTATE(xrs), tolerance);
xrs->status = _XrGStateSetTolerance(_XR_CURRENT_GSTATE(xrs), tolerance);
}
void
XrSetAlpha(XrState *xrs, double alpha)
{
if (xrs->status)
return;
_XrClipValue(&alpha, 0.0, 1.0);
_XrGStateSetAlpha(_XR_CURRENT_GSTATE(xrs), alpha);
xrs->status = _XrGStateSetAlpha(_XR_CURRENT_GSTATE(xrs), alpha);
}
void
XrSetFillRule(XrState *xrs, XrFillRule fill_rule)
{
_XrGStateSetFillRule(_XR_CURRENT_GSTATE(xrs), fill_rule);
if (xrs->status)
return;
xrs->status = _XrGStateSetFillRule(_XR_CURRENT_GSTATE(xrs), fill_rule);
}
void
XrSetLineWidth(XrState *xrs, double width)
{
_XrGStateSetLineWidth(_XR_CURRENT_GSTATE(xrs), width);
if (xrs->status)
return;
xrs->status = _XrGStateSetLineWidth(_XR_CURRENT_GSTATE(xrs), width);
}
void
XrSetLineCap(XrState *xrs, XrLineCap line_cap)
{
_XrGStateSetLineCap(_XR_CURRENT_GSTATE(xrs), line_cap);
if (xrs->status)
return;
xrs->status = _XrGStateSetLineCap(_XR_CURRENT_GSTATE(xrs), line_cap);
}
void
XrSetLineJoin(XrState *xrs, XrLineJoin line_join)
{
_XrGStateSetLineJoin(_XR_CURRENT_GSTATE(xrs), line_join);
if (xrs->status)
return;
xrs->status = _XrGStateSetLineJoin(_XR_CURRENT_GSTATE(xrs), line_join);
}
void
XrSetDash(XrState *xrs, double *dashes, int ndash, double offset)
{
XrStatus status;
status = _XrGStateSetDash(_XR_CURRENT_GSTATE(xrs), dashes, ndash, offset);
if (status)
xrs->status = status;
if (xrs->status)
return;
xrs->status = _XrGStateSetDash(_XR_CURRENT_GSTATE(xrs), dashes, ndash, offset);
}
void
XrSetMiterLimit(XrState *xrs, double limit)
{
_XrGStateSetMiterLimit(_XR_CURRENT_GSTATE(xrs), limit);
if (xrs->status)
return;
xrs->status = _XrGStateSetMiterLimit(_XR_CURRENT_GSTATE(xrs), limit);
}
void
XrTranslate(XrState *xrs, double tx, double ty)
{
_XrGStateTranslate(_XR_CURRENT_GSTATE(xrs), tx, ty);
if (xrs->status)
return;
xrs->status = _XrGStateTranslate(_XR_CURRENT_GSTATE(xrs), tx, ty);
}
void
XrScale(XrState *xrs, double sx, double sy)
{
_XrGStateScale(_XR_CURRENT_GSTATE(xrs), sx, sy);
if (xrs->status)
return;
xrs->status = _XrGStateScale(_XR_CURRENT_GSTATE(xrs), sx, sy);
}
void
XrRotate(XrState *xrs, double angle)
{
_XrGStateRotate(_XR_CURRENT_GSTATE(xrs), angle);
if (xrs->status)
return;
xrs->status = _XrGStateRotate(_XR_CURRENT_GSTATE(xrs), angle);
}
void
@ -176,33 +223,37 @@ XrConcatMatrix(XrState *xrs,
double c, double d,
double tx, double ty)
{
_XrGStateConcatMatrix(_XR_CURRENT_GSTATE(xrs), a, b, c, d, tx, ty);
if (xrs->status)
return;
xrs->status = _XrGStateConcatMatrix(_XR_CURRENT_GSTATE(xrs), a, b, c, d, tx, ty);
}
void
XrNewPath(XrState *xrs)
{
_XrGStateNewPath(_XR_CURRENT_GSTATE(xrs));
if (xrs->status)
return;
xrs->status = _XrGStateNewPath(_XR_CURRENT_GSTATE(xrs));
}
void
XrMoveTo(XrState *xrs, double x, double y)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
if (status)
xrs->status = status;
xrs->status = _XrGStateMoveTo(_XR_CURRENT_GSTATE(xrs), x, y);
}
void
XrLineTo(XrState *xrs, double x, double y)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
if (status)
xrs->status = status;
xrs->status = _XrGStateLineTo(_XR_CURRENT_GSTATE(xrs), x, y);
}
void
@ -211,36 +262,31 @@ XrCurveTo(XrState *xrs,
double x2, double y2,
double x3, double y3)
{
XrStatus status;
XPointDouble pt[3];
if (xrs->status)
return;
pt[0].x = x1; pt[0].y = y1;
pt[1].x = x2; pt[1].y = y2;
pt[2].x = x3; pt[2].y = y3;
status = _XrGStateAddPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpCurveTo, pt, 3);
if (status)
xrs->status = status;
xrs->status = _XrGStateCurveTo(_XR_CURRENT_GSTATE(xrs),
x1, y1,
x2, y2,
x3, y3);
}
void
XrRelMoveTo(XrState *xrs, double dx, double dy)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, dx, dy);
if (status)
xrs->status = status;
xrs->status = _XrGStateRelMoveTo(_XR_CURRENT_GSTATE(xrs), dx, dy);
}
void
XrRelLineTo(XrState *xrs, double dx, double dy)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpRelLineTo, dx, dy);
if (status)
xrs->status = status;
xrs->status = _XrGStateRelLineTo(_XR_CURRENT_GSTATE(xrs), dx, dy);
}
void
@ -249,53 +295,49 @@ XrRelCurveTo(XrState *xrs,
double dx2, double dy2,
double dx3, double dy3)
{
XrStatus status;
XPointDouble pt[3];
if (xrs->status)
return;
pt[0].x = dx1; pt[0].y = dy1;
pt[1].x = dx2; pt[1].y = dy2;
pt[2].x = dx3; pt[2].y = dy3;
status = _XrGStateAddPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpRelCurveTo, pt, 3);
if (status)
xrs->status = status;
xrs->status = _XrGStateRelCurveTo(_XR_CURRENT_GSTATE(xrs),
dx1, dy1,
dx2, dy2,
dx3, dy3);
}
void
XrClosePath(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateClosePath(_XR_CURRENT_GSTATE(xrs));
if (status)
xrs->status = status;
xrs->status = _XrGStateClosePath(_XR_CURRENT_GSTATE(xrs));
}
void
XrStroke(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateStroke(_XR_CURRENT_GSTATE(xrs));
if (status)
xrs->status = status;
xrs->status = _XrGStateStroke(_XR_CURRENT_GSTATE(xrs));
}
void
XrFill(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateFill(_XR_CURRENT_GSTATE(xrs));
if (status) {
xrs->status = status;
}
xrs->status = _XrGStateFill(_XR_CURRENT_GSTATE(xrs));
}
void
XrShowText(XrState *xrs, const char *utf8)
{
if (xrs->status)
return;
xrs->status = _XrGStateShowText(_XR_CURRENT_GSTATE(xrs), utf8);
}
XrStatus

View file

@ -159,72 +159,94 @@ _XrGStateClone(XrGState *gstate)
return clone;
}
void
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
{
_XrSurfaceSetDrawable(&gstate->surface, drawable);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual)
{
_XrSurfaceSetVisual(&gstate->surface, visual);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format)
{
_XrSurfaceSetFormat(&gstate->surface, format);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetOperator(XrGState *gstate, XrOperator operator)
{
gstate->operator = operator;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{
_XrColorSetRGB(&gstate->color, red, green, blue);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetTolerance(XrGState *gstate, double tolerance)
{
gstate->tolerance = tolerance;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha)
{
_XrColorSetAlpha(&gstate->color, alpha);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule)
{
gstate->fill_rule = fill_rule;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetLineWidth(XrGState *gstate, double width)
{
gstate->line_width = width;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap)
{
gstate->line_cap = line_cap;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join)
{
gstate->line_join = line_join;
return XrStatusSuccess;
}
XrStatus
@ -242,16 +264,19 @@ _XrGStateSetDash(XrGState *gstate, double *dashes, int ndash, double offset)
gstate->ndashes = ndash;
memcpy (gstate->dashes, dashes, ndash * sizeof (double));
gstate->dash_offset = offset;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetMiterLimit(XrGState *gstate, double limit)
{
gstate->miter_limit = limit;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty)
{
XrTransform tmp;
@ -261,9 +286,11 @@ _XrGStateTranslate(XrGState *gstate, double tx, double ty)
_XrTransformInitTranslate(&tmp, -tx, -ty);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateScale(XrGState *gstate, double sx, double sy)
{
XrTransform tmp;
@ -273,9 +300,11 @@ _XrGStateScale(XrGState *gstate, double sx, double sy)
_XrTransformInitScale(&tmp, 1/sx, 1/sy);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateRotate(XrGState *gstate, double angle)
{
XrTransform tmp;
@ -285,9 +314,11 @@ _XrGStateRotate(XrGState *gstate, double angle)
_XrTransformInitRotate(&tmp, -angle);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateConcatMatrix(XrGState *gstate,
double a, double b,
double c, double d,
@ -300,72 +331,144 @@ _XrGStateConcatMatrix(XrGState *gstate,
_XrTransformComputeInverse(&tmp);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
}
void
_XrGStateNewPath(XrGState *gstate)
{
_XrPathDeinit(&gstate->path);
return XrStatusSuccess;
}
XrStatus
_XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts)
_XrGStateNewPath(XrGState *gstate)
{
_XrPathDeinit(&gstate->path);
return XrStatusSuccess;
}
XrStatus
_XrGStateMoveTo(XrGState *gstate, double x, double y)
{
int i;
XrStatus status;
XPointFixed *pt_fixed;
switch (op) {
case XrPathOpMoveTo:
case XrPathOpLineTo:
case XrPathOpCurveTo:
for (i=0; i < num_pts; i++) {
_XrTransformPoint(&gstate->ctm, &pt[i]);
}
break;
case XrPathOpRelMoveTo:
case XrPathOpRelLineTo:
case XrPathOpRelCurveTo:
for (i=0; i < num_pts; i++) {
_XrTransformDistance(&gstate->ctm, &pt[i]);
}
break;
case XrPathOpClosePath:
break;
}
_XrTransformPoint(&gstate->ctm, &x, &y);
pt_fixed = malloc(num_pts * sizeof(XPointFixed));
if (pt_fixed == NULL) {
return XrStatusNoMemory;
}
status = _XrPathMoveTo(&gstate->path, x, y);
for (i=0; i < num_pts; i++) {
pt_fixed[i].x = XDoubleToFixed(pt[i].x);
pt_fixed[i].y = XDoubleToFixed(pt[i].y);
}
gstate->current_pt.x = x;
gstate->current_pt.y = y;
status = _XrPathAdd(&gstate->path, op, pt_fixed, num_pts);
free(pt_fixed);
gstate->last_move_pt = gstate->current_pt;
return status;
}
XrStatus
_XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
_XrGStateLineTo(XrGState *gstate, double x, double y)
{
XPointDouble pt;
XrStatus status;
pt.x = x;
pt.y = y;
_XrTransformPoint(&gstate->ctm, &x, &y);
return _XrGStateAddPathOp(gstate, op, &pt, 1);
status = _XrPathLineTo(&gstate->path, x, y);
gstate->current_pt.x = x;
gstate->current_pt.y = y;
return status;
}
XrStatus
_XrGStateCurveTo(XrGState *gstate,
double x1, double y1,
double x2, double y2,
double x3, double y3)
{
XrStatus status;
_XrTransformPoint(&gstate->ctm, &x1, &y1);
_XrTransformPoint(&gstate->ctm, &x2, &y2);
_XrTransformPoint(&gstate->ctm, &x3, &y3);
status = _XrPathCurveTo(&gstate->path,
x1, y1,
x2, y2,
x3, y3);
gstate->current_pt.x = x3;
gstate->current_pt.y = y3;
return status;
}
XrStatus
_XrGStateRelMoveTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathMoveTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
gstate->last_move_pt = gstate->current_pt;
return status;
}
XrStatus
_XrGStateRelLineTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathLineTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
return status;
}
XrStatus
_XrGStateRelCurveTo(XrGState *gstate,
double dx1, double dy1,
double dx2, double dy2,
double dx3, double dy3)
{
XrStatus status;
_XrTransformDistance(&gstate->ctm, &dx1, &dy1);
_XrTransformDistance(&gstate->ctm, &dx2, &dy2);
_XrTransformDistance(&gstate->ctm, &dx3, &dy3);
status = _XrPathCurveTo(&gstate->path,
gstate->current_pt.x + dx1, gstate->current_pt.y + dy1,
gstate->current_pt.x + dx2, gstate->current_pt.y + dy2,
gstate->current_pt.x + dx3, gstate->current_pt.y + dy3);
gstate->current_pt.x += dx3;
gstate->current_pt.y += dy3;
return status;
}
XrStatus
_XrGStateClosePath(XrGState *gstate)
{
return _XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
XrStatus status;
status = _XrPathClosePath(&gstate->path);
gstate->current_pt = gstate->last_move_pt;
return status;
}
XrStatus
@ -456,3 +559,11 @@ _XrGStateFill(XrGState *gstate)
return XrStatusSuccess;
}
XrStatus
_XrGStateShowText(XrGState *gstate, const char *utf8)
{
/* XXX: NYI */
return XrStatusSuccess;
}

View file

@ -53,10 +53,7 @@ typedef enum _XrPathOp {
XrPathOpMoveTo = 0,
XrPathOpLineTo = 1,
XrPathOpCurveTo = 2,
XrPathOpRelMoveTo = 3,
XrPathOpRelLineTo = 4,
XrPathOpRelCurveTo = 5,
XrPathOpClosePath = 6
XrPathOpClosePath = 3
} __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */
typedef enum _XrPathDirection {
@ -238,6 +235,9 @@ typedef struct _XrGState {
XrPath path;
XPointDouble last_move_pt;
XPointDouble current_pt;
XrPen pen_regular;
struct _XrGState *next;
@ -294,7 +294,7 @@ _XrStateDestroy(XrState *state);
XrStatus
_XrStatePush(XrState *xrs);
void
XrStatus
_XrStatePop(XrState *xrs);
/* xrgstate.c */
@ -316,68 +316,86 @@ _XrGStateDestroy(XrGState *gstate);
XrGState *
_XrGStateClone(XrGState *gstate);
void
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable);
void
XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual);
void
XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format);
void
XrStatus
_XrGStateSetOperator(XrGState *gstate, XrOperator operator);
void
XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue);
void
XrStatus
_XrGStateSetTolerance(XrGState *gstate, double tolerance);
void
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha);
void
XrStatus
_XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule);
void
XrStatus
_XrGStateSetLineWidth(XrGState *gstate, double width);
void
XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap);
void
XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join);
XrStatus
_XrGStateSetDash(XrGState *gstate, double *dashes, int ndash, double offset);
void
XrStatus
_XrGStateSetMiterLimit(XrGState *gstate, double limit);
void
XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty);
void
XrStatus
_XrGStateScale(XrGState *gstate, double sx, double sy);
void
XrStatus
_XrGStateRotate(XrGState *gstate, double angle);
void
XrStatus
_XrGStateConcatMatrix(XrGState *gstate,
double a, double b,
double c, double d,
double tx, double ty);
void
XrStatus
_XrGStateNewPath(XrGState *gstate);
XrStatus
_XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts);
_XrGStateMoveTo(XrGState *gstate, double x, double y);
XrStatus
_XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y);
_XrGStateLineTo(XrGState *gstate, double x, double y);
XrStatus
_XrGStateCurveTo(XrGState *gstate,
double x1, double y1,
double x2, double y2,
double x3, double y3);
XrStatus
_XrGStateRelMoveTo(XrGState *gstate, double dx, double dy);
XrStatus
_XrGStateRelLineTo(XrGState *gstate, double dx, double dy);
XrStatus
_XrGStateRelCurveTo(XrGState *gstate,
double dx1, double dy1,
double dx2, double dy2,
double dx3, double dy3);
XrStatus
_XrGStateClosePath(XrGState *gstate);
@ -388,6 +406,9 @@ _XrGStateStroke(XrGState *gstate);
XrStatus
_XrGStateFill(XrGState *fill);
XrStatus
_XrGStateShowText(XrGState *gstate, const char *utf8);
/* xrcolor.c */
void
_XrColorInit(XrColor *color);
@ -412,7 +433,19 @@ void
_XrPathDeinit(XrPath *path);
XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
_XrPathMoveTo(XrPath *path, double x, double y);
XrStatus
_XrPathLineTo(XrPath *path, double x, double y);
XrStatus
_XrPathCurveTo(XrPath *path,
double x1, double y1,
double x2, double y2,
double x3, double y3);
XrStatus
_XrPathClosePath(XrPath *path);
XrStatus
_XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
@ -560,10 +593,10 @@ void
_XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new);
void
_XrTransformDistance(XrTransform *transform, XPointDouble *pt);
_XrTransformDistance(XrTransform *transform, double *dx, double *dy);
void
_XrTransformPoint(XrTransform *transform, XPointDouble *pt);
_XrTransformPoint(XrTransform *transform, double *x, double *y);
void
_XrTransformComputeInverse(XrTransform *transform);

View file

@ -27,6 +27,9 @@
#include "xrint.h"
/* private functions */
static XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
@ -57,10 +60,6 @@ _XrPathArgBufDestroy(XrPathArgBuf *buf);
static void
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
static void
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
void
_XrPathInit(XrPath *path)
{
@ -121,6 +120,76 @@ _XrPathDeinit(XrPath *path)
path->arg_tail = NULL;
}
XrStatus
_XrPathMoveTo(XrPath *path, double x, double y)
{
XPointFixed pt;
pt.x = XDoubleToFixed(x);
pt.y = XDoubleToFixed(y);
return _XrPathAdd(path, XrPathOpMoveTo, &pt, 1);
}
XrStatus
_XrPathLineTo(XrPath *path, double x, double y)
{
XPointFixed pt;
pt.x = XDoubleToFixed(x);
pt.y = XDoubleToFixed(y);
return _XrPathAdd(path, XrPathOpLineTo, &pt, 1);
}
XrStatus
_XrPathCurveTo(XrPath *path,
double x1, double y1,
double x2, double y2,
double x3, double y3)
{
XPointFixed pt[3];
pt[0].x = XDoubleToFixed(x1);
pt[0].y = XDoubleToFixed(y1);
pt[1].x = XDoubleToFixed(x2);
pt[1].y = XDoubleToFixed(y2);
pt[2].x = XDoubleToFixed(x3);
pt[2].y = XDoubleToFixed(y3);
return _XrPathAdd(path, XrPathOpCurveTo, pt, 3);
}
XrStatus
_XrPathClosePath(XrPath *path)
{
return _XrPathAdd(path, XrPathOpClosePath, NULL, 0);
}
static XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
{
XrStatus status;
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
status = _XrPathNewOpBuf(path);
if (status)
return status;
}
_XrPathOpBufAdd(path->op_tail, op);
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
status = _XrPathNewArgBuf(path);
if (status)
return status;
}
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
return XrStatusSuccess;
}
static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
{
@ -180,29 +249,6 @@ _XrPathNewArgBuf(XrPath *path)
return XrStatusSuccess;
}
XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
{
XrStatus status;
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
status = _XrPathNewOpBuf(path);
if (status)
return status;
}
_XrPathOpBufAdd(path->op_tail, op);
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
status = _XrPathNewArgBuf(path);
if (status)
return status;
}
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
return XrStatusSuccess;
}
static XrPathOpBuf *
_XrPathOpBufCreate(void)
{
@ -261,13 +307,6 @@ _XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts)
}
}
static void
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
{
pt->x += offset->x;
pt->y += offset->y;
}
#define XR_PATH_OP_MAX_ARGS 3
static int num_args[] =
@ -275,9 +314,6 @@ static int num_args[] =
1, /* XrPathMoveTo */
1, /* XrPathOpLineTo */
3, /* XrPathOpCurveTo */
1, /* XrPathOpRelMoveTo */
1, /* XrPathOpRelLineTo */
3, /* XrPathOpRelCurveTo */
0, /* XrPathOpClosePath */
};
@ -335,9 +371,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
}
switch (op) {
case XrPathOpRelMoveTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpMoveTo:
if (has_edge) {
status = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
@ -349,9 +382,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_current = 1;
has_edge = 0;
break;
case XrPathOpRelLineTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpLineTo:
if (has_current) {
status = (*cb->AddEdge)(closure, &current, &pt[0]);
@ -366,11 +396,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_edge = 0;
}
break;
case XrPathOpRelCurveTo:
for (arg = 0; arg < num_args[op]; arg++) {
_TranslatePointFixed(&pt[arg], &current);
}
/* fall-through */
case XrPathOpCurveTo:
if (has_current) {
status = (*cb->AddSpline)(closure, &current, &pt[0], &pt[1], &pt[2]);

View file

@ -60,7 +60,7 @@ _XrPenInit(XrPen *pen, double radius, XrGState *gstate)
{
int i;
XrPenVertex *v;
XPointDouble pt;
double dx, dy;
if (pen->num_vertices) {
/* XXX: It would be nice to notice that the pen is already properly constructed.
@ -88,11 +88,11 @@ _XrPenInit(XrPen *pen, double radius, XrGState *gstate)
for (i=0; i < pen->num_vertices; i++) {
v = &pen->vertex[i];
v->theta = 2 * M_PI * i / (double) pen->num_vertices;
pt.x = radius * cos(v->theta);
pt.y = radius * sin(v->theta);
_XrTransformDistance(&gstate->ctm, &pt);
v->pt.x = XDoubleToFixed(pt.x);
v->pt.y = XDoubleToFixed(pt.y);
dx = radius * cos(v->theta);
dy = radius * sin(v->theta);
_XrTransformDistance(&gstate->ctm, &dx, &dy);
v->pt.x = XDoubleToFixed(dx);
v->pt.y = XDoubleToFixed(dy);
v->flag = XrPenVertexFlagNone;
}

View file

@ -90,7 +90,7 @@ _XrStatePush(XrState *xrs)
return XrStatusSuccess;
}
void
XrStatus
_XrStatePop(XrState *xrs)
{
XrGState *top;
@ -101,5 +101,7 @@ _XrStatePop(XrState *xrs)
_XrGStateDestroy(top);
}
return XrStatusSuccess;
}

View file

@ -145,21 +145,18 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
XDouble mx, my;
XDouble dx1, dx2, dy1, dy2;
XPointFixed outer;
XPointDouble v1, v2;
x1 = XFixedToDouble(inpt->x);
y1 = XFixedToDouble(inpt->y);
v1 = in->vector;
_XrTransformDistance(&gstate->ctm, &v1);
dx1 = v1.x;
dy1 = v1.y;
dx1 = in->vector.x;
dy1 = in->vector.y;
_XrTransformDistance(&gstate->ctm, &dx1, &dy1);
x2 = XFixedToDouble(outpt->x);
y2 = XFixedToDouble(outpt->y);
v2 = out->vector;
_XrTransformDistance(&gstate->ctm, &v2);
dx2 = v2.x;
dy2 = v2.y;
dx2 = out->vector.x;
dy2 = out->vector.y;
_XrTransformDistance(&gstate->ctm, &dx2, &dy2);
my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) /
(dx1 * dy2 - dx2 * dy1));
@ -208,14 +205,16 @@ _XrStrokerCap(XrStroker *stroker, XrStrokeFace *f)
break;
}
case XrLineCapSquare: {
XPointDouble vector = f->vector;
double dx, dy;
XPointFixed fvector;
XPointFixed occw, ocw;
vector.x *= gstate->line_width / 2.0;
vector.y *= gstate->line_width / 2.0;
_XrTransformDistance(&gstate->ctm, &vector);
fvector.x = XDoubleToFixed(vector.x);
fvector.y = XDoubleToFixed(vector.y);
dx = f->vector.x;
dy = f->vector.y;
dx *= gstate->line_width / 2.0;
dy *= gstate->line_width / 2.0;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
fvector.x = XDoubleToFixed(dx);
fvector.y = XDoubleToFixed(dy);
occw.x = f->ccw.x + fvector.x;
occw.y = f->ccw.y + fvector.y;
ocw.x = f->cw.x + fvector.x;
@ -242,34 +241,35 @@ static void
_ComputeFace(XPointFixed *pt, XrSlopeFixed *slope, XrGState *gstate, XrStrokeFace *face)
{
double mag, tmp;
XPointDouble vector;
double dx, dy;
XPointDouble user_vector;
XPointFixed offset_ccw, offset_cw;
vector.x = XFixedToDouble(slope->dx);
vector.y = XFixedToDouble(slope->dy);
dx = XFixedToDouble(slope->dx);
dy = XFixedToDouble(slope->dy);
_XrTransformDistance(&gstate->ctm_inverse, &vector);
_XrTransformDistance(&gstate->ctm_inverse, &dx, &dy);
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
mag = sqrt(dx * dx + dy * dy);
if (mag == 0) {
/* XXX: Can't compute other face points. Do we want a tag in the face for this case? */
return;
}
vector.x /= mag;
vector.y /= mag;
dx /= mag;
dy /= mag;
user_vector = vector;
user_vector.x = dx;
user_vector.y = dy;
tmp = vector.x;
vector.x = - vector.y * (gstate->line_width / 2.0);
vector.y = tmp * (gstate->line_width / 2.0);
tmp = dx;
dx = - dy * (gstate->line_width / 2.0);
dy = tmp * (gstate->line_width / 2.0);
_XrTransformDistance(&gstate->ctm, &vector);
_XrTransformDistance(&gstate->ctm, &dx, &dy);
offset_ccw.x = XDoubleToFixed(vector.x);
offset_ccw.y = XDoubleToFixed(vector.y);
offset_ccw.x = XDoubleToFixed(dx);
offset_ccw.y = XDoubleToFixed(dy);
offset_cw.x = -offset_ccw.x;
offset_cw.y = -offset_ccw.y;
@ -362,17 +362,18 @@ _XrStrokerAddEdgeDashed (void *closure, XPointFixed *p1, XPointFixed *p2)
XrStroker *stroker = closure;
XrGState *gstate = stroker->gstate;
double mag, remain, tmp;
XPointDouble vector, d2;
double dx, dy;
double dx2, dy2;
XPointFixed fd1, fd2;
int first = 1;
XrStrokeFace sub_start, sub_end;
vector.x = XFixedToDouble(p2->x - p1->x);
vector.y = XFixedToDouble(p2->y - p1->y);
dx = XFixedToDouble(p2->x - p1->x);
dy = XFixedToDouble(p2->y - p1->y);
_XrTransformDistance(&gstate->ctm_inverse, &vector);
_XrTransformDistance(&gstate->ctm_inverse, &dx, &dy);
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
mag = sqrt(dx *dx + dy * dy);
remain = mag;
fd1 = *p1;
while (remain) {
@ -380,11 +381,11 @@ _XrStrokerAddEdgeDashed (void *closure, XPointFixed *p1, XPointFixed *p2)
if (tmp > remain)
tmp = remain;
remain -= tmp;
d2.x = vector.x * (mag - remain)/mag;
d2.y = vector.y * (mag - remain)/mag;
_XrTransformDistance (&gstate->ctm, &d2);
fd2.x = XDoubleToFixed (d2.x);
fd2.y = XDoubleToFixed (d2.y);
dx2 = dx * (mag - remain)/mag;
dy2 = dy * (mag - remain)/mag;
_XrTransformDistance (&gstate->ctm, &dx2, &dy2);
fd2.x = XDoubleToFixed (dx2);
fd2.y = XDoubleToFixed (dy2);
fd2.x += p1->x;
fd2.y += p1->y;
/*

View file

@ -136,26 +136,26 @@ _XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *
}
void
_XrTransformDistance(XrTransform *transform, XPointDouble *pt)
_XrTransformDistance(XrTransform *transform, double *dx, double *dy)
{
double new_x, new_y;
new_x = (transform->m[0][0] * pt->x
+ transform->m[1][0] * pt->y);
new_y = (transform->m[0][1] * pt->x
+ transform->m[1][1] * pt->y);
new_x = (transform->m[0][0] * *dx
+ transform->m[1][0] * *dy);
new_y = (transform->m[0][1] * *dx
+ transform->m[1][1] * *dy);
pt->x = new_x;
pt->y = new_y;
*dx = new_x;
*dy = new_y;
}
void
_XrTransformPoint(XrTransform *transform, XPointDouble *pt)
_XrTransformPoint(XrTransform *transform, double *x, double *y)
{
_XrTransformDistance(transform, pt);
_XrTransformDistance(transform, x, y);
pt->x += transform->m[2][0];
pt->y += transform->m[2][1];
*x += transform->m[2][0];
*y += transform->m[2][1];
}
static void

192
xr.c
View file

@ -47,11 +47,10 @@ XrDestroy(XrState *xrs)
void
XrSave(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrStatePush(xrs);
if (status)
xrs->status = status;
xrs->status = _XrStatePush(xrs);
}
void
@ -60,114 +59,162 @@ XrRestore(XrState *xrs)
/* XXX: BUG: Calling XrRestore without a matching XrSave shoud
flag an error. Also, in order to prevent crashes, XrStatePop
should not be called in that case. */
_XrStatePop(xrs);
if (xrs->status)
return;
xrs->status = _XrStatePop(xrs);
}
void
XrSetDrawable(XrState *xrs, Drawable drawable)
{
_XrGStateSetDrawable(_XR_CURRENT_GSTATE(xrs), drawable);
if (xrs->status)
return;
xrs->status = _XrGStateSetDrawable(_XR_CURRENT_GSTATE(xrs), drawable);
}
void
XrSetVisual(XrState *xrs, Visual *visual)
{
_XrGStateSetVisual(_XR_CURRENT_GSTATE(xrs), visual);
if (xrs->status)
return;
xrs->status = _XrGStateSetVisual(_XR_CURRENT_GSTATE(xrs), visual);
}
void
XrSetFormat(XrState *xrs, XrFormat format)
{
_XrGStateSetFormat(_XR_CURRENT_GSTATE(xrs), format);
if (xrs->status)
return;
xrs->status = _XrGStateSetFormat(_XR_CURRENT_GSTATE(xrs), format);
}
void
XrSetOperator(XrState *xrs, XrOperator operator)
{
_XrGStateSetOperator(_XR_CURRENT_GSTATE(xrs), operator);
if (xrs->status)
return;
xrs->status = _XrGStateSetOperator(_XR_CURRENT_GSTATE(xrs), operator);
}
void
XrSetRGBColor(XrState *xrs, double red, double green, double blue)
{
if (xrs->status)
return;
_XrClipValue(&red, 0.0, 1.0);
_XrClipValue(&green, 0.0, 1.0);
_XrClipValue(&blue, 0.0, 1.0);
_XrGStateSetRGBColor(_XR_CURRENT_GSTATE(xrs), red, green, blue);
xrs->status = _XrGStateSetRGBColor(_XR_CURRENT_GSTATE(xrs), red, green, blue);
}
void
XrSetTolerance(XrState *xrs, double tolerance)
{
if (xrs->status)
return;
_XrClipValue(&tolerance, XR_TOLERANCE_MINIMUM, tolerance);
_XrGStateSetTolerance(_XR_CURRENT_GSTATE(xrs), tolerance);
xrs->status = _XrGStateSetTolerance(_XR_CURRENT_GSTATE(xrs), tolerance);
}
void
XrSetAlpha(XrState *xrs, double alpha)
{
if (xrs->status)
return;
_XrClipValue(&alpha, 0.0, 1.0);
_XrGStateSetAlpha(_XR_CURRENT_GSTATE(xrs), alpha);
xrs->status = _XrGStateSetAlpha(_XR_CURRENT_GSTATE(xrs), alpha);
}
void
XrSetFillRule(XrState *xrs, XrFillRule fill_rule)
{
_XrGStateSetFillRule(_XR_CURRENT_GSTATE(xrs), fill_rule);
if (xrs->status)
return;
xrs->status = _XrGStateSetFillRule(_XR_CURRENT_GSTATE(xrs), fill_rule);
}
void
XrSetLineWidth(XrState *xrs, double width)
{
_XrGStateSetLineWidth(_XR_CURRENT_GSTATE(xrs), width);
if (xrs->status)
return;
xrs->status = _XrGStateSetLineWidth(_XR_CURRENT_GSTATE(xrs), width);
}
void
XrSetLineCap(XrState *xrs, XrLineCap line_cap)
{
_XrGStateSetLineCap(_XR_CURRENT_GSTATE(xrs), line_cap);
if (xrs->status)
return;
xrs->status = _XrGStateSetLineCap(_XR_CURRENT_GSTATE(xrs), line_cap);
}
void
XrSetLineJoin(XrState *xrs, XrLineJoin line_join)
{
_XrGStateSetLineJoin(_XR_CURRENT_GSTATE(xrs), line_join);
if (xrs->status)
return;
xrs->status = _XrGStateSetLineJoin(_XR_CURRENT_GSTATE(xrs), line_join);
}
void
XrSetDash(XrState *xrs, double *dashes, int ndash, double offset)
{
XrStatus status;
status = _XrGStateSetDash(_XR_CURRENT_GSTATE(xrs), dashes, ndash, offset);
if (status)
xrs->status = status;
if (xrs->status)
return;
xrs->status = _XrGStateSetDash(_XR_CURRENT_GSTATE(xrs), dashes, ndash, offset);
}
void
XrSetMiterLimit(XrState *xrs, double limit)
{
_XrGStateSetMiterLimit(_XR_CURRENT_GSTATE(xrs), limit);
if (xrs->status)
return;
xrs->status = _XrGStateSetMiterLimit(_XR_CURRENT_GSTATE(xrs), limit);
}
void
XrTranslate(XrState *xrs, double tx, double ty)
{
_XrGStateTranslate(_XR_CURRENT_GSTATE(xrs), tx, ty);
if (xrs->status)
return;
xrs->status = _XrGStateTranslate(_XR_CURRENT_GSTATE(xrs), tx, ty);
}
void
XrScale(XrState *xrs, double sx, double sy)
{
_XrGStateScale(_XR_CURRENT_GSTATE(xrs), sx, sy);
if (xrs->status)
return;
xrs->status = _XrGStateScale(_XR_CURRENT_GSTATE(xrs), sx, sy);
}
void
XrRotate(XrState *xrs, double angle)
{
_XrGStateRotate(_XR_CURRENT_GSTATE(xrs), angle);
if (xrs->status)
return;
xrs->status = _XrGStateRotate(_XR_CURRENT_GSTATE(xrs), angle);
}
void
@ -176,33 +223,37 @@ XrConcatMatrix(XrState *xrs,
double c, double d,
double tx, double ty)
{
_XrGStateConcatMatrix(_XR_CURRENT_GSTATE(xrs), a, b, c, d, tx, ty);
if (xrs->status)
return;
xrs->status = _XrGStateConcatMatrix(_XR_CURRENT_GSTATE(xrs), a, b, c, d, tx, ty);
}
void
XrNewPath(XrState *xrs)
{
_XrGStateNewPath(_XR_CURRENT_GSTATE(xrs));
if (xrs->status)
return;
xrs->status = _XrGStateNewPath(_XR_CURRENT_GSTATE(xrs));
}
void
XrMoveTo(XrState *xrs, double x, double y)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
if (status)
xrs->status = status;
xrs->status = _XrGStateMoveTo(_XR_CURRENT_GSTATE(xrs), x, y);
}
void
XrLineTo(XrState *xrs, double x, double y)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
if (status)
xrs->status = status;
xrs->status = _XrGStateLineTo(_XR_CURRENT_GSTATE(xrs), x, y);
}
void
@ -211,36 +262,31 @@ XrCurveTo(XrState *xrs,
double x2, double y2,
double x3, double y3)
{
XrStatus status;
XPointDouble pt[3];
if (xrs->status)
return;
pt[0].x = x1; pt[0].y = y1;
pt[1].x = x2; pt[1].y = y2;
pt[2].x = x3; pt[2].y = y3;
status = _XrGStateAddPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpCurveTo, pt, 3);
if (status)
xrs->status = status;
xrs->status = _XrGStateCurveTo(_XR_CURRENT_GSTATE(xrs),
x1, y1,
x2, y2,
x3, y3);
}
void
XrRelMoveTo(XrState *xrs, double dx, double dy)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, dx, dy);
if (status)
xrs->status = status;
xrs->status = _XrGStateRelMoveTo(_XR_CURRENT_GSTATE(xrs), dx, dy);
}
void
XrRelLineTo(XrState *xrs, double dx, double dy)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateAddUnaryPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpRelLineTo, dx, dy);
if (status)
xrs->status = status;
xrs->status = _XrGStateRelLineTo(_XR_CURRENT_GSTATE(xrs), dx, dy);
}
void
@ -249,53 +295,49 @@ XrRelCurveTo(XrState *xrs,
double dx2, double dy2,
double dx3, double dy3)
{
XrStatus status;
XPointDouble pt[3];
if (xrs->status)
return;
pt[0].x = dx1; pt[0].y = dy1;
pt[1].x = dx2; pt[1].y = dy2;
pt[2].x = dx3; pt[2].y = dy3;
status = _XrGStateAddPathOp(_XR_CURRENT_GSTATE(xrs), XrPathOpRelCurveTo, pt, 3);
if (status)
xrs->status = status;
xrs->status = _XrGStateRelCurveTo(_XR_CURRENT_GSTATE(xrs),
dx1, dy1,
dx2, dy2,
dx3, dy3);
}
void
XrClosePath(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateClosePath(_XR_CURRENT_GSTATE(xrs));
if (status)
xrs->status = status;
xrs->status = _XrGStateClosePath(_XR_CURRENT_GSTATE(xrs));
}
void
XrStroke(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateStroke(_XR_CURRENT_GSTATE(xrs));
if (status)
xrs->status = status;
xrs->status = _XrGStateStroke(_XR_CURRENT_GSTATE(xrs));
}
void
XrFill(XrState *xrs)
{
XrStatus status;
if (xrs->status)
return;
status = _XrGStateFill(_XR_CURRENT_GSTATE(xrs));
if (status) {
xrs->status = status;
}
xrs->status = _XrGStateFill(_XR_CURRENT_GSTATE(xrs));
}
void
XrShowText(XrState *xrs, const char *utf8)
{
if (xrs->status)
return;
xrs->status = _XrGStateShowText(_XR_CURRENT_GSTATE(xrs), utf8);
}
XrStatus

View file

@ -159,72 +159,94 @@ _XrGStateClone(XrGState *gstate)
return clone;
}
void
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
{
_XrSurfaceSetDrawable(&gstate->surface, drawable);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual)
{
_XrSurfaceSetVisual(&gstate->surface, visual);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format)
{
_XrSurfaceSetFormat(&gstate->surface, format);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetOperator(XrGState *gstate, XrOperator operator)
{
gstate->operator = operator;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{
_XrColorSetRGB(&gstate->color, red, green, blue);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetTolerance(XrGState *gstate, double tolerance)
{
gstate->tolerance = tolerance;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha)
{
_XrColorSetAlpha(&gstate->color, alpha);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule)
{
gstate->fill_rule = fill_rule;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetLineWidth(XrGState *gstate, double width)
{
gstate->line_width = width;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap)
{
gstate->line_cap = line_cap;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join)
{
gstate->line_join = line_join;
return XrStatusSuccess;
}
XrStatus
@ -242,16 +264,19 @@ _XrGStateSetDash(XrGState *gstate, double *dashes, int ndash, double offset)
gstate->ndashes = ndash;
memcpy (gstate->dashes, dashes, ndash * sizeof (double));
gstate->dash_offset = offset;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateSetMiterLimit(XrGState *gstate, double limit)
{
gstate->miter_limit = limit;
return XrStatusSuccess;
}
void
XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty)
{
XrTransform tmp;
@ -261,9 +286,11 @@ _XrGStateTranslate(XrGState *gstate, double tx, double ty)
_XrTransformInitTranslate(&tmp, -tx, -ty);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateScale(XrGState *gstate, double sx, double sy)
{
XrTransform tmp;
@ -273,9 +300,11 @@ _XrGStateScale(XrGState *gstate, double sx, double sy)
_XrTransformInitScale(&tmp, 1/sx, 1/sy);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateRotate(XrGState *gstate, double angle)
{
XrTransform tmp;
@ -285,9 +314,11 @@ _XrGStateRotate(XrGState *gstate, double angle)
_XrTransformInitRotate(&tmp, -angle);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
}
void
XrStatus
_XrGStateConcatMatrix(XrGState *gstate,
double a, double b,
double c, double d,
@ -300,72 +331,144 @@ _XrGStateConcatMatrix(XrGState *gstate,
_XrTransformComputeInverse(&tmp);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
}
void
_XrGStateNewPath(XrGState *gstate)
{
_XrPathDeinit(&gstate->path);
return XrStatusSuccess;
}
XrStatus
_XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts)
_XrGStateNewPath(XrGState *gstate)
{
_XrPathDeinit(&gstate->path);
return XrStatusSuccess;
}
XrStatus
_XrGStateMoveTo(XrGState *gstate, double x, double y)
{
int i;
XrStatus status;
XPointFixed *pt_fixed;
switch (op) {
case XrPathOpMoveTo:
case XrPathOpLineTo:
case XrPathOpCurveTo:
for (i=0; i < num_pts; i++) {
_XrTransformPoint(&gstate->ctm, &pt[i]);
}
break;
case XrPathOpRelMoveTo:
case XrPathOpRelLineTo:
case XrPathOpRelCurveTo:
for (i=0; i < num_pts; i++) {
_XrTransformDistance(&gstate->ctm, &pt[i]);
}
break;
case XrPathOpClosePath:
break;
}
_XrTransformPoint(&gstate->ctm, &x, &y);
pt_fixed = malloc(num_pts * sizeof(XPointFixed));
if (pt_fixed == NULL) {
return XrStatusNoMemory;
}
status = _XrPathMoveTo(&gstate->path, x, y);
for (i=0; i < num_pts; i++) {
pt_fixed[i].x = XDoubleToFixed(pt[i].x);
pt_fixed[i].y = XDoubleToFixed(pt[i].y);
}
gstate->current_pt.x = x;
gstate->current_pt.y = y;
status = _XrPathAdd(&gstate->path, op, pt_fixed, num_pts);
free(pt_fixed);
gstate->last_move_pt = gstate->current_pt;
return status;
}
XrStatus
_XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
_XrGStateLineTo(XrGState *gstate, double x, double y)
{
XPointDouble pt;
XrStatus status;
pt.x = x;
pt.y = y;
_XrTransformPoint(&gstate->ctm, &x, &y);
return _XrGStateAddPathOp(gstate, op, &pt, 1);
status = _XrPathLineTo(&gstate->path, x, y);
gstate->current_pt.x = x;
gstate->current_pt.y = y;
return status;
}
XrStatus
_XrGStateCurveTo(XrGState *gstate,
double x1, double y1,
double x2, double y2,
double x3, double y3)
{
XrStatus status;
_XrTransformPoint(&gstate->ctm, &x1, &y1);
_XrTransformPoint(&gstate->ctm, &x2, &y2);
_XrTransformPoint(&gstate->ctm, &x3, &y3);
status = _XrPathCurveTo(&gstate->path,
x1, y1,
x2, y2,
x3, y3);
gstate->current_pt.x = x3;
gstate->current_pt.y = y3;
return status;
}
XrStatus
_XrGStateRelMoveTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathMoveTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
gstate->last_move_pt = gstate->current_pt;
return status;
}
XrStatus
_XrGStateRelLineTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathLineTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
return status;
}
XrStatus
_XrGStateRelCurveTo(XrGState *gstate,
double dx1, double dy1,
double dx2, double dy2,
double dx3, double dy3)
{
XrStatus status;
_XrTransformDistance(&gstate->ctm, &dx1, &dy1);
_XrTransformDistance(&gstate->ctm, &dx2, &dy2);
_XrTransformDistance(&gstate->ctm, &dx3, &dy3);
status = _XrPathCurveTo(&gstate->path,
gstate->current_pt.x + dx1, gstate->current_pt.y + dy1,
gstate->current_pt.x + dx2, gstate->current_pt.y + dy2,
gstate->current_pt.x + dx3, gstate->current_pt.y + dy3);
gstate->current_pt.x += dx3;
gstate->current_pt.y += dy3;
return status;
}
XrStatus
_XrGStateClosePath(XrGState *gstate)
{
return _XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
XrStatus status;
status = _XrPathClosePath(&gstate->path);
gstate->current_pt = gstate->last_move_pt;
return status;
}
XrStatus
@ -456,3 +559,11 @@ _XrGStateFill(XrGState *gstate)
return XrStatusSuccess;
}
XrStatus
_XrGStateShowText(XrGState *gstate, const char *utf8)
{
/* XXX: NYI */
return XrStatusSuccess;
}

87
xrint.h
View file

@ -53,10 +53,7 @@ typedef enum _XrPathOp {
XrPathOpMoveTo = 0,
XrPathOpLineTo = 1,
XrPathOpCurveTo = 2,
XrPathOpRelMoveTo = 3,
XrPathOpRelLineTo = 4,
XrPathOpRelCurveTo = 5,
XrPathOpClosePath = 6
XrPathOpClosePath = 3
} __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */
typedef enum _XrPathDirection {
@ -238,6 +235,9 @@ typedef struct _XrGState {
XrPath path;
XPointDouble last_move_pt;
XPointDouble current_pt;
XrPen pen_regular;
struct _XrGState *next;
@ -294,7 +294,7 @@ _XrStateDestroy(XrState *state);
XrStatus
_XrStatePush(XrState *xrs);
void
XrStatus
_XrStatePop(XrState *xrs);
/* xrgstate.c */
@ -316,68 +316,86 @@ _XrGStateDestroy(XrGState *gstate);
XrGState *
_XrGStateClone(XrGState *gstate);
void
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable);
void
XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual);
void
XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format);
void
XrStatus
_XrGStateSetOperator(XrGState *gstate, XrOperator operator);
void
XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue);
void
XrStatus
_XrGStateSetTolerance(XrGState *gstate, double tolerance);
void
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha);
void
XrStatus
_XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule);
void
XrStatus
_XrGStateSetLineWidth(XrGState *gstate, double width);
void
XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap);
void
XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join);
XrStatus
_XrGStateSetDash(XrGState *gstate, double *dashes, int ndash, double offset);
void
XrStatus
_XrGStateSetMiterLimit(XrGState *gstate, double limit);
void
XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty);
void
XrStatus
_XrGStateScale(XrGState *gstate, double sx, double sy);
void
XrStatus
_XrGStateRotate(XrGState *gstate, double angle);
void
XrStatus
_XrGStateConcatMatrix(XrGState *gstate,
double a, double b,
double c, double d,
double tx, double ty);
void
XrStatus
_XrGStateNewPath(XrGState *gstate);
XrStatus
_XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts);
_XrGStateMoveTo(XrGState *gstate, double x, double y);
XrStatus
_XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y);
_XrGStateLineTo(XrGState *gstate, double x, double y);
XrStatus
_XrGStateCurveTo(XrGState *gstate,
double x1, double y1,
double x2, double y2,
double x3, double y3);
XrStatus
_XrGStateRelMoveTo(XrGState *gstate, double dx, double dy);
XrStatus
_XrGStateRelLineTo(XrGState *gstate, double dx, double dy);
XrStatus
_XrGStateRelCurveTo(XrGState *gstate,
double dx1, double dy1,
double dx2, double dy2,
double dx3, double dy3);
XrStatus
_XrGStateClosePath(XrGState *gstate);
@ -388,6 +406,9 @@ _XrGStateStroke(XrGState *gstate);
XrStatus
_XrGStateFill(XrGState *fill);
XrStatus
_XrGStateShowText(XrGState *gstate, const char *utf8);
/* xrcolor.c */
void
_XrColorInit(XrColor *color);
@ -412,7 +433,19 @@ void
_XrPathDeinit(XrPath *path);
XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
_XrPathMoveTo(XrPath *path, double x, double y);
XrStatus
_XrPathLineTo(XrPath *path, double x, double y);
XrStatus
_XrPathCurveTo(XrPath *path,
double x1, double y1,
double x2, double y2,
double x3, double y3);
XrStatus
_XrPathClosePath(XrPath *path);
XrStatus
_XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
@ -560,10 +593,10 @@ void
_XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new);
void
_XrTransformDistance(XrTransform *transform, XPointDouble *pt);
_XrTransformDistance(XrTransform *transform, double *dx, double *dy);
void
_XrTransformPoint(XrTransform *transform, XPointDouble *pt);
_XrTransformPoint(XrTransform *transform, double *x, double *y);
void
_XrTransformComputeInverse(XrTransform *transform);

121
xrpath.c
View file

@ -27,6 +27,9 @@
#include "xrint.h"
/* private functions */
static XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
@ -57,10 +60,6 @@ _XrPathArgBufDestroy(XrPathArgBuf *buf);
static void
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
static void
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
void
_XrPathInit(XrPath *path)
{
@ -121,6 +120,76 @@ _XrPathDeinit(XrPath *path)
path->arg_tail = NULL;
}
XrStatus
_XrPathMoveTo(XrPath *path, double x, double y)
{
XPointFixed pt;
pt.x = XDoubleToFixed(x);
pt.y = XDoubleToFixed(y);
return _XrPathAdd(path, XrPathOpMoveTo, &pt, 1);
}
XrStatus
_XrPathLineTo(XrPath *path, double x, double y)
{
XPointFixed pt;
pt.x = XDoubleToFixed(x);
pt.y = XDoubleToFixed(y);
return _XrPathAdd(path, XrPathOpLineTo, &pt, 1);
}
XrStatus
_XrPathCurveTo(XrPath *path,
double x1, double y1,
double x2, double y2,
double x3, double y3)
{
XPointFixed pt[3];
pt[0].x = XDoubleToFixed(x1);
pt[0].y = XDoubleToFixed(y1);
pt[1].x = XDoubleToFixed(x2);
pt[1].y = XDoubleToFixed(y2);
pt[2].x = XDoubleToFixed(x3);
pt[2].y = XDoubleToFixed(y3);
return _XrPathAdd(path, XrPathOpCurveTo, pt, 3);
}
XrStatus
_XrPathClosePath(XrPath *path)
{
return _XrPathAdd(path, XrPathOpClosePath, NULL, 0);
}
static XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
{
XrStatus status;
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
status = _XrPathNewOpBuf(path);
if (status)
return status;
}
_XrPathOpBufAdd(path->op_tail, op);
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
status = _XrPathNewArgBuf(path);
if (status)
return status;
}
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
return XrStatusSuccess;
}
static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
{
@ -180,29 +249,6 @@ _XrPathNewArgBuf(XrPath *path)
return XrStatusSuccess;
}
XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
{
XrStatus status;
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
status = _XrPathNewOpBuf(path);
if (status)
return status;
}
_XrPathOpBufAdd(path->op_tail, op);
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
status = _XrPathNewArgBuf(path);
if (status)
return status;
}
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
return XrStatusSuccess;
}
static XrPathOpBuf *
_XrPathOpBufCreate(void)
{
@ -261,13 +307,6 @@ _XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts)
}
}
static void
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
{
pt->x += offset->x;
pt->y += offset->y;
}
#define XR_PATH_OP_MAX_ARGS 3
static int num_args[] =
@ -275,9 +314,6 @@ static int num_args[] =
1, /* XrPathMoveTo */
1, /* XrPathOpLineTo */
3, /* XrPathOpCurveTo */
1, /* XrPathOpRelMoveTo */
1, /* XrPathOpRelLineTo */
3, /* XrPathOpRelCurveTo */
0, /* XrPathOpClosePath */
};
@ -335,9 +371,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
}
switch (op) {
case XrPathOpRelMoveTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpMoveTo:
if (has_edge) {
status = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
@ -349,9 +382,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_current = 1;
has_edge = 0;
break;
case XrPathOpRelLineTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpLineTo:
if (has_current) {
status = (*cb->AddEdge)(closure, &current, &pt[0]);
@ -366,11 +396,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_edge = 0;
}
break;
case XrPathOpRelCurveTo:
for (arg = 0; arg < num_args[op]; arg++) {
_TranslatePointFixed(&pt[arg], &current);
}
/* fall-through */
case XrPathOpCurveTo:
if (has_current) {
status = (*cb->AddSpline)(closure, &current, &pt[0], &pt[1], &pt[2]);

12
xrpen.c
View file

@ -60,7 +60,7 @@ _XrPenInit(XrPen *pen, double radius, XrGState *gstate)
{
int i;
XrPenVertex *v;
XPointDouble pt;
double dx, dy;
if (pen->num_vertices) {
/* XXX: It would be nice to notice that the pen is already properly constructed.
@ -88,11 +88,11 @@ _XrPenInit(XrPen *pen, double radius, XrGState *gstate)
for (i=0; i < pen->num_vertices; i++) {
v = &pen->vertex[i];
v->theta = 2 * M_PI * i / (double) pen->num_vertices;
pt.x = radius * cos(v->theta);
pt.y = radius * sin(v->theta);
_XrTransformDistance(&gstate->ctm, &pt);
v->pt.x = XDoubleToFixed(pt.x);
v->pt.y = XDoubleToFixed(pt.y);
dx = radius * cos(v->theta);
dy = radius * sin(v->theta);
_XrTransformDistance(&gstate->ctm, &dx, &dy);
v->pt.x = XDoubleToFixed(dx);
v->pt.y = XDoubleToFixed(dy);
v->flag = XrPenVertexFlagNone;
}

View file

@ -90,7 +90,7 @@ _XrStatePush(XrState *xrs)
return XrStatusSuccess;
}
void
XrStatus
_XrStatePop(XrState *xrs)
{
XrGState *top;
@ -101,5 +101,7 @@ _XrStatePop(XrState *xrs)
_XrGStateDestroy(top);
}
return XrStatusSuccess;
}

View file

@ -145,21 +145,18 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
XDouble mx, my;
XDouble dx1, dx2, dy1, dy2;
XPointFixed outer;
XPointDouble v1, v2;
x1 = XFixedToDouble(inpt->x);
y1 = XFixedToDouble(inpt->y);
v1 = in->vector;
_XrTransformDistance(&gstate->ctm, &v1);
dx1 = v1.x;
dy1 = v1.y;
dx1 = in->vector.x;
dy1 = in->vector.y;
_XrTransformDistance(&gstate->ctm, &dx1, &dy1);
x2 = XFixedToDouble(outpt->x);
y2 = XFixedToDouble(outpt->y);
v2 = out->vector;
_XrTransformDistance(&gstate->ctm, &v2);
dx2 = v2.x;
dy2 = v2.y;
dx2 = out->vector.x;
dy2 = out->vector.y;
_XrTransformDistance(&gstate->ctm, &dx2, &dy2);
my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) /
(dx1 * dy2 - dx2 * dy1));
@ -208,14 +205,16 @@ _XrStrokerCap(XrStroker *stroker, XrStrokeFace *f)
break;
}
case XrLineCapSquare: {
XPointDouble vector = f->vector;
double dx, dy;
XPointFixed fvector;
XPointFixed occw, ocw;
vector.x *= gstate->line_width / 2.0;
vector.y *= gstate->line_width / 2.0;
_XrTransformDistance(&gstate->ctm, &vector);
fvector.x = XDoubleToFixed(vector.x);
fvector.y = XDoubleToFixed(vector.y);
dx = f->vector.x;
dy = f->vector.y;
dx *= gstate->line_width / 2.0;
dy *= gstate->line_width / 2.0;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
fvector.x = XDoubleToFixed(dx);
fvector.y = XDoubleToFixed(dy);
occw.x = f->ccw.x + fvector.x;
occw.y = f->ccw.y + fvector.y;
ocw.x = f->cw.x + fvector.x;
@ -242,34 +241,35 @@ static void
_ComputeFace(XPointFixed *pt, XrSlopeFixed *slope, XrGState *gstate, XrStrokeFace *face)
{
double mag, tmp;
XPointDouble vector;
double dx, dy;
XPointDouble user_vector;
XPointFixed offset_ccw, offset_cw;
vector.x = XFixedToDouble(slope->dx);
vector.y = XFixedToDouble(slope->dy);
dx = XFixedToDouble(slope->dx);
dy = XFixedToDouble(slope->dy);
_XrTransformDistance(&gstate->ctm_inverse, &vector);
_XrTransformDistance(&gstate->ctm_inverse, &dx, &dy);
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
mag = sqrt(dx * dx + dy * dy);
if (mag == 0) {
/* XXX: Can't compute other face points. Do we want a tag in the face for this case? */
return;
}
vector.x /= mag;
vector.y /= mag;
dx /= mag;
dy /= mag;
user_vector = vector;
user_vector.x = dx;
user_vector.y = dy;
tmp = vector.x;
vector.x = - vector.y * (gstate->line_width / 2.0);
vector.y = tmp * (gstate->line_width / 2.0);
tmp = dx;
dx = - dy * (gstate->line_width / 2.0);
dy = tmp * (gstate->line_width / 2.0);
_XrTransformDistance(&gstate->ctm, &vector);
_XrTransformDistance(&gstate->ctm, &dx, &dy);
offset_ccw.x = XDoubleToFixed(vector.x);
offset_ccw.y = XDoubleToFixed(vector.y);
offset_ccw.x = XDoubleToFixed(dx);
offset_ccw.y = XDoubleToFixed(dy);
offset_cw.x = -offset_ccw.x;
offset_cw.y = -offset_ccw.y;
@ -362,17 +362,18 @@ _XrStrokerAddEdgeDashed (void *closure, XPointFixed *p1, XPointFixed *p2)
XrStroker *stroker = closure;
XrGState *gstate = stroker->gstate;
double mag, remain, tmp;
XPointDouble vector, d2;
double dx, dy;
double dx2, dy2;
XPointFixed fd1, fd2;
int first = 1;
XrStrokeFace sub_start, sub_end;
vector.x = XFixedToDouble(p2->x - p1->x);
vector.y = XFixedToDouble(p2->y - p1->y);
dx = XFixedToDouble(p2->x - p1->x);
dy = XFixedToDouble(p2->y - p1->y);
_XrTransformDistance(&gstate->ctm_inverse, &vector);
_XrTransformDistance(&gstate->ctm_inverse, &dx, &dy);
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
mag = sqrt(dx *dx + dy * dy);
remain = mag;
fd1 = *p1;
while (remain) {
@ -380,11 +381,11 @@ _XrStrokerAddEdgeDashed (void *closure, XPointFixed *p1, XPointFixed *p2)
if (tmp > remain)
tmp = remain;
remain -= tmp;
d2.x = vector.x * (mag - remain)/mag;
d2.y = vector.y * (mag - remain)/mag;
_XrTransformDistance (&gstate->ctm, &d2);
fd2.x = XDoubleToFixed (d2.x);
fd2.y = XDoubleToFixed (d2.y);
dx2 = dx * (mag - remain)/mag;
dy2 = dy * (mag - remain)/mag;
_XrTransformDistance (&gstate->ctm, &dx2, &dy2);
fd2.x = XDoubleToFixed (dx2);
fd2.y = XDoubleToFixed (dy2);
fd2.x += p1->x;
fd2.y += p1->y;
/*

View file

@ -136,26 +136,26 @@ _XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *
}
void
_XrTransformDistance(XrTransform *transform, XPointDouble *pt)
_XrTransformDistance(XrTransform *transform, double *dx, double *dy)
{
double new_x, new_y;
new_x = (transform->m[0][0] * pt->x
+ transform->m[1][0] * pt->y);
new_y = (transform->m[0][1] * pt->x
+ transform->m[1][1] * pt->y);
new_x = (transform->m[0][0] * *dx
+ transform->m[1][0] * *dy);
new_y = (transform->m[0][1] * *dx
+ transform->m[1][1] * *dy);
pt->x = new_x;
pt->y = new_y;
*dx = new_x;
*dy = new_y;
}
void
_XrTransformPoint(XrTransform *transform, XPointDouble *pt)
_XrTransformPoint(XrTransform *transform, double *x, double *y)
{
_XrTransformDistance(transform, pt);
_XrTransformDistance(transform, x, y);
pt->x += transform->m[2][0];
pt->y += transform->m[2][1];
*x += transform->m[2][0];
*y += transform->m[2][1];
}
static void