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. * 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 * xrtraps.c (_XrTrapsTessellatePolygon): Fix for polygon with
multiple sub-polygons that are disjoint in Y. 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. * Xr.h: Renamed xrpicture.c to xrsurface.c as part of the move.
Added XrSetFormat, XrSetOperator, XrSetLineCap, XrSetLineJoin, and Added XrSetFormat, XrSetOperator, XrSetLineCap, XrSetLineJoin, and

8
Xr.h
View file

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

View file

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

192
src/xr.c
View file

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

View file

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

View file

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

View file

@ -27,6 +27,9 @@
#include "xrint.h" #include "xrint.h"
/* private functions */ /* private functions */
static XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
static void static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op); _XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
@ -57,10 +60,6 @@ _XrPathArgBufDestroy(XrPathArgBuf *buf);
static void static void
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts); _XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
static void
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
void void
_XrPathInit(XrPath *path) _XrPathInit(XrPath *path)
{ {
@ -121,6 +120,76 @@ _XrPathDeinit(XrPath *path)
path->arg_tail = NULL; 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 static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op) _XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
{ {
@ -180,29 +249,6 @@ _XrPathNewArgBuf(XrPath *path)
return XrStatusSuccess; 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 * static XrPathOpBuf *
_XrPathOpBufCreate(void) _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 #define XR_PATH_OP_MAX_ARGS 3
static int num_args[] = static int num_args[] =
@ -275,9 +314,6 @@ static int num_args[] =
1, /* XrPathMoveTo */ 1, /* XrPathMoveTo */
1, /* XrPathOpLineTo */ 1, /* XrPathOpLineTo */
3, /* XrPathOpCurveTo */ 3, /* XrPathOpCurveTo */
1, /* XrPathOpRelMoveTo */
1, /* XrPathOpRelLineTo */
3, /* XrPathOpRelCurveTo */
0, /* XrPathOpClosePath */ 0, /* XrPathOpClosePath */
}; };
@ -335,9 +371,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
} }
switch (op) { switch (op) {
case XrPathOpRelMoveTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpMoveTo: case XrPathOpMoveTo:
if (has_edge) { if (has_edge) {
status = (*cb->DoneSubPath) (closure, XrSubPathDoneCap); status = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
@ -349,9 +382,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_current = 1; has_current = 1;
has_edge = 0; has_edge = 0;
break; break;
case XrPathOpRelLineTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpLineTo: case XrPathOpLineTo:
if (has_current) { if (has_current) {
status = (*cb->AddEdge)(closure, &current, &pt[0]); status = (*cb->AddEdge)(closure, &current, &pt[0]);
@ -366,11 +396,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_edge = 0; has_edge = 0;
} }
break; break;
case XrPathOpRelCurveTo:
for (arg = 0; arg < num_args[op]; arg++) {
_TranslatePointFixed(&pt[arg], &current);
}
/* fall-through */
case XrPathOpCurveTo: case XrPathOpCurveTo:
if (has_current) { if (has_current) {
status = (*cb->AddSpline)(closure, &current, &pt[0], &pt[1], &pt[2]); 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; int i;
XrPenVertex *v; XrPenVertex *v;
XPointDouble pt; double dx, dy;
if (pen->num_vertices) { if (pen->num_vertices) {
/* XXX: It would be nice to notice that the pen is already properly constructed. /* 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++) { for (i=0; i < pen->num_vertices; i++) {
v = &pen->vertex[i]; v = &pen->vertex[i];
v->theta = 2 * M_PI * i / (double) pen->num_vertices; v->theta = 2 * M_PI * i / (double) pen->num_vertices;
pt.x = radius * cos(v->theta); dx = radius * cos(v->theta);
pt.y = radius * sin(v->theta); dy = radius * sin(v->theta);
_XrTransformDistance(&gstate->ctm, &pt); _XrTransformDistance(&gstate->ctm, &dx, &dy);
v->pt.x = XDoubleToFixed(pt.x); v->pt.x = XDoubleToFixed(dx);
v->pt.y = XDoubleToFixed(pt.y); v->pt.y = XDoubleToFixed(dy);
v->flag = XrPenVertexFlagNone; v->flag = XrPenVertexFlagNone;
} }

View file

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

View file

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

View file

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

192
xr.c
View file

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

View file

@ -159,72 +159,94 @@ _XrGStateClone(XrGState *gstate)
return clone; return clone;
} }
void XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable) _XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
{ {
_XrSurfaceSetDrawable(&gstate->surface, drawable); _XrSurfaceSetDrawable(&gstate->surface, drawable);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual) _XrGStateSetVisual(XrGState *gstate, Visual *visual)
{ {
_XrSurfaceSetVisual(&gstate->surface, visual); _XrSurfaceSetVisual(&gstate->surface, visual);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format) _XrGStateSetFormat(XrGState *gstate, XrFormat format)
{ {
_XrSurfaceSetFormat(&gstate->surface, format); _XrSurfaceSetFormat(&gstate->surface, format);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetOperator(XrGState *gstate, XrOperator operator) _XrGStateSetOperator(XrGState *gstate, XrOperator operator)
{ {
gstate->operator = operator; gstate->operator = operator;
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue) _XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{ {
_XrColorSetRGB(&gstate->color, red, green, blue); _XrColorSetRGB(&gstate->color, red, green, blue);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat); _XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetTolerance(XrGState *gstate, double tolerance) _XrGStateSetTolerance(XrGState *gstate, double tolerance)
{ {
gstate->tolerance = tolerance; gstate->tolerance = tolerance;
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha) _XrGStateSetAlpha(XrGState *gstate, double alpha)
{ {
_XrColorSetAlpha(&gstate->color, alpha); _XrColorSetAlpha(&gstate->color, alpha);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat); _XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule) _XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule)
{ {
gstate->fill_rule = fill_rule; gstate->fill_rule = fill_rule;
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetLineWidth(XrGState *gstate, double width) _XrGStateSetLineWidth(XrGState *gstate, double width)
{ {
gstate->line_width = width; gstate->line_width = width;
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap) _XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap)
{ {
gstate->line_cap = line_cap; gstate->line_cap = line_cap;
return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join) _XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join)
{ {
gstate->line_join = line_join; gstate->line_join = line_join;
return XrStatusSuccess;
} }
XrStatus XrStatus
@ -242,16 +264,19 @@ _XrGStateSetDash(XrGState *gstate, double *dashes, int ndash, double offset)
gstate->ndashes = ndash; gstate->ndashes = ndash;
memcpy (gstate->dashes, dashes, ndash * sizeof (double)); memcpy (gstate->dashes, dashes, ndash * sizeof (double));
gstate->dash_offset = offset; gstate->dash_offset = offset;
return XrStatusSuccess; return XrStatusSuccess;
} }
void XrStatus
_XrGStateSetMiterLimit(XrGState *gstate, double limit) _XrGStateSetMiterLimit(XrGState *gstate, double limit)
{ {
gstate->miter_limit = limit; gstate->miter_limit = limit;
return XrStatusSuccess;
} }
void XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty) _XrGStateTranslate(XrGState *gstate, double tx, double ty)
{ {
XrTransform tmp; XrTransform tmp;
@ -261,9 +286,11 @@ _XrGStateTranslate(XrGState *gstate, double tx, double ty)
_XrTransformInitTranslate(&tmp, -tx, -ty); _XrTransformInitTranslate(&tmp, -tx, -ty);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); _XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateScale(XrGState *gstate, double sx, double sy) _XrGStateScale(XrGState *gstate, double sx, double sy)
{ {
XrTransform tmp; XrTransform tmp;
@ -273,9 +300,11 @@ _XrGStateScale(XrGState *gstate, double sx, double sy)
_XrTransformInitScale(&tmp, 1/sx, 1/sy); _XrTransformInitScale(&tmp, 1/sx, 1/sy);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); _XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateRotate(XrGState *gstate, double angle) _XrGStateRotate(XrGState *gstate, double angle)
{ {
XrTransform tmp; XrTransform tmp;
@ -285,9 +314,11 @@ _XrGStateRotate(XrGState *gstate, double angle)
_XrTransformInitRotate(&tmp, -angle); _XrTransformInitRotate(&tmp, -angle);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); _XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
return XrStatusSuccess;
} }
void XrStatus
_XrGStateConcatMatrix(XrGState *gstate, _XrGStateConcatMatrix(XrGState *gstate,
double a, double b, double a, double b,
double c, double d, double c, double d,
@ -300,72 +331,144 @@ _XrGStateConcatMatrix(XrGState *gstate,
_XrTransformComputeInverse(&tmp); _XrTransformComputeInverse(&tmp);
_XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); _XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
}
void return XrStatusSuccess;
_XrGStateNewPath(XrGState *gstate)
{
_XrPathDeinit(&gstate->path);
} }
XrStatus 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; XrStatus status;
XPointFixed *pt_fixed;
switch (op) { _XrTransformPoint(&gstate->ctm, &x, &y);
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;
}
pt_fixed = malloc(num_pts * sizeof(XPointFixed)); status = _XrPathMoveTo(&gstate->path, x, y);
if (pt_fixed == NULL) {
return XrStatusNoMemory;
}
for (i=0; i < num_pts; i++) { gstate->current_pt.x = x;
pt_fixed[i].x = XDoubleToFixed(pt[i].x); gstate->current_pt.y = y;
pt_fixed[i].y = XDoubleToFixed(pt[i].y);
}
status = _XrPathAdd(&gstate->path, op, pt_fixed, num_pts); gstate->last_move_pt = gstate->current_pt;
free(pt_fixed);
return status; return status;
} }
XrStatus XrStatus
_XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y) _XrGStateLineTo(XrGState *gstate, double x, double y)
{ {
XPointDouble pt; XrStatus status;
pt.x = x; _XrTransformPoint(&gstate->ctm, &x, &y);
pt.y = 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 XrStatus
_XrGStateClosePath(XrGState *gstate) _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 XrStatus
@ -456,3 +559,11 @@ _XrGStateFill(XrGState *gstate)
return XrStatusSuccess; 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, XrPathOpMoveTo = 0,
XrPathOpLineTo = 1, XrPathOpLineTo = 1,
XrPathOpCurveTo = 2, XrPathOpCurveTo = 2,
XrPathOpRelMoveTo = 3, XrPathOpClosePath = 3
XrPathOpRelLineTo = 4,
XrPathOpRelCurveTo = 5,
XrPathOpClosePath = 6
} __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */ } __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */
typedef enum _XrPathDirection { typedef enum _XrPathDirection {
@ -238,6 +235,9 @@ typedef struct _XrGState {
XrPath path; XrPath path;
XPointDouble last_move_pt;
XPointDouble current_pt;
XrPen pen_regular; XrPen pen_regular;
struct _XrGState *next; struct _XrGState *next;
@ -294,7 +294,7 @@ _XrStateDestroy(XrState *state);
XrStatus XrStatus
_XrStatePush(XrState *xrs); _XrStatePush(XrState *xrs);
void XrStatus
_XrStatePop(XrState *xrs); _XrStatePop(XrState *xrs);
/* xrgstate.c */ /* xrgstate.c */
@ -316,68 +316,86 @@ _XrGStateDestroy(XrGState *gstate);
XrGState * XrGState *
_XrGStateClone(XrGState *gstate); _XrGStateClone(XrGState *gstate);
void XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable); _XrGStateSetDrawable(XrGState *gstate, Drawable drawable);
void XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual); _XrGStateSetVisual(XrGState *gstate, Visual *visual);
void XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format); _XrGStateSetFormat(XrGState *gstate, XrFormat format);
void XrStatus
_XrGStateSetOperator(XrGState *gstate, XrOperator operator); _XrGStateSetOperator(XrGState *gstate, XrOperator operator);
void XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue); _XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue);
void XrStatus
_XrGStateSetTolerance(XrGState *gstate, double tolerance); _XrGStateSetTolerance(XrGState *gstate, double tolerance);
void XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha); _XrGStateSetAlpha(XrGState *gstate, double alpha);
void XrStatus
_XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule); _XrGStateSetFillRule(XrGState *gstate, XrFillRule fill_rule);
void XrStatus
_XrGStateSetLineWidth(XrGState *gstate, double width); _XrGStateSetLineWidth(XrGState *gstate, double width);
void XrStatus
_XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap); _XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap);
void XrStatus
_XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join); _XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join);
XrStatus XrStatus
_XrGStateSetDash(XrGState *gstate, double *dashes, int ndash, double offset); _XrGStateSetDash(XrGState *gstate, double *dashes, int ndash, double offset);
void XrStatus
_XrGStateSetMiterLimit(XrGState *gstate, double limit); _XrGStateSetMiterLimit(XrGState *gstate, double limit);
void XrStatus
_XrGStateTranslate(XrGState *gstate, double tx, double ty); _XrGStateTranslate(XrGState *gstate, double tx, double ty);
void XrStatus
_XrGStateScale(XrGState *gstate, double sx, double sy); _XrGStateScale(XrGState *gstate, double sx, double sy);
void XrStatus
_XrGStateRotate(XrGState *gstate, double angle); _XrGStateRotate(XrGState *gstate, double angle);
void XrStatus
_XrGStateConcatMatrix(XrGState *gstate, _XrGStateConcatMatrix(XrGState *gstate,
double a, double b, double a, double b,
double c, double d, double c, double d,
double tx, double ty); double tx, double ty);
void XrStatus
_XrGStateNewPath(XrGState *gstate); _XrGStateNewPath(XrGState *gstate);
XrStatus XrStatus
_XrGStateAddPathOp(XrGState *gstate, XrPathOp op, XPointDouble *pt, int num_pts); _XrGStateMoveTo(XrGState *gstate, double x, double y);
XrStatus 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 XrStatus
_XrGStateClosePath(XrGState *gstate); _XrGStateClosePath(XrGState *gstate);
@ -388,6 +406,9 @@ _XrGStateStroke(XrGState *gstate);
XrStatus XrStatus
_XrGStateFill(XrGState *fill); _XrGStateFill(XrGState *fill);
XrStatus
_XrGStateShowText(XrGState *gstate, const char *utf8);
/* xrcolor.c */ /* xrcolor.c */
void void
_XrColorInit(XrColor *color); _XrColorInit(XrColor *color);
@ -412,7 +433,19 @@ void
_XrPathDeinit(XrPath *path); _XrPathDeinit(XrPath *path);
XrStatus 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 XrStatus
_XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure); _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
@ -560,10 +593,10 @@ void
_XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new); _XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new);
void void
_XrTransformDistance(XrTransform *transform, XPointDouble *pt); _XrTransformDistance(XrTransform *transform, double *dx, double *dy);
void void
_XrTransformPoint(XrTransform *transform, XPointDouble *pt); _XrTransformPoint(XrTransform *transform, double *x, double *y);
void void
_XrTransformComputeInverse(XrTransform *transform); _XrTransformComputeInverse(XrTransform *transform);

121
xrpath.c
View file

@ -27,6 +27,9 @@
#include "xrint.h" #include "xrint.h"
/* private functions */ /* private functions */
static XrStatus
_XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
static void static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op); _XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
@ -57,10 +60,6 @@ _XrPathArgBufDestroy(XrPathArgBuf *buf);
static void static void
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts); _XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
static void
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
void void
_XrPathInit(XrPath *path) _XrPathInit(XrPath *path)
{ {
@ -121,6 +120,76 @@ _XrPathDeinit(XrPath *path)
path->arg_tail = NULL; 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 static void
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op) _XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
{ {
@ -180,29 +249,6 @@ _XrPathNewArgBuf(XrPath *path)
return XrStatusSuccess; 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 * static XrPathOpBuf *
_XrPathOpBufCreate(void) _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 #define XR_PATH_OP_MAX_ARGS 3
static int num_args[] = static int num_args[] =
@ -275,9 +314,6 @@ static int num_args[] =
1, /* XrPathMoveTo */ 1, /* XrPathMoveTo */
1, /* XrPathOpLineTo */ 1, /* XrPathOpLineTo */
3, /* XrPathOpCurveTo */ 3, /* XrPathOpCurveTo */
1, /* XrPathOpRelMoveTo */
1, /* XrPathOpRelLineTo */
3, /* XrPathOpRelCurveTo */
0, /* XrPathOpClosePath */ 0, /* XrPathOpClosePath */
}; };
@ -335,9 +371,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
} }
switch (op) { switch (op) {
case XrPathOpRelMoveTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpMoveTo: case XrPathOpMoveTo:
if (has_edge) { if (has_edge) {
status = (*cb->DoneSubPath) (closure, XrSubPathDoneCap); status = (*cb->DoneSubPath) (closure, XrSubPathDoneCap);
@ -349,9 +382,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_current = 1; has_current = 1;
has_edge = 0; has_edge = 0;
break; break;
case XrPathOpRelLineTo:
_TranslatePointFixed(&pt[0], &current);
/* fall-through */
case XrPathOpLineTo: case XrPathOpLineTo:
if (has_current) { if (has_current) {
status = (*cb->AddEdge)(closure, &current, &pt[0]); status = (*cb->AddEdge)(closure, &current, &pt[0]);
@ -366,11 +396,6 @@ _XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *c
has_edge = 0; has_edge = 0;
} }
break; break;
case XrPathOpRelCurveTo:
for (arg = 0; arg < num_args[op]; arg++) {
_TranslatePointFixed(&pt[arg], &current);
}
/* fall-through */
case XrPathOpCurveTo: case XrPathOpCurveTo:
if (has_current) { if (has_current) {
status = (*cb->AddSpline)(closure, &current, &pt[0], &pt[1], &pt[2]); 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; int i;
XrPenVertex *v; XrPenVertex *v;
XPointDouble pt; double dx, dy;
if (pen->num_vertices) { if (pen->num_vertices) {
/* XXX: It would be nice to notice that the pen is already properly constructed. /* 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++) { for (i=0; i < pen->num_vertices; i++) {
v = &pen->vertex[i]; v = &pen->vertex[i];
v->theta = 2 * M_PI * i / (double) pen->num_vertices; v->theta = 2 * M_PI * i / (double) pen->num_vertices;
pt.x = radius * cos(v->theta); dx = radius * cos(v->theta);
pt.y = radius * sin(v->theta); dy = radius * sin(v->theta);
_XrTransformDistance(&gstate->ctm, &pt); _XrTransformDistance(&gstate->ctm, &dx, &dy);
v->pt.x = XDoubleToFixed(pt.x); v->pt.x = XDoubleToFixed(dx);
v->pt.y = XDoubleToFixed(pt.y); v->pt.y = XDoubleToFixed(dy);
v->flag = XrPenVertexFlagNone; v->flag = XrPenVertexFlagNone;
} }

View file

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

View file

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

View file

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