2002-06-11 04:02:23 +00:00
|
|
|
|
/*
|
|
|
|
|
|
* $XFree86: $
|
|
|
|
|
|
*
|
2002-08-14 00:39:43 +00:00
|
|
|
|
* Copyright <EFBFBD> 2002 Carl D. Worth
|
2002-06-11 04:02:23 +00:00
|
|
|
|
*
|
|
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software
|
|
|
|
|
|
* and its documentation for any purpose is hereby granted without
|
|
|
|
|
|
* fee, provided that the above copyright notice appear in all copies
|
|
|
|
|
|
* and that both that copyright notice and this permission notice
|
2002-08-14 00:39:43 +00:00
|
|
|
|
* appear in supporting documentation, and that the name of Carl
|
|
|
|
|
|
* D. Worth not be used in advertising or publicity pertaining to
|
|
|
|
|
|
* distribution of the software without specific, written prior
|
|
|
|
|
|
* permission. Carl D. Worth makes no representations about the
|
|
|
|
|
|
* suitability of this software for any purpose. It is provided "as
|
|
|
|
|
|
* is" without express or implied warranty.
|
2002-06-11 04:02:23 +00:00
|
|
|
|
*
|
2002-08-14 00:39:43 +00:00
|
|
|
|
* CARL D. WORTH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
|
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
|
|
|
|
* FITNESS, IN NO EVENT SHALL CARL D. WORTH BE LIABLE FOR ANY SPECIAL,
|
|
|
|
|
|
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
|
|
|
|
|
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
|
|
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
|
|
|
|
|
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
|
*/
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "xrint.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* Private functions */
|
|
|
|
|
|
static XrGState *
|
|
|
|
|
|
_XrGStateAlloc(void);
|
|
|
|
|
|
|
|
|
|
|
|
static XrGState *
|
|
|
|
|
|
_XrGStateAlloc(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
return malloc(sizeof(XrGState));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XrGState *
|
|
|
|
|
|
XrGStateCreate(Display *dpy)
|
|
|
|
|
|
{
|
|
|
|
|
|
XrGState *gstate;
|
|
|
|
|
|
|
|
|
|
|
|
gstate = _XrGStateAlloc();
|
|
|
|
|
|
XrGStateInit(gstate, dpy);
|
|
|
|
|
|
|
|
|
|
|
|
return gstate;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateInit(XrGState *gstate, Display *dpy)
|
|
|
|
|
|
{
|
|
|
|
|
|
gstate->dpy = dpy;
|
|
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
gstate->operator = XR_GSTATE_OPERATOR_DEFAULT;
|
2002-08-14 17:32:22 +00:00
|
|
|
|
|
|
|
|
|
|
gstate->fill_style.winding = XR_GSTATE_WINDING_DEFAULT;
|
|
|
|
|
|
|
|
|
|
|
|
gstate->stroke_style.line_width = XR_GSTATE_LINE_WIDTH_DEFAULT;
|
|
|
|
|
|
gstate->stroke_style.line_cap = XR_GSTATE_LINE_CAP_DEFAULT;
|
|
|
|
|
|
gstate->stroke_style.line_join = XR_GSTATE_LINE_JOIN_DEFAULT;
|
|
|
|
|
|
gstate->stroke_style.miter_limit = XR_GSTATE_MITER_LIMIT_DEFAULT;
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
gstate->solidFormat = XcFindStandardFormat(dpy, PictStandardARGB32);
|
|
|
|
|
|
gstate->alphaFormat = XcFindStandardFormat(dpy, PictStandardA8);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceInit(&gstate->surface, dpy);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceInit(&gstate->src, dpy);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
XrColorInit(&gstate->color);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransformInit(&gstate->ctm);
|
|
|
|
|
|
XrTransformInit(&gstate->ctm_inverse);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
|
|
|
|
|
XrPathInit(&gstate->path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateInitCopy(XrGState *gstate, XrGState *other)
|
|
|
|
|
|
{
|
|
|
|
|
|
*gstate = *other;
|
|
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceInit(&gstate->src, gstate->dpy);
|
|
|
|
|
|
XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
|
|
|
|
|
|
|
2002-06-11 04:02:23 +00:00
|
|
|
|
XrPathInitCopy(&gstate->path, &other->path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateDeinit(XrGState *gstate)
|
|
|
|
|
|
{
|
|
|
|
|
|
XrColorDeinit(&gstate->color);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceDeinit(&gstate->src);
|
|
|
|
|
|
XrSurfaceDeinit(&gstate->surface);
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransformDeinit(&gstate->ctm);
|
|
|
|
|
|
XrTransformDeinit(&gstate->ctm_inverse);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
|
|
|
|
|
XrPathDeinit(&gstate->path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateDestroy(XrGState *gstate)
|
|
|
|
|
|
{
|
|
|
|
|
|
XrGStateDeinit(gstate);
|
|
|
|
|
|
free(gstate);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2002-08-14 00:39:43 +00:00
|
|
|
|
XrGState*
|
2002-06-11 04:02:23 +00:00
|
|
|
|
XrGStateClone(XrGState *gstate)
|
|
|
|
|
|
{
|
|
|
|
|
|
XrGState *clone;
|
|
|
|
|
|
|
|
|
|
|
|
clone = _XrGStateAlloc();
|
|
|
|
|
|
|
|
|
|
|
|
XrGStateInitCopy(clone, gstate);
|
|
|
|
|
|
return clone;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
|
2002-06-11 04:02:23 +00:00
|
|
|
|
{
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceSetDrawable(&gstate->surface, drawable);
|
2002-06-14 15:13:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetVisual(XrGState *gstate, Visual *visual)
|
|
|
|
|
|
{
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceSetVisual(&gstate->surface, visual);
|
2002-06-14 15:13:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetFormat(XrGState *gstate, XrFormat format)
|
|
|
|
|
|
{
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceSetFormat(&gstate->surface, format);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetOperator(XrGState *gstate, XrOperator operator)
|
|
|
|
|
|
{
|
|
|
|
|
|
gstate->operator = operator;
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
|
2002-06-11 04:02:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
XrColorSetRGB(&gstate->color, red, green, blue);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetAlpha(XrGState *gstate, double alpha)
|
|
|
|
|
|
{
|
|
|
|
|
|
XrColorSetAlpha(&gstate->color, alpha);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetLineWidth(XrGState *gstate, double width)
|
|
|
|
|
|
{
|
2002-08-14 17:32:22 +00:00
|
|
|
|
gstate->stroke_style.line_width = width;
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetLineCap(XrGState *gstate, XrLineCap line_cap)
|
|
|
|
|
|
{
|
2002-08-14 17:32:22 +00:00
|
|
|
|
gstate->stroke_style.line_cap = line_cap;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join)
|
|
|
|
|
|
{
|
2002-08-14 17:32:22 +00:00
|
|
|
|
gstate->stroke_style.line_join = line_join;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateSetMiterLimit(XrGState *gstate, double limit)
|
|
|
|
|
|
{
|
2002-08-14 17:32:22 +00:00
|
|
|
|
gstate->stroke_style.miter_limit = limit;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2002-06-11 04:02:23 +00:00
|
|
|
|
void
|
|
|
|
|
|
XrGStateTranslate(XrGState *gstate, double tx, double ty)
|
|
|
|
|
|
{
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransform tmp;
|
|
|
|
|
|
|
|
|
|
|
|
XrTransformInitTranslate(&tmp, tx, ty);
|
|
|
|
|
|
XrTransformMultiplyIntoRight(&tmp, &gstate->ctm);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransformInitTranslate(&tmp, -tx, -ty);
|
|
|
|
|
|
XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateScale(XrGState *gstate, double sx, double sy)
|
|
|
|
|
|
{
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransform tmp;
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransformInitScale(&tmp, sx, sy);
|
|
|
|
|
|
XrTransformMultiplyIntoRight(&tmp, &gstate->ctm);
|
|
|
|
|
|
|
|
|
|
|
|
XrTransformInitScale(&tmp, -sx, -sy);
|
|
|
|
|
|
XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateRotate(XrGState *gstate, double angle)
|
|
|
|
|
|
{
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransform tmp;
|
|
|
|
|
|
|
|
|
|
|
|
XrTransformInitRotate(&tmp, angle);
|
|
|
|
|
|
XrTransformMultiplyIntoRight(&tmp, &gstate->ctm);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-06-14 15:13:44 +00:00
|
|
|
|
XrTransformInitRotate(&tmp, -angle);
|
|
|
|
|
|
XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateNewPath(XrGState *gstate)
|
|
|
|
|
|
{
|
|
|
|
|
|
XrPathDeinit(&gstate->path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-08-14 00:39:43 +00:00
|
|
|
|
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
|
2002-06-11 04:02:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
XPointDouble pt;
|
2002-08-14 00:39:43 +00:00
|
|
|
|
XPointFixed pt_fixed;
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
|
|
|
|
|
pt.x = x;
|
|
|
|
|
|
pt.y = y;
|
|
|
|
|
|
|
2002-08-14 00:39:43 +00:00
|
|
|
|
switch (op) {
|
|
|
|
|
|
case XrPathOpMoveTo:
|
|
|
|
|
|
case XrPathOpLineTo:
|
|
|
|
|
|
XrTransformPoint(&gstate->ctm, &pt);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case XrPathOpRelMoveTo:
|
|
|
|
|
|
case XrPathOpRelLineTo:
|
|
|
|
|
|
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
/* Invalid */
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-08-14 00:39:43 +00:00
|
|
|
|
pt_fixed.x = XDoubleToFixed(pt.x);
|
|
|
|
|
|
pt_fixed.y = XDoubleToFixed(pt.y);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-08-14 00:39:43 +00:00
|
|
|
|
XrPathAdd(&gstate->path, op, &pt_fixed, 1);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateClosePath(XrGState *gstate)
|
|
|
|
|
|
{
|
2002-08-14 00:39:43 +00:00
|
|
|
|
XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateStroke(XrGState *gstate)
|
|
|
|
|
|
{
|
2002-08-14 17:32:22 +00:00
|
|
|
|
static XrPathCallbacks cb = { XrStrokerAddEdge };
|
|
|
|
|
|
|
|
|
|
|
|
XrStroker stroker;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrTraps traps;
|
|
|
|
|
|
|
2002-08-14 17:32:22 +00:00
|
|
|
|
XrStrokerInit(&stroker, gstate, &traps);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrTrapsInit(&traps);
|
|
|
|
|
|
|
2002-08-14 17:32:22 +00:00
|
|
|
|
XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &stroker);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|
|
|
|
|
|
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
|
|
|
|
|
gstate->src.xcsurface, gstate->surface.xcsurface,
|
|
|
|
|
|
gstate->alphaFormat,
|
|
|
|
|
|
0, 0,
|
|
|
|
|
|
traps.xtraps,
|
|
|
|
|
|
traps.num_xtraps);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrTrapsDeinit(&traps);
|
2002-08-14 17:32:22 +00:00
|
|
|
|
XrStrokerDeinit(&stroker);
|
|
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrGStateNewPath(gstate);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
XrGStateFill(XrGState *gstate)
|
|
|
|
|
|
{
|
2002-08-14 17:32:22 +00:00
|
|
|
|
static XrPathCallbacks cb = { XrPolygonAddEdge };
|
|
|
|
|
|
|
|
|
|
|
|
XrPolygon polygon;
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrTraps traps;
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-08-14 17:32:22 +00:00
|
|
|
|
XrPolygonInit(&polygon);
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrTrapsInit(&traps);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-08-14 17:32:22 +00:00
|
|
|
|
XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &polygon);
|
|
|
|
|
|
XrTrapsTessellatePolygon(&traps, &polygon, gstate->fill_style.winding);
|
2002-08-14 00:39:43 +00:00
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
|
|
|
|
|
gstate->src.xcsurface, gstate->surface.xcsurface,
|
|
|
|
|
|
gstate->alphaFormat,
|
|
|
|
|
|
0, 0,
|
|
|
|
|
|
traps.xtraps,
|
|
|
|
|
|
traps.num_xtraps);
|
2002-06-11 04:02:23 +00:00
|
|
|
|
|
2002-07-23 07:22:23 +00:00
|
|
|
|
XrTrapsDeinit(&traps);
|
2002-08-14 17:32:22 +00:00
|
|
|
|
XrPolygonDeinit(&polygon);
|
2002-06-14 15:13:44 +00:00
|
|
|
|
|
2002-08-14 00:39:43 +00:00
|
|
|
|
XrGStateNewPath(gstate);
|
|
|
|
|
|
}
|
2002-07-23 07:22:23 +00:00
|
|
|
|
|