cairo/xrgstate.c

314 lines
7.1 KiB
C
Raw Normal View History

2002-06-11 04:02:23 +00:00
/*
* $XFree86: $
*
* 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
* 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
*
* 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;
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
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);
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);
}
XrGState*
2002-06-11 04:02:23 +00:00
XrGStateClone(XrGState *gstate)
{
XrGState *clone;
clone = _XrGStateAlloc();
XrGStateInitCopy(clone, gstate);
return clone;
}
void
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);
}
void
XrGStateSetVisual(XrGState *gstate, Visual *visual)
{
2002-07-23 07:22:23 +00:00
XrSurfaceSetVisual(&gstate->surface, visual);
}
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)
{
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)
{
gstate->stroke_style.line_cap = line_cap;
2002-07-23 07:22:23 +00:00
}
void
XrGStateSetLineJoin(XrGState *gstate, XrLineJoin line_join)
{
gstate->stroke_style.line_join = line_join;
2002-07-23 07:22:23 +00:00
}
void
XrGStateSetMiterLimit(XrGState *gstate, double limit)
{
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)
{
XrTransform tmp;
XrTransformInitTranslate(&tmp, tx, ty);
XrTransformMultiplyIntoRight(&tmp, &gstate->ctm);
2002-06-11 04:02:23 +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)
{
XrTransform tmp;
2002-06-11 04:02:23 +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)
{
XrTransform tmp;
XrTransformInitRotate(&tmp, angle);
XrTransformMultiplyIntoRight(&tmp, &gstate->ctm);
2002-06-11 04:02:23 +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
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
2002-06-11 04:02:23 +00:00
{
XPointDouble pt;
XPointFixed pt_fixed;
2002-06-11 04:02:23 +00:00
pt.x = x;
pt.y = y;
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
pt_fixed.x = XDoubleToFixed(pt.x);
pt_fixed.y = XDoubleToFixed(pt.y);
2002-06-11 04:02:23 +00:00
XrPathAdd(&gstate->path, op, &pt_fixed, 1);
2002-06-11 04:02:23 +00:00
}
void
XrGStateClosePath(XrGState *gstate)
{
XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
2002-06-11 04:02:23 +00:00
}
void
XrGStateStroke(XrGState *gstate)
{
static XrPathCallbacks cb = { XrStrokerAddEdge };
XrStroker stroker;
2002-07-23 07:22:23 +00:00
XrTraps traps;
XrStrokerInit(&stroker, gstate, &traps);
2002-07-23 07:22:23 +00:00
XrTrapsInit(&traps);
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);
XrStrokerDeinit(&stroker);
2002-07-23 07:22:23 +00:00
XrGStateNewPath(gstate);
2002-06-11 04:02:23 +00:00
}
void
XrGStateFill(XrGState *gstate)
{
static XrPathCallbacks cb = { XrPolygonAddEdge };
XrPolygon polygon;
2002-07-23 07:22:23 +00:00
XrTraps traps;
2002-06-11 04:02:23 +00:00
XrPolygonInit(&polygon);
2002-07-23 07:22:23 +00:00
XrTrapsInit(&traps);
2002-06-11 04:02:23 +00:00
XrPathInterpret(&gstate->path, XrPathDirectionForward, &cb, &polygon);
XrTrapsTessellatePolygon(&traps, &polygon, gstate->fill_style.winding);
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);
XrPolygonDeinit(&polygon);
XrGStateNewPath(gstate);
}
2002-07-23 07:22:23 +00:00