mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 23:28:07 +02:00
Total rewrite of path storage/interpretation in preparation for splines.
This commit is contained in:
parent
9824dc8944
commit
48bd9e5d30
26 changed files with 1736 additions and 1554 deletions
|
|
@ -22,8 +22,9 @@ SRCS = xr.c \
|
|||
xrcolor.c \
|
||||
xrgstate.c \
|
||||
xrpath.c \
|
||||
xrpolygon.c \
|
||||
xrstate.c \
|
||||
xrsubpath.c \
|
||||
xrstroker.c \
|
||||
xrsurface.c \
|
||||
xrtransform.c \
|
||||
xrtraps.c
|
||||
|
|
@ -32,8 +33,9 @@ OBJS = xr.o \
|
|||
xrcolor.o \
|
||||
xrgstate.o \
|
||||
xrpath.o \
|
||||
xrpolygon.o \
|
||||
xrstate.o \
|
||||
xrsubpath.o \
|
||||
xrstroker.o \
|
||||
xrsurface.o \
|
||||
xrtransform.o \
|
||||
xrtraps.o
|
||||
|
|
|
|||
33
Xr.h
33
Xr.h
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _XR_H_
|
||||
#define _XR_H_
|
||||
|
|
|
|||
33
src/Xr.h
33
src/Xr.h
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _XR_H_
|
||||
#define _XR_H_
|
||||
|
|
|
|||
41
src/xr.c
41
src/xr.c
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
|
|
@ -139,25 +136,25 @@ XrNewPath(XrState *xrs)
|
|||
void
|
||||
XrMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateMoveTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
XrLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateLineTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
XrRelMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateRelMoveTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
XrRelLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateRelLineTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelLineTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
|
|
|
|||
289
src/xrgstate.c
289
src/xrgstate.c
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
|
@ -35,33 +32,6 @@
|
|||
static XrGState *
|
||||
_XrGStateAlloc(void);
|
||||
|
||||
static void
|
||||
_TranslatePoint(XPointDouble *pt, const XPointDouble *offset);
|
||||
|
||||
static void
|
||||
_XrGStateStrokePath(XrGState *gstate, XrPath *path, XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSubPath(XrGState *gstate, XrSubPath *subpath, XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeCap(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeJoin(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSegment(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateFillPath(XrGState *gstate, XrPath *path);
|
||||
|
||||
static XrGState *
|
||||
_XrGStateAlloc(void)
|
||||
{
|
||||
|
|
@ -136,7 +106,7 @@ XrGStateDestroy(XrGState *gstate)
|
|||
free(gstate);
|
||||
}
|
||||
|
||||
XrGState *
|
||||
XrGState*
|
||||
XrGStateClone(XrGState *gstate)
|
||||
{
|
||||
XrGState *clone;
|
||||
|
|
@ -147,12 +117,6 @@ XrGStateClone(XrGState *gstate)
|
|||
return clone;
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt)
|
||||
{
|
||||
XrPathGetCurrentPoint(&gstate->path, pt);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
|
||||
{
|
||||
|
|
@ -258,68 +222,38 @@ XrGStateNewPath(XrGState *gstate)
|
|||
}
|
||||
|
||||
void
|
||||
XrGStateMoveTo(XrGState *gstate, double x, double y)
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
|
||||
{
|
||||
XPointDouble pt;
|
||||
XPointFixed pt_fixed;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
XrPathMoveTo(&gstate->path, &pt);
|
||||
}
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
case XrPathOpLineTo:
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
case XrPathOpRelLineTo:
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
break;
|
||||
default:
|
||||
/* Invalid */
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateLineTo(XrGState *gstate, double x, double y)
|
||||
{
|
||||
XPointDouble pt;
|
||||
pt_fixed.x = XDoubleToFixed(pt.x);
|
||||
pt_fixed.y = XDoubleToFixed(pt.y);
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
XrPathLineTo(&gstate->path, &pt);
|
||||
}
|
||||
|
||||
static void
|
||||
_TranslatePoint(XPointDouble *pt, const XPointDouble *offset)
|
||||
{
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateRelMoveTo(XrGState *gstate, double x, double y)
|
||||
{
|
||||
XPointDouble pt, current;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
XrGStateGetCurrentPoint(gstate, ¤t);
|
||||
_TranslatePoint(&pt, ¤t);
|
||||
XrPathMoveTo(&gstate->path, &pt);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateRelLineTo(XrGState *gstate, double x, double y)
|
||||
{
|
||||
XPointDouble pt, current;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
XrGStateGetCurrentPoint(gstate, ¤t);
|
||||
_TranslatePoint(&pt, ¤t);
|
||||
XrPathLineTo(&gstate->path, &pt);
|
||||
XrPathAdd(&gstate->path, op, &pt_fixed, 1);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateClosePath(XrGState *gstate)
|
||||
{
|
||||
XrPathClose(&gstate->path);
|
||||
XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -329,7 +263,7 @@ XrGStateStroke(XrGState *gstate)
|
|||
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
_XrGStateStrokePath(gstate, &gstate->path, &traps);
|
||||
XrPathStrokeTraps(&gstate->path, gstate, &traps);
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
|
|
@ -345,157 +279,13 @@ XrGStateStroke(XrGState *gstate)
|
|||
|
||||
void
|
||||
XrGStateFill(XrGState *gstate)
|
||||
{
|
||||
_XrGStateFillPath(gstate, &gstate->path);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokePath(XrGState *gstate, XrPath *path, XrTraps *traps)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
|
||||
for (subpath = path->head; subpath; subpath = subpath->next) {
|
||||
if (subpath->num_pts) {
|
||||
_XrGStateStrokeSubPath(gstate, subpath, traps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSubPath(XrGState *gstate, XrSubPath *subpath, XrTraps *traps)
|
||||
{
|
||||
int i;
|
||||
XPointDouble *pt_prev, *pt, *pt_next;
|
||||
|
||||
/* XXX: BUG: Need to consider degenerate paths here, (all paths
|
||||
less then 3 points may need special consideration) */
|
||||
|
||||
/* Stroke initial cap or join */
|
||||
pt_prev = subpath->pts + subpath->num_pts - 1;
|
||||
pt = subpath->pts;
|
||||
pt_next = pt + 1;
|
||||
if (subpath->closed) {
|
||||
_XrGStateStrokeJoin(gstate, pt_prev, pt, pt_next, traps);
|
||||
} else {
|
||||
_XrGStateStrokeCap(gstate, pt_next, pt, traps);
|
||||
}
|
||||
_XrGStateStrokeSegment(gstate, pt, pt_next, traps);
|
||||
|
||||
/* Stroke path segments */
|
||||
for (i = 1; i < subpath->num_pts - 1; i++) {
|
||||
pt_prev = pt;
|
||||
pt = pt_next;
|
||||
pt_next++;
|
||||
|
||||
_XrGStateStrokeJoin(gstate, pt_prev, pt, pt_next, traps);
|
||||
_XrGStateStrokeSegment(gstate, pt, pt_next, traps);
|
||||
}
|
||||
|
||||
/* Close path or add final cap as necessary */
|
||||
pt_prev = pt;
|
||||
pt = pt_next;
|
||||
pt_next = subpath->pts;
|
||||
if (subpath->closed) {
|
||||
_XrGStateStrokeJoin(gstate, pt_prev, pt, pt_next, traps);
|
||||
_XrGStateStrokeSegment(gstate, pt, pt_next, traps);
|
||||
} else {
|
||||
_XrGStateStrokeCap(gstate, pt_prev, pt, traps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeCap(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_cap) {
|
||||
case XrLineCapRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapSquare:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapButt:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeJoin(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_join) {
|
||||
case XrLineJoinMiter:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinBevel:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSegment(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps)
|
||||
{
|
||||
double mag, tmp;
|
||||
XPointDouble offset;
|
||||
XPointDouble quad[4];
|
||||
|
||||
offset.x = p1->x - p0->x;
|
||||
offset.y = p1->y - p0->y;
|
||||
|
||||
mag = sqrt(offset.x * offset.x + offset.y * offset.y);
|
||||
if (mag == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
offset.x /= mag;
|
||||
offset.y /= mag;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm_inverse, &offset);
|
||||
|
||||
tmp = offset.x;
|
||||
offset.x = offset.y * (gstate->line_width / 2.0);
|
||||
offset.y = - tmp * (gstate->line_width / 2.0);
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &offset);
|
||||
|
||||
quad[0] = *p0;
|
||||
_TranslatePoint(&quad[0], &offset);
|
||||
quad[1] = *p1;
|
||||
_TranslatePoint(&quad[1], &offset);
|
||||
|
||||
offset.x = - offset.x;
|
||||
offset.y = - offset.y;
|
||||
|
||||
quad[2] = *p1;
|
||||
_TranslatePoint(&quad[2], &offset);
|
||||
quad[3] = *p0;
|
||||
_TranslatePoint(&quad[3], &offset);
|
||||
|
||||
XrTrapsTessellateConvexQuad(traps, quad);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateFillPath(XrGState *gstate, XrPath *path)
|
||||
{
|
||||
XrTraps traps;
|
||||
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
XrTrapsTessellatePath(&traps, path, gstate->winding);
|
||||
XrPathFillTraps(&gstate->path, &traps, gstate->winding);
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
gstate->alphaFormat,
|
||||
|
|
@ -504,6 +294,7 @@ _XrGStateFillPath(XrGState *gstate, XrPath *path)
|
|||
traps.num_xtraps);
|
||||
|
||||
XrTrapsDeinit(&traps);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
220
src/xrint.h
220
src/xrint.h
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These definitions are solely for use by the implementation of Xr
|
||||
|
|
@ -37,23 +34,72 @@
|
|||
#ifndef _XRINT_H_
|
||||
#define _XRINT_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include "Xr.h"
|
||||
|
||||
typedef struct _XrSubPath {
|
||||
int num_pts;
|
||||
int pts_size;
|
||||
XPointDouble *pts;
|
||||
int closed;
|
||||
#ifndef __GCC__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
struct _XrSubPath *next;
|
||||
} XrSubPath;
|
||||
typedef enum _XrPathOp {
|
||||
XrPathOpMoveTo,
|
||||
XrPathOpLineTo,
|
||||
XrPathOpRelMoveTo,
|
||||
XrPathOpRelLineTo,
|
||||
XrPathOpClosePath
|
||||
} __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */
|
||||
|
||||
typedef enum _XrPathDirection {
|
||||
XrPathDirectionForward,
|
||||
XrPathDirectionReverse
|
||||
} XrPathDirection;
|
||||
|
||||
typedef struct _XrPathCallbacks {
|
||||
void (*AddEdge)(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
} XrPathCallbacks;
|
||||
|
||||
#define XR_PATH_BUF_SZ 64
|
||||
|
||||
typedef struct _XrPathOpBuf {
|
||||
int num_ops;
|
||||
XrPathOp op[XR_PATH_BUF_SZ];
|
||||
|
||||
struct _XrPathOpBuf *next, *prev;
|
||||
} XrPathOpBuf;
|
||||
|
||||
typedef struct _XrPathArgBuf {
|
||||
int num_pts;
|
||||
XPointFixed pt[XR_PATH_BUF_SZ];
|
||||
|
||||
struct _XrPathArgBuf *next, *prev;
|
||||
} XrPathArgBuf;
|
||||
|
||||
typedef struct _XrPath {
|
||||
XrSubPath *head;
|
||||
XrSubPath *tail;
|
||||
XrPathOpBuf *op_head;
|
||||
XrPathOpBuf *op_tail;
|
||||
|
||||
XrPathArgBuf *arg_head;
|
||||
XrPathArgBuf *arg_tail;
|
||||
} XrPath;
|
||||
|
||||
typedef struct _XrEdge {
|
||||
/* Externally initialized */
|
||||
XLineFixed edge;
|
||||
Bool clockWise;
|
||||
|
||||
/* Internal use by XrTrapsTessellateEdges */
|
||||
XFixed current_x;
|
||||
XFixed next_x;
|
||||
struct _XrEdge *next, *prev;
|
||||
} XrEdge;
|
||||
|
||||
typedef struct _XrPolygon {
|
||||
int num_edges;
|
||||
int edges_size;
|
||||
XrEdge *edges;
|
||||
} XrPolygon;
|
||||
|
||||
typedef struct _XrSurface {
|
||||
Display *dpy;
|
||||
|
||||
|
|
@ -90,7 +136,7 @@ typedef struct _XrTraps {
|
|||
|
||||
#define XR_GSTATE_OPERATOR_DEFAULT XrOperatorOver
|
||||
#define XR_GSTATE_WINDING_DEFAULT 1
|
||||
#define XR_GSTATE_LINE_WIDTH_DEFAULT 1.0
|
||||
#define XR_GSTATE_LINE_WIDTH_DEFAULT 2.0
|
||||
#define XR_GSTATE_LINE_CAP_DEFAULT XrLineCapButt
|
||||
#define XR_GSTATE_LINE_JOIN_DEFAULT XrLineJoinMiter
|
||||
#define XR_GSTATE_MITER_LIMIT_DEFAULT 10.0
|
||||
|
|
@ -126,6 +172,11 @@ struct _XrState {
|
|||
XrGState *stack;
|
||||
};
|
||||
|
||||
typedef struct _XrStroker {
|
||||
XrGState *gstate;
|
||||
XrTraps *traps;
|
||||
} XrStroker;
|
||||
|
||||
/* xrstate.c */
|
||||
|
||||
#define CURRENT_GSTATE(xrs) (xrs->stack)
|
||||
|
|
@ -152,9 +203,6 @@ XrStatePop(XrState *xrs);
|
|||
XrGState *
|
||||
XrGStateCreate(Display *dpy);
|
||||
|
||||
XrGState *
|
||||
XrGStateClone(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateInit(XrGState *gstate, Display *dpy);
|
||||
|
||||
|
|
@ -167,8 +215,8 @@ XrGStateDeinit(XrGState *gstate);
|
|||
void
|
||||
XrGStateDestroy(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt);
|
||||
XrGState *
|
||||
XrGStateClone(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateSetDrawable(XrGState *gstate, Drawable drawable);
|
||||
|
|
@ -213,16 +261,7 @@ void
|
|||
XrGStateNewPath(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateMoveTo(XrGState *gstate, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateLineTo(XrGState *gstate, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateRelMoveTo(XrGState *gstate, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateRelLineTo(XrGState *gstate, double x, double y);
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateClosePath(XrGState *gstate);
|
||||
|
|
@ -256,69 +295,23 @@ XrPathInit(XrPath *path);
|
|||
void
|
||||
XrPathInitCopy(XrPath *path, XrPath *other);
|
||||
|
||||
void
|
||||
XrPathReinit(XrPath *path);
|
||||
|
||||
void
|
||||
XrPathDeinit(XrPath *path);
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path);
|
||||
|
||||
XrPath *
|
||||
XrPathClone(XrPath *path);
|
||||
void
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
|
||||
|
||||
void
|
||||
XrPathGetCurrentPoint(XrPath *path, XPointDouble *pt);
|
||||
|
||||
int
|
||||
XrPathNumSubPaths(XrPath *path);
|
||||
XrPathStrokeTraps(XrPath *path, XrGState *gstate, XrTraps *traps);
|
||||
|
||||
void
|
||||
XrPathNewSubPath(XrPath *path);
|
||||
XrPathFillTraps(XrPath *path, XrTraps *traps, int winding);
|
||||
|
||||
void
|
||||
XrPathAddPoint(XrPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrPathMoveTo(XrPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrPathLineTo(XrPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrPathClose(XrPath *path);
|
||||
|
||||
/* xrsubpath.c */
|
||||
XrSubPath *
|
||||
XrSubPathCreate(void);
|
||||
|
||||
void
|
||||
XrSubPathInit(XrSubPath *path);
|
||||
|
||||
void
|
||||
XrSubPathInitCopy(XrSubPath *path, XrSubPath *other);
|
||||
|
||||
void
|
||||
XrSubPathDeinit(XrSubPath *path);
|
||||
|
||||
void
|
||||
XrSubPathDestroy(XrSubPath *path);
|
||||
|
||||
XrSubPath *
|
||||
XrSubPathClone(XrSubPath *path);
|
||||
|
||||
void
|
||||
XrSubPathGetCurrentPoint(XrSubPath *path, XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrSubPathSetCurrentPoint(XrSubPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrSubPathAddPoint(XrSubPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrSubPathClose(XrSubPath *path);
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
|
||||
|
||||
/* xrsurface.c */
|
||||
void
|
||||
|
|
@ -339,6 +332,26 @@ XrSurfaceSetVisual(XrSurface *surface, Visual *visual);
|
|||
void
|
||||
XrSurfaceSetFormat(XrSurface *surface, XrFormat format);
|
||||
|
||||
/* xrpolygon.c */
|
||||
void
|
||||
XrPolygonInit(XrPolygon *poly);
|
||||
|
||||
void
|
||||
XrPolygonDeinit(XrPolygon *poly);
|
||||
|
||||
void
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
/* xrstroke.c */
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps);
|
||||
|
||||
void
|
||||
XrStrokerDeinit(XrStroker *stroker);
|
||||
|
||||
void
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
/* xrtransform.c */
|
||||
void
|
||||
XrTransformInit(XrTransform *transform);
|
||||
|
|
@ -383,7 +396,6 @@ void
|
|||
XrTransformPoint(XrTransform *transform, XPointDouble *pt);
|
||||
|
||||
/* xrtraps.c */
|
||||
|
||||
XrTraps *
|
||||
XrTrapsCreate(void);
|
||||
|
||||
|
|
@ -397,25 +409,13 @@ void
|
|||
XrTrapsDestroy(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right);
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3]);
|
||||
|
||||
void
|
||||
XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointFixed q[4]);
|
||||
|
||||
void
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointDouble *tri);
|
||||
|
||||
void
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointDouble *quad);
|
||||
|
||||
void
|
||||
XrTrapsTessellatePath (XrTraps *traps, XrPath *path, int winding);
|
||||
|
||||
void
|
||||
XrTrapsTessellateSubPath (XrTraps *traps, XrSubPath *subpath, int winding);
|
||||
XrTrapsTessellatePolygon (XrTraps *traps, XrPolygon *poly, int winding);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
397
src/xrpath.c
397
src/xrpath.c
|
|
@ -1,37 +1,65 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xrint.h"
|
||||
|
||||
/* private functions */
|
||||
static void
|
||||
_XrPathAddSubPath(XrPath *path, XrSubPath *subpath);
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
|
||||
|
||||
void
|
||||
_XrPathNewOpBuf(XrPath *path);
|
||||
|
||||
static void
|
||||
_XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg);
|
||||
|
||||
void
|
||||
_XrPathNewArgBuf(XrPath *path);
|
||||
|
||||
XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void);
|
||||
|
||||
void
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *buf);
|
||||
|
||||
void
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op);
|
||||
|
||||
XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void);
|
||||
|
||||
void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *buf);
|
||||
|
||||
void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
|
||||
|
||||
static void
|
||||
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
|
||||
XrPath *
|
||||
XrPathCreate(void)
|
||||
|
|
@ -39,137 +67,340 @@ XrPathCreate(void)
|
|||
XrPath *path;
|
||||
|
||||
path = malloc(sizeof(XrPath));
|
||||
XrPathInit(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInit(XrPath *path)
|
||||
{
|
||||
path->head = NULL;
|
||||
path->tail = NULL;
|
||||
path->op_head = NULL;
|
||||
path->op_tail = NULL;
|
||||
|
||||
path->arg_head = NULL;
|
||||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInitCopy(XrPath *path, XrPath *other)
|
||||
{
|
||||
XrSubPath *subpath, *othersub;
|
||||
XrPathOpBuf *op, *other_op;
|
||||
XrPathArgBuf *arg, *other_arg;
|
||||
|
||||
XrPathInit(path);
|
||||
|
||||
for (othersub = other->head; othersub; othersub = othersub->next) {
|
||||
subpath = XrSubPathClone(othersub);
|
||||
_XrPathAddSubPath(path, subpath);
|
||||
for (other_op = other->op_head; other_op; other_op = other_op->next) {
|
||||
op = _XrPathOpBufCreate();
|
||||
*op = *other_op;
|
||||
_XrPathAddOpBuf(path, op);
|
||||
}
|
||||
|
||||
for (other_arg = other->arg_head; other_arg; other_arg = other_arg->next) {
|
||||
arg = _XrPathArgBufCreate();
|
||||
*arg = *other_arg;
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrPathDeinit(XrPath *path)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
XrPathOpBuf *op;
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
while (path->head) {
|
||||
subpath = path->head;
|
||||
path->head = subpath->next;
|
||||
XrSubPathDestroy(subpath);
|
||||
while (path->op_head) {
|
||||
op = path->op_head;
|
||||
path->op_head = op->next;
|
||||
_XrPathOpBufDestroy(op);
|
||||
}
|
||||
path->tail = NULL;
|
||||
path->op_tail = NULL;
|
||||
|
||||
while (path->arg_head) {
|
||||
arg = path->arg_head;
|
||||
path->arg_head = arg->next;
|
||||
_XrPathArgBufDestroy(arg);
|
||||
}
|
||||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path)
|
||||
{
|
||||
XrPathDeinit(path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
XrPath *
|
||||
XrPathClone(XrPath *path)
|
||||
static void
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
|
||||
{
|
||||
XrPath *clone;
|
||||
op->next = NULL;
|
||||
op->prev = path->op_tail;
|
||||
|
||||
clone = XrPathCreate();
|
||||
XrPathInitCopy(clone, path);
|
||||
return clone;
|
||||
if (path->op_tail) {
|
||||
path->op_tail->next = op;
|
||||
} else {
|
||||
path->op_head = op;
|
||||
}
|
||||
|
||||
path->op_tail = op;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathGetCurrentPoint(XrPath *path, XPointDouble *pt)
|
||||
_XrPathNewOpBuf(XrPath *path)
|
||||
{
|
||||
XrSubPathGetCurrentPoint(path->tail, pt);
|
||||
}
|
||||
XrPathOpBuf *op;
|
||||
|
||||
int
|
||||
XrPathNumSubPaths(XrPath *path)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
int num_subpaths;
|
||||
|
||||
num_subpaths = 0;
|
||||
for (subpath = path->head; subpath; subpath = subpath->next) {
|
||||
num_subpaths++;
|
||||
}
|
||||
|
||||
return num_subpaths;
|
||||
op = _XrPathOpBufCreate();
|
||||
_XrPathAddOpBuf(path, op);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrPathAddSubPath(XrPath *path, XrSubPath *subpath)
|
||||
_XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg)
|
||||
{
|
||||
subpath->next = NULL;
|
||||
arg->next = NULL;
|
||||
arg->prev = path->arg_tail;
|
||||
|
||||
if (path->tail) {
|
||||
path->tail->next = subpath;
|
||||
if (path->arg_tail) {
|
||||
path->arg_tail->next = arg;
|
||||
} else {
|
||||
path->head = subpath;
|
||||
path->arg_head = arg;
|
||||
}
|
||||
|
||||
path->tail = subpath;
|
||||
path->arg_tail = arg;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathNewSubPath(XrPath *path)
|
||||
_XrPathNewArgBuf(XrPath *path)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
subpath = XrSubPathCreate();
|
||||
_XrPathAddSubPath(path, subpath);
|
||||
arg = _XrPathArgBufCreate();
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewOpBuf(path);
|
||||
}
|
||||
_XrPathOpBufAdd(path->op_tail, op);
|
||||
|
||||
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewArgBuf(path);
|
||||
}
|
||||
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
|
||||
}
|
||||
|
||||
XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void)
|
||||
{
|
||||
XrPathOpBuf *op;
|
||||
|
||||
op = malloc(sizeof(XrPathOpBuf));
|
||||
|
||||
op->num_ops = 0;
|
||||
op->next = NULL;
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathAddPoint(XrPath *path, const XPointDouble *pt)
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *op)
|
||||
{
|
||||
XrSubPathAddPoint(path->tail, pt);
|
||||
op->num_ops = 0;
|
||||
free(op);
|
||||
}
|
||||
|
||||
void
|
||||
XrPathMoveTo(XrPath *path, const XPointDouble *pt)
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
op_buf->op[op_buf->num_ops++] = op;
|
||||
}
|
||||
|
||||
subpath = path->tail;
|
||||
XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void)
|
||||
{
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
if (subpath == NULL || subpath->num_pts > 1) {
|
||||
XrPathNewSubPath(path);
|
||||
XrPathAddPoint(path, pt);
|
||||
} else {
|
||||
XrSubPathSetCurrentPoint(subpath, pt);
|
||||
arg = malloc(sizeof(XrPathArgBuf));
|
||||
|
||||
arg->num_pts = 0;
|
||||
arg->next = NULL;
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *arg)
|
||||
{
|
||||
arg->num_pts = 0;
|
||||
free(arg);
|
||||
}
|
||||
|
||||
void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_pts; i++) {
|
||||
arg->pt[arg->num_pts++] = pts[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrPathLineTo(XrPath *path, const XPointDouble *pt)
|
||||
static void
|
||||
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
|
||||
{
|
||||
if (path->tail == NULL) {
|
||||
XrPathMoveTo(path, pt);
|
||||
} else {
|
||||
XrPathAddPoint(path, pt);
|
||||
}
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathClose(XrPath *path)
|
||||
XrPathStrokeTraps(XrPath *path, XrGState *gstate, XrTraps *traps)
|
||||
{
|
||||
if (path->tail) {
|
||||
XrSubPathClose(path->tail);
|
||||
XrPathNewSubPath(path);
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge };
|
||||
XrStroker stroker;
|
||||
|
||||
XrStrokerInit(&stroker, gstate, traps);
|
||||
|
||||
XrPathInterpret(path, XrPathDirectionForward, &cb, &stroker);
|
||||
|
||||
XrStrokerDeinit(&stroker);
|
||||
}
|
||||
|
||||
void
|
||||
XrPathFillTraps(XrPath *path, XrTraps *traps, int winding)
|
||||
{
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge };
|
||||
XrPolygon polygon;
|
||||
|
||||
XrPolygonInit(&polygon);
|
||||
|
||||
XrPathInterpret(path, XrPathDirectionForward, &cb, &polygon);
|
||||
XrTrapsTessellatePolygon(traps, &polygon, winding);
|
||||
|
||||
XrPolygonDeinit(&polygon);
|
||||
}
|
||||
|
||||
#define START_ARGS(n) \
|
||||
{ \
|
||||
if (dir != XrPathDirectionForward) \
|
||||
{ \
|
||||
if (arg_i == 0) { \
|
||||
arg_buf = arg_buf->prev; \
|
||||
arg_i = arg_buf->num_pts; \
|
||||
} \
|
||||
arg_i -= n; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NEXT_ARG(pt) \
|
||||
{ \
|
||||
(pt) = arg_buf->pt[arg_i]; \
|
||||
arg_i++; \
|
||||
if (arg_i >= arg_buf->num_pts) { \
|
||||
arg_buf = arg_buf->next; \
|
||||
arg_i = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define END_ARGS(n) \
|
||||
{ \
|
||||
if (dir != XrPathDirectionForward) \
|
||||
{ \
|
||||
arg_i -= n; \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure)
|
||||
{
|
||||
int i;
|
||||
XrPathOpBuf *op_buf;
|
||||
XrPathOp op;
|
||||
XrPathArgBuf *arg_buf = path->arg_head;
|
||||
int arg_i = 0;
|
||||
XPointFixed pt;
|
||||
XPointFixed current = {0, 0};
|
||||
XPointFixed first = {0, 0};
|
||||
int has_current = 0;
|
||||
int step = (dir == XrPathDirectionForward) ? 1 : -1;
|
||||
|
||||
for (op_buf = (dir == XrPathDirectionForward) ? path->op_head : path->op_tail;
|
||||
op_buf;
|
||||
op_buf = (dir == XrPathDirectionForward) ? op_buf->next : op_buf->prev)
|
||||
{
|
||||
int start, stop;
|
||||
if (dir == XrPathDirectionForward)
|
||||
{
|
||||
start = 0;
|
||||
stop = op_buf->num_ops;
|
||||
} else {
|
||||
start = op_buf->num_ops - 1;
|
||||
stop = -1;
|
||||
}
|
||||
|
||||
for (i=start; i != stop; i += step)
|
||||
{
|
||||
op = op_buf->op[i];
|
||||
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
break;
|
||||
case XrPathOpLineTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
current = pt;
|
||||
} else {
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
}
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
_TranslatePointFixed(&pt, ¤t);
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
break;
|
||||
case XrPathOpRelLineTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
_TranslatePointFixed(&pt, ¤t);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
current = pt;
|
||||
} else {
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
}
|
||||
break;
|
||||
case XrPathOpClosePath:
|
||||
(*cb->AddEdge)(closure, ¤t, &first);
|
||||
current.x = 0;
|
||||
current.y = 0;
|
||||
first.x = 0;
|
||||
first.y = 0;
|
||||
has_current = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
104
src/xrpolygon.c
Normal file
104
src/xrpolygon.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xrint.h"
|
||||
|
||||
#define XR_POLYGON_GROWTH_INC 10
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional);
|
||||
|
||||
void
|
||||
XrPolygonInit(XrPolygon *poly)
|
||||
{
|
||||
poly->num_edges = 0;
|
||||
|
||||
poly->edges_size = 0;
|
||||
poly->edges = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonDeinit(XrPolygon *poly)
|
||||
{
|
||||
if (poly->edges_size) {
|
||||
free(poly->edges);
|
||||
poly->edges_size = 0;
|
||||
poly->num_edges = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional)
|
||||
{
|
||||
XrEdge *new_edges;
|
||||
int old_size = poly->edges_size;
|
||||
int new_size = poly->num_edges + additional;
|
||||
|
||||
if (new_size <= poly->edges_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
poly->edges_size = new_size;
|
||||
new_edges = realloc(poly->edges, poly->edges_size * sizeof(XrEdge));
|
||||
|
||||
if (new_edges) {
|
||||
poly->edges = new_edges;
|
||||
} else {
|
||||
/* XXX: BUG: How do we really want to handle this out of memory error? */
|
||||
poly->edges_size = old_size;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrEdge *edge;
|
||||
XrPolygon *poly = closure;
|
||||
|
||||
/* drop horizontal edges */
|
||||
if (p1->y == p2->y) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (poly->num_edges >= poly->edges_size) {
|
||||
_XrPolygonGrowBy(poly, XR_POLYGON_GROWTH_INC);
|
||||
}
|
||||
|
||||
edge = &poly->edges[poly->num_edges];
|
||||
if (p1->y < p2->y) {
|
||||
edge->edge.p1 = *p1;
|
||||
edge->edge.p2 = *p2;
|
||||
edge->clockWise = True;
|
||||
} else {
|
||||
edge->edge.p1 = *p2;
|
||||
edge->edge.p2 = *p1;
|
||||
edge->clockWise = False;
|
||||
}
|
||||
|
||||
poly->num_edges++;
|
||||
}
|
||||
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xrint.h"
|
||||
|
|
|
|||
141
src/xrstroker.c
Normal file
141
src/xrstroker.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
/* private functions */
|
||||
static void
|
||||
_TranslatePoint(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps)
|
||||
{
|
||||
stroker->gstate = gstate;
|
||||
stroker->traps = traps;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerDeinit(XrStroker *stroker)
|
||||
{
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
static void
|
||||
_TranslatePoint(XPointFixed *pt, XPointFixed *offset)
|
||||
{
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrStroker *stroker = closure;
|
||||
XrGState *gstate = stroker->gstate;
|
||||
XrTraps *traps = stroker->traps;
|
||||
double mag, tmp;
|
||||
XPointDouble vector;
|
||||
XPointFixed offset;
|
||||
XPointFixed quad[4];
|
||||
|
||||
vector.x = XFixedToDouble(p2->x - p1->x);
|
||||
vector.y = XFixedToDouble(p2->y - p1->y);
|
||||
|
||||
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
|
||||
if (mag == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
vector.x /= mag;
|
||||
vector.y /= mag;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm_inverse, &vector);
|
||||
|
||||
tmp = vector.x;
|
||||
vector.x = vector.y * (gstate->line_width / 2.0);
|
||||
vector.y = - tmp * (gstate->line_width / 2.0);
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &vector);
|
||||
|
||||
offset.x = XDoubleToFixed(vector.x);
|
||||
offset.y = XDoubleToFixed(vector.y);
|
||||
|
||||
quad[0] = *p1;
|
||||
_TranslatePoint(&quad[0], &offset);
|
||||
quad[1] = *p2;
|
||||
_TranslatePoint(&quad[1], &offset);
|
||||
|
||||
offset.x = - offset.x;
|
||||
offset.y = - offset.y;
|
||||
|
||||
quad[2] = *p2;
|
||||
_TranslatePoint(&quad[2], &offset);
|
||||
quad[3] = *p1;
|
||||
_TranslatePoint(&quad[3], &offset);
|
||||
|
||||
XrTrapsTessellateConvexQuad(traps, quad);
|
||||
}
|
||||
|
||||
/* These functions aren't written yet... */
|
||||
#if 0
|
||||
static void
|
||||
_XrGStateStrokerCap(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_cap) {
|
||||
case XrLineCapRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapSquare:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapButt:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokerJoin(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2, const XPointDouble *p3,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_join) {
|
||||
case XrLineJoinMiter:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinBevel:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
|
|
|||
210
src/xrtraps.c
210
src/xrtraps.c
|
|
@ -28,26 +28,25 @@
|
|||
|
||||
#define XR_TRAPS_GROWTH_INC 10
|
||||
|
||||
typedef struct _Edge Edge;
|
||||
|
||||
struct _Edge {
|
||||
XLineFixed edge;
|
||||
XFixed current_x;
|
||||
XFixed next_x;
|
||||
Bool clockWise;
|
||||
Edge *next, *prev;
|
||||
};
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
_XrTrapsGrowBy(XrTraps *traps, int additional);
|
||||
|
||||
void
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right);
|
||||
|
||||
void
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
|
||||
static int
|
||||
_ComparePointFixedByY (const void *v1, const void *v2);
|
||||
|
||||
static int
|
||||
_CompareEdgeByTop (const void *v1, const void *v2);
|
||||
_CompareXrEdgeByTop (const void *v1, const void *v2);
|
||||
|
||||
static XFixed
|
||||
_ComputeX (XLineFixed *line, XFixed y);
|
||||
|
|
@ -61,12 +60,6 @@ _ComputeXIntercept (XLineFixed *l, double inverse_slope);
|
|||
static XFixed
|
||||
_ComputeIntersect (XLineFixed *l1, XLineFixed *l2);
|
||||
|
||||
static void
|
||||
_XrTrapsTessellateEdges (XrTraps *traps,
|
||||
Edge *edges,
|
||||
int nedges,
|
||||
int winding);
|
||||
|
||||
XrTraps *
|
||||
XrTrapsCreate(void)
|
||||
{
|
||||
|
|
@ -106,8 +99,8 @@ XrTrapsDestroy(XrTraps *traps)
|
|||
}
|
||||
|
||||
void
|
||||
XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right)
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right)
|
||||
{
|
||||
XTrapezoid *trap;
|
||||
|
||||
|
|
@ -129,9 +122,9 @@ XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
}
|
||||
|
||||
void
|
||||
XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
{
|
||||
XLineFixed left;
|
||||
XLineFixed right;
|
||||
|
|
@ -142,7 +135,7 @@ XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
right.p1 = right_p1;
|
||||
right.p2 = right_p2;
|
||||
|
||||
XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
_XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -180,132 +173,45 @@ _ComparePointFixedByY (const void *v1, const void *v2)
|
|||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointDouble *tri)
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3])
|
||||
{
|
||||
XPointFixed t[4];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
t[i].x = XDoubleToFixed(tri[i].x);
|
||||
t[i].y = XDoubleToFixed(tri[i].y);
|
||||
}
|
||||
|
||||
qsort(t, 3, sizeof(XPointFixed), _ComparePointFixedByY);
|
||||
|
||||
if (t[1].x > t[2].x) {
|
||||
XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[2], t[0], t[1]);
|
||||
XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[0], t[2], t[1], t[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[2], t[0], t[1]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[0], t[2], t[1], t[2]);
|
||||
} else {
|
||||
XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[1], t[0], t[2]);
|
||||
XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[1], t[2], t[0], t[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[1], t[0], t[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[1], t[2], t[0], t[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointDouble *quad)
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointFixed q[4])
|
||||
{
|
||||
XPointFixed q[4];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
q[i].x = XDoubleToFixed(quad[i].x);
|
||||
q[i].y = XDoubleToFixed(quad[i].y);
|
||||
}
|
||||
|
||||
qsort(q, 4, sizeof(XPointFixed), _ComparePointFixedByY);
|
||||
|
||||
if (q[1].x > q[2].x) {
|
||||
XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
} else {
|
||||
XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellatePath (XrTraps *traps, XrPath *path, int winding)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
|
||||
for (subpath = path->head; subpath; subpath = subpath->next) {
|
||||
XrTrapsTessellateSubPath(traps, subpath, winding);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellateSubPath (XrTraps *traps, XrSubPath *subpath, int winding)
|
||||
{
|
||||
Edge *edges;
|
||||
int i, nedges, npoints = subpath->num_pts;
|
||||
XFixed x, y, prevx = 0, prevy = 0, firstx = 0, firsty = 0;
|
||||
XFixed top = 0, bottom = 0; /* GCCism */
|
||||
|
||||
edges = (Edge *) Xmalloc (npoints * sizeof (Edge));
|
||||
if (!edges)
|
||||
return;
|
||||
|
||||
_XrTrapsGrowBy(traps, npoints * npoints);
|
||||
|
||||
/* XXX: CLEANUP: This code is still in the same form it was in
|
||||
when I brought it over from Xrender. The right thing to do here
|
||||
is to probably move the edge information into XrPath/XrSubPath
|
||||
and construct all edges during path construction. */
|
||||
nedges = 0;
|
||||
for (i = 0; i <= npoints; i++) {
|
||||
if (i == npoints) {
|
||||
x = firstx;
|
||||
y = firsty;
|
||||
}
|
||||
else {
|
||||
x = XDoubleToFixed (subpath->pts[i].x);
|
||||
y = XDoubleToFixed (subpath->pts[i].y);
|
||||
}
|
||||
if (i) {
|
||||
if (y < top) {
|
||||
top = y;
|
||||
} else if (y > bottom) {
|
||||
bottom = y;
|
||||
}
|
||||
if (prevy < y) {
|
||||
edges[nedges].edge.p1.x = prevx;
|
||||
edges[nedges].edge.p1.y = prevy;
|
||||
edges[nedges].edge.p2.x = x;
|
||||
edges[nedges].edge.p2.y = y;
|
||||
edges[nedges].clockWise = True;
|
||||
nedges++;
|
||||
}
|
||||
else if (prevy > y) {
|
||||
edges[nedges].edge.p1.x = x;
|
||||
edges[nedges].edge.p1.y = y;
|
||||
edges[nedges].edge.p2.x = prevx;
|
||||
edges[nedges].edge.p2.y = prevy;
|
||||
edges[nedges].clockWise = False;
|
||||
nedges++;
|
||||
}
|
||||
/* drop horizontal edges */
|
||||
} else {
|
||||
top = y;
|
||||
bottom = y;
|
||||
firstx = x;
|
||||
firsty = y;
|
||||
}
|
||||
prevx = x;
|
||||
prevy = y;
|
||||
}
|
||||
|
||||
_XrTrapsTessellateEdges (traps, edges, nedges, winding);
|
||||
Xfree (edges);
|
||||
}
|
||||
|
||||
static int
|
||||
_CompareEdgeByTop (const void *v1, const void *v2)
|
||||
_CompareXrEdgeByTop (const void *v1, const void *v2)
|
||||
{
|
||||
const Edge *e1 = v1, *e2 = v2;
|
||||
const XrEdge *e1 = v1, *e2 = v2;
|
||||
int ret;
|
||||
|
||||
return e1->edge.p1.y - e2->edge.p1.y;
|
||||
ret = e1->edge.p1.y - e2->edge.p1.y;
|
||||
if (ret == 0)
|
||||
ret = e1->edge.p1.x - e2->edge.p1.x;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static XFixed
|
||||
|
|
@ -349,27 +255,27 @@ _ComputeIntersect (XLineFixed *l1, XLineFixed *l2)
|
|||
return XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
}
|
||||
|
||||
static void
|
||||
_XrTrapsTessellateEdges (XrTraps *traps,
|
||||
Edge *edges,
|
||||
int nedges,
|
||||
int winding)
|
||||
void
|
||||
XrTrapsTessellatePolygon (XrTraps *traps,
|
||||
XrPolygon *poly,
|
||||
int winding)
|
||||
{
|
||||
int inactive;
|
||||
Edge *active;
|
||||
Edge *e, *en, *next;
|
||||
XrEdge *active;
|
||||
XrEdge *e, *en, *ep, *next;
|
||||
XFixed y, next_y, intersect;
|
||||
int in_out;
|
||||
int in_out, num_edges = poly->num_edges;
|
||||
XrEdge *edges = poly->edges;
|
||||
|
||||
qsort (edges, nedges, sizeof (Edge), _CompareEdgeByTop);
|
||||
qsort (edges, num_edges, sizeof (XrEdge), _CompareXrEdgeByTop);
|
||||
|
||||
y = edges[0].edge.p1.y;
|
||||
active = 0;
|
||||
inactive = 0;
|
||||
while (active || inactive < nedges)
|
||||
while (active || inactive < num_edges)
|
||||
{
|
||||
/* insert new active edges into list */
|
||||
while (inactive < nedges)
|
||||
while (inactive < num_edges)
|
||||
{
|
||||
e = &edges[inactive];
|
||||
if (e->edge.p1.y > y)
|
||||
|
|
@ -377,11 +283,21 @@ _XrTrapsTessellateEdges (XrTraps *traps,
|
|||
/* move this edge into the active list */
|
||||
inactive++;
|
||||
e->next_x = _ComputeX (&e->edge, y);
|
||||
e->next = active;
|
||||
e->prev = 0;
|
||||
if (active)
|
||||
active->prev = e;
|
||||
active = e;
|
||||
|
||||
/* insert e at sorted position */
|
||||
for (en=active, ep=0; en; ep=en, en=en->next)
|
||||
{
|
||||
if (en->next_x > e->next_x)
|
||||
break;
|
||||
}
|
||||
e->next = en;
|
||||
e->prev = ep;
|
||||
if (ep)
|
||||
ep->next = e;
|
||||
else
|
||||
active = e;
|
||||
if (en)
|
||||
en->prev = e;
|
||||
}
|
||||
|
||||
/* find next inflection point */
|
||||
|
|
@ -402,7 +318,7 @@ _XrTrapsTessellateEdges (XrTraps *traps,
|
|||
}
|
||||
}
|
||||
/* check next inactive point */
|
||||
if (inactive < nedges && edges[inactive].edge.p1.y < next_y)
|
||||
if (inactive < num_edges && edges[inactive].edge.p1.y < next_y)
|
||||
next_y = edges[inactive].edge.p1.y;
|
||||
|
||||
/* compute x coordinates along this group */
|
||||
|
|
@ -479,7 +395,7 @@ _XrTrapsTessellateEdges (XrTraps *traps,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
_XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
}
|
||||
|
||||
y = next_y;
|
||||
|
|
|
|||
41
xr.c
41
xr.c
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
|
|
@ -139,25 +136,25 @@ XrNewPath(XrState *xrs)
|
|||
void
|
||||
XrMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateMoveTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpMoveTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
XrLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateLineTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpLineTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
XrRelMoveTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateRelMoveTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelMoveTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
XrRelLineTo(XrState *xrs, double x, double y)
|
||||
{
|
||||
XrGStateRelLineTo(CURRENT_GSTATE(xrs), x, y);
|
||||
XrGStateAddUnaryPathOp(CURRENT_GSTATE(xrs), XrPathOpRelLineTo, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
33
xrcolor.c
33
xrcolor.c
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
|
|
|
|||
289
xrgstate.c
289
xrgstate.c
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
|
@ -35,33 +32,6 @@
|
|||
static XrGState *
|
||||
_XrGStateAlloc(void);
|
||||
|
||||
static void
|
||||
_TranslatePoint(XPointDouble *pt, const XPointDouble *offset);
|
||||
|
||||
static void
|
||||
_XrGStateStrokePath(XrGState *gstate, XrPath *path, XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSubPath(XrGState *gstate, XrSubPath *subpath, XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeCap(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeJoin(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSegment(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps);
|
||||
|
||||
static void
|
||||
_XrGStateFillPath(XrGState *gstate, XrPath *path);
|
||||
|
||||
static XrGState *
|
||||
_XrGStateAlloc(void)
|
||||
{
|
||||
|
|
@ -136,7 +106,7 @@ XrGStateDestroy(XrGState *gstate)
|
|||
free(gstate);
|
||||
}
|
||||
|
||||
XrGState *
|
||||
XrGState*
|
||||
XrGStateClone(XrGState *gstate)
|
||||
{
|
||||
XrGState *clone;
|
||||
|
|
@ -147,12 +117,6 @@ XrGStateClone(XrGState *gstate)
|
|||
return clone;
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt)
|
||||
{
|
||||
XrPathGetCurrentPoint(&gstate->path, pt);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
|
||||
{
|
||||
|
|
@ -258,68 +222,38 @@ XrGStateNewPath(XrGState *gstate)
|
|||
}
|
||||
|
||||
void
|
||||
XrGStateMoveTo(XrGState *gstate, double x, double y)
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y)
|
||||
{
|
||||
XPointDouble pt;
|
||||
XPointFixed pt_fixed;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
XrPathMoveTo(&gstate->path, &pt);
|
||||
}
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
case XrPathOpLineTo:
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
case XrPathOpRelLineTo:
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
break;
|
||||
default:
|
||||
/* Invalid */
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateLineTo(XrGState *gstate, double x, double y)
|
||||
{
|
||||
XPointDouble pt;
|
||||
pt_fixed.x = XDoubleToFixed(pt.x);
|
||||
pt_fixed.y = XDoubleToFixed(pt.y);
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPoint(&gstate->ctm, &pt);
|
||||
XrPathLineTo(&gstate->path, &pt);
|
||||
}
|
||||
|
||||
static void
|
||||
_TranslatePoint(XPointDouble *pt, const XPointDouble *offset)
|
||||
{
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateRelMoveTo(XrGState *gstate, double x, double y)
|
||||
{
|
||||
XPointDouble pt, current;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
XrGStateGetCurrentPoint(gstate, ¤t);
|
||||
_TranslatePoint(&pt, ¤t);
|
||||
XrPathMoveTo(&gstate->path, &pt);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateRelLineTo(XrGState *gstate, double x, double y)
|
||||
{
|
||||
XPointDouble pt, current;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &pt);
|
||||
XrGStateGetCurrentPoint(gstate, ¤t);
|
||||
_TranslatePoint(&pt, ¤t);
|
||||
XrPathLineTo(&gstate->path, &pt);
|
||||
XrPathAdd(&gstate->path, op, &pt_fixed, 1);
|
||||
}
|
||||
|
||||
void
|
||||
XrGStateClosePath(XrGState *gstate)
|
||||
{
|
||||
XrPathClose(&gstate->path);
|
||||
XrPathAdd(&gstate->path, XrPathOpClosePath, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -329,7 +263,7 @@ XrGStateStroke(XrGState *gstate)
|
|||
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
_XrGStateStrokePath(gstate, &gstate->path, &traps);
|
||||
XrPathStrokeTraps(&gstate->path, gstate, &traps);
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
|
|
@ -345,157 +279,13 @@ XrGStateStroke(XrGState *gstate)
|
|||
|
||||
void
|
||||
XrGStateFill(XrGState *gstate)
|
||||
{
|
||||
_XrGStateFillPath(gstate, &gstate->path);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokePath(XrGState *gstate, XrPath *path, XrTraps *traps)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
|
||||
for (subpath = path->head; subpath; subpath = subpath->next) {
|
||||
if (subpath->num_pts) {
|
||||
_XrGStateStrokeSubPath(gstate, subpath, traps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSubPath(XrGState *gstate, XrSubPath *subpath, XrTraps *traps)
|
||||
{
|
||||
int i;
|
||||
XPointDouble *pt_prev, *pt, *pt_next;
|
||||
|
||||
/* XXX: BUG: Need to consider degenerate paths here, (all paths
|
||||
less then 3 points may need special consideration) */
|
||||
|
||||
/* Stroke initial cap or join */
|
||||
pt_prev = subpath->pts + subpath->num_pts - 1;
|
||||
pt = subpath->pts;
|
||||
pt_next = pt + 1;
|
||||
if (subpath->closed) {
|
||||
_XrGStateStrokeJoin(gstate, pt_prev, pt, pt_next, traps);
|
||||
} else {
|
||||
_XrGStateStrokeCap(gstate, pt_next, pt, traps);
|
||||
}
|
||||
_XrGStateStrokeSegment(gstate, pt, pt_next, traps);
|
||||
|
||||
/* Stroke path segments */
|
||||
for (i = 1; i < subpath->num_pts - 1; i++) {
|
||||
pt_prev = pt;
|
||||
pt = pt_next;
|
||||
pt_next++;
|
||||
|
||||
_XrGStateStrokeJoin(gstate, pt_prev, pt, pt_next, traps);
|
||||
_XrGStateStrokeSegment(gstate, pt, pt_next, traps);
|
||||
}
|
||||
|
||||
/* Close path or add final cap as necessary */
|
||||
pt_prev = pt;
|
||||
pt = pt_next;
|
||||
pt_next = subpath->pts;
|
||||
if (subpath->closed) {
|
||||
_XrGStateStrokeJoin(gstate, pt_prev, pt, pt_next, traps);
|
||||
_XrGStateStrokeSegment(gstate, pt, pt_next, traps);
|
||||
} else {
|
||||
_XrGStateStrokeCap(gstate, pt_prev, pt, traps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeCap(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_cap) {
|
||||
case XrLineCapRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapSquare:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapButt:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeJoin(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_join) {
|
||||
case XrLineJoinMiter:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinBevel:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokeSegment(XrGState *gstate,
|
||||
const XPointDouble *p0, const XPointDouble *p1,
|
||||
XrTraps *traps)
|
||||
{
|
||||
double mag, tmp;
|
||||
XPointDouble offset;
|
||||
XPointDouble quad[4];
|
||||
|
||||
offset.x = p1->x - p0->x;
|
||||
offset.y = p1->y - p0->y;
|
||||
|
||||
mag = sqrt(offset.x * offset.x + offset.y * offset.y);
|
||||
if (mag == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
offset.x /= mag;
|
||||
offset.y /= mag;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm_inverse, &offset);
|
||||
|
||||
tmp = offset.x;
|
||||
offset.x = offset.y * (gstate->line_width / 2.0);
|
||||
offset.y = - tmp * (gstate->line_width / 2.0);
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &offset);
|
||||
|
||||
quad[0] = *p0;
|
||||
_TranslatePoint(&quad[0], &offset);
|
||||
quad[1] = *p1;
|
||||
_TranslatePoint(&quad[1], &offset);
|
||||
|
||||
offset.x = - offset.x;
|
||||
offset.y = - offset.y;
|
||||
|
||||
quad[2] = *p1;
|
||||
_TranslatePoint(&quad[2], &offset);
|
||||
quad[3] = *p0;
|
||||
_TranslatePoint(&quad[3], &offset);
|
||||
|
||||
XrTrapsTessellateConvexQuad(traps, quad);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateFillPath(XrGState *gstate, XrPath *path)
|
||||
{
|
||||
XrTraps traps;
|
||||
|
||||
XrTrapsInit(&traps);
|
||||
|
||||
XrTrapsTessellatePath(&traps, path, gstate->winding);
|
||||
XrPathFillTraps(&gstate->path, &traps, gstate->winding);
|
||||
|
||||
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
|
||||
gstate->src.xcsurface, gstate->surface.xcsurface,
|
||||
gstate->alphaFormat,
|
||||
|
|
@ -504,6 +294,7 @@ _XrGStateFillPath(XrGState *gstate, XrPath *path)
|
|||
traps.num_xtraps);
|
||||
|
||||
XrTrapsDeinit(&traps);
|
||||
|
||||
XrGStateNewPath(gstate);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
220
xrint.h
220
xrint.h
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These definitions are solely for use by the implementation of Xr
|
||||
|
|
@ -37,23 +34,72 @@
|
|||
#ifndef _XRINT_H_
|
||||
#define _XRINT_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include "Xr.h"
|
||||
|
||||
typedef struct _XrSubPath {
|
||||
int num_pts;
|
||||
int pts_size;
|
||||
XPointDouble *pts;
|
||||
int closed;
|
||||
#ifndef __GCC__
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
struct _XrSubPath *next;
|
||||
} XrSubPath;
|
||||
typedef enum _XrPathOp {
|
||||
XrPathOpMoveTo,
|
||||
XrPathOpLineTo,
|
||||
XrPathOpRelMoveTo,
|
||||
XrPathOpRelLineTo,
|
||||
XrPathOpClosePath
|
||||
} __attribute__ ((packed)) XrPathOp; /* Don't want 32 bits if we can avoid it. */
|
||||
|
||||
typedef enum _XrPathDirection {
|
||||
XrPathDirectionForward,
|
||||
XrPathDirectionReverse
|
||||
} XrPathDirection;
|
||||
|
||||
typedef struct _XrPathCallbacks {
|
||||
void (*AddEdge)(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
} XrPathCallbacks;
|
||||
|
||||
#define XR_PATH_BUF_SZ 64
|
||||
|
||||
typedef struct _XrPathOpBuf {
|
||||
int num_ops;
|
||||
XrPathOp op[XR_PATH_BUF_SZ];
|
||||
|
||||
struct _XrPathOpBuf *next, *prev;
|
||||
} XrPathOpBuf;
|
||||
|
||||
typedef struct _XrPathArgBuf {
|
||||
int num_pts;
|
||||
XPointFixed pt[XR_PATH_BUF_SZ];
|
||||
|
||||
struct _XrPathArgBuf *next, *prev;
|
||||
} XrPathArgBuf;
|
||||
|
||||
typedef struct _XrPath {
|
||||
XrSubPath *head;
|
||||
XrSubPath *tail;
|
||||
XrPathOpBuf *op_head;
|
||||
XrPathOpBuf *op_tail;
|
||||
|
||||
XrPathArgBuf *arg_head;
|
||||
XrPathArgBuf *arg_tail;
|
||||
} XrPath;
|
||||
|
||||
typedef struct _XrEdge {
|
||||
/* Externally initialized */
|
||||
XLineFixed edge;
|
||||
Bool clockWise;
|
||||
|
||||
/* Internal use by XrTrapsTessellateEdges */
|
||||
XFixed current_x;
|
||||
XFixed next_x;
|
||||
struct _XrEdge *next, *prev;
|
||||
} XrEdge;
|
||||
|
||||
typedef struct _XrPolygon {
|
||||
int num_edges;
|
||||
int edges_size;
|
||||
XrEdge *edges;
|
||||
} XrPolygon;
|
||||
|
||||
typedef struct _XrSurface {
|
||||
Display *dpy;
|
||||
|
||||
|
|
@ -90,7 +136,7 @@ typedef struct _XrTraps {
|
|||
|
||||
#define XR_GSTATE_OPERATOR_DEFAULT XrOperatorOver
|
||||
#define XR_GSTATE_WINDING_DEFAULT 1
|
||||
#define XR_GSTATE_LINE_WIDTH_DEFAULT 1.0
|
||||
#define XR_GSTATE_LINE_WIDTH_DEFAULT 2.0
|
||||
#define XR_GSTATE_LINE_CAP_DEFAULT XrLineCapButt
|
||||
#define XR_GSTATE_LINE_JOIN_DEFAULT XrLineJoinMiter
|
||||
#define XR_GSTATE_MITER_LIMIT_DEFAULT 10.0
|
||||
|
|
@ -126,6 +172,11 @@ struct _XrState {
|
|||
XrGState *stack;
|
||||
};
|
||||
|
||||
typedef struct _XrStroker {
|
||||
XrGState *gstate;
|
||||
XrTraps *traps;
|
||||
} XrStroker;
|
||||
|
||||
/* xrstate.c */
|
||||
|
||||
#define CURRENT_GSTATE(xrs) (xrs->stack)
|
||||
|
|
@ -152,9 +203,6 @@ XrStatePop(XrState *xrs);
|
|||
XrGState *
|
||||
XrGStateCreate(Display *dpy);
|
||||
|
||||
XrGState *
|
||||
XrGStateClone(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateInit(XrGState *gstate, Display *dpy);
|
||||
|
||||
|
|
@ -167,8 +215,8 @@ XrGStateDeinit(XrGState *gstate);
|
|||
void
|
||||
XrGStateDestroy(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt);
|
||||
XrGState *
|
||||
XrGStateClone(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateSetDrawable(XrGState *gstate, Drawable drawable);
|
||||
|
|
@ -213,16 +261,7 @@ void
|
|||
XrGStateNewPath(XrGState *gstate);
|
||||
|
||||
void
|
||||
XrGStateMoveTo(XrGState *gstate, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateLineTo(XrGState *gstate, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateRelMoveTo(XrGState *gstate, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateRelLineTo(XrGState *gstate, double x, double y);
|
||||
XrGStateAddUnaryPathOp(XrGState *gstate, XrPathOp op, double x, double y);
|
||||
|
||||
void
|
||||
XrGStateClosePath(XrGState *gstate);
|
||||
|
|
@ -256,69 +295,23 @@ XrPathInit(XrPath *path);
|
|||
void
|
||||
XrPathInitCopy(XrPath *path, XrPath *other);
|
||||
|
||||
void
|
||||
XrPathReinit(XrPath *path);
|
||||
|
||||
void
|
||||
XrPathDeinit(XrPath *path);
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path);
|
||||
|
||||
XrPath *
|
||||
XrPathClone(XrPath *path);
|
||||
void
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts);
|
||||
|
||||
void
|
||||
XrPathGetCurrentPoint(XrPath *path, XPointDouble *pt);
|
||||
|
||||
int
|
||||
XrPathNumSubPaths(XrPath *path);
|
||||
XrPathStrokeTraps(XrPath *path, XrGState *gstate, XrTraps *traps);
|
||||
|
||||
void
|
||||
XrPathNewSubPath(XrPath *path);
|
||||
XrPathFillTraps(XrPath *path, XrTraps *traps, int winding);
|
||||
|
||||
void
|
||||
XrPathAddPoint(XrPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrPathMoveTo(XrPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrPathLineTo(XrPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrPathClose(XrPath *path);
|
||||
|
||||
/* xrsubpath.c */
|
||||
XrSubPath *
|
||||
XrSubPathCreate(void);
|
||||
|
||||
void
|
||||
XrSubPathInit(XrSubPath *path);
|
||||
|
||||
void
|
||||
XrSubPathInitCopy(XrSubPath *path, XrSubPath *other);
|
||||
|
||||
void
|
||||
XrSubPathDeinit(XrSubPath *path);
|
||||
|
||||
void
|
||||
XrSubPathDestroy(XrSubPath *path);
|
||||
|
||||
XrSubPath *
|
||||
XrSubPathClone(XrSubPath *path);
|
||||
|
||||
void
|
||||
XrSubPathGetCurrentPoint(XrSubPath *path, XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrSubPathSetCurrentPoint(XrSubPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrSubPathAddPoint(XrSubPath *path, const XPointDouble *pt);
|
||||
|
||||
void
|
||||
XrSubPathClose(XrSubPath *path);
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
|
||||
|
||||
/* xrsurface.c */
|
||||
void
|
||||
|
|
@ -339,6 +332,26 @@ XrSurfaceSetVisual(XrSurface *surface, Visual *visual);
|
|||
void
|
||||
XrSurfaceSetFormat(XrSurface *surface, XrFormat format);
|
||||
|
||||
/* xrpolygon.c */
|
||||
void
|
||||
XrPolygonInit(XrPolygon *poly);
|
||||
|
||||
void
|
||||
XrPolygonDeinit(XrPolygon *poly);
|
||||
|
||||
void
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
/* xrstroke.c */
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps);
|
||||
|
||||
void
|
||||
XrStrokerDeinit(XrStroker *stroker);
|
||||
|
||||
void
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
/* xrtransform.c */
|
||||
void
|
||||
XrTransformInit(XrTransform *transform);
|
||||
|
|
@ -383,7 +396,6 @@ void
|
|||
XrTransformPoint(XrTransform *transform, XPointDouble *pt);
|
||||
|
||||
/* xrtraps.c */
|
||||
|
||||
XrTraps *
|
||||
XrTrapsCreate(void);
|
||||
|
||||
|
|
@ -397,25 +409,13 @@ void
|
|||
XrTrapsDestroy(XrTraps *traps);
|
||||
|
||||
void
|
||||
XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right);
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3]);
|
||||
|
||||
void
|
||||
XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointFixed q[4]);
|
||||
|
||||
void
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointDouble *tri);
|
||||
|
||||
void
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointDouble *quad);
|
||||
|
||||
void
|
||||
XrTrapsTessellatePath (XrTraps *traps, XrPath *path, int winding);
|
||||
|
||||
void
|
||||
XrTrapsTessellateSubPath (XrTraps *traps, XrSubPath *subpath, int winding);
|
||||
XrTrapsTessellatePolygon (XrTraps *traps, XrPolygon *poly, int winding);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
397
xrpath.c
397
xrpath.c
|
|
@ -1,37 +1,65 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xrint.h"
|
||||
|
||||
/* private functions */
|
||||
static void
|
||||
_XrPathAddSubPath(XrPath *path, XrSubPath *subpath);
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op);
|
||||
|
||||
void
|
||||
_XrPathNewOpBuf(XrPath *path);
|
||||
|
||||
static void
|
||||
_XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg);
|
||||
|
||||
void
|
||||
_XrPathNewArgBuf(XrPath *path);
|
||||
|
||||
XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void);
|
||||
|
||||
void
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *buf);
|
||||
|
||||
void
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op);
|
||||
|
||||
XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void);
|
||||
|
||||
void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *buf);
|
||||
|
||||
void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts);
|
||||
|
||||
static void
|
||||
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
|
||||
XrPath *
|
||||
XrPathCreate(void)
|
||||
|
|
@ -39,137 +67,340 @@ XrPathCreate(void)
|
|||
XrPath *path;
|
||||
|
||||
path = malloc(sizeof(XrPath));
|
||||
XrPathInit(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInit(XrPath *path)
|
||||
{
|
||||
path->head = NULL;
|
||||
path->tail = NULL;
|
||||
path->op_head = NULL;
|
||||
path->op_tail = NULL;
|
||||
|
||||
path->arg_head = NULL;
|
||||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInitCopy(XrPath *path, XrPath *other)
|
||||
{
|
||||
XrSubPath *subpath, *othersub;
|
||||
XrPathOpBuf *op, *other_op;
|
||||
XrPathArgBuf *arg, *other_arg;
|
||||
|
||||
XrPathInit(path);
|
||||
|
||||
for (othersub = other->head; othersub; othersub = othersub->next) {
|
||||
subpath = XrSubPathClone(othersub);
|
||||
_XrPathAddSubPath(path, subpath);
|
||||
for (other_op = other->op_head; other_op; other_op = other_op->next) {
|
||||
op = _XrPathOpBufCreate();
|
||||
*op = *other_op;
|
||||
_XrPathAddOpBuf(path, op);
|
||||
}
|
||||
|
||||
for (other_arg = other->arg_head; other_arg; other_arg = other_arg->next) {
|
||||
arg = _XrPathArgBufCreate();
|
||||
*arg = *other_arg;
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrPathDeinit(XrPath *path)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
XrPathOpBuf *op;
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
while (path->head) {
|
||||
subpath = path->head;
|
||||
path->head = subpath->next;
|
||||
XrSubPathDestroy(subpath);
|
||||
while (path->op_head) {
|
||||
op = path->op_head;
|
||||
path->op_head = op->next;
|
||||
_XrPathOpBufDestroy(op);
|
||||
}
|
||||
path->tail = NULL;
|
||||
path->op_tail = NULL;
|
||||
|
||||
while (path->arg_head) {
|
||||
arg = path->arg_head;
|
||||
path->arg_head = arg->next;
|
||||
_XrPathArgBufDestroy(arg);
|
||||
}
|
||||
path->arg_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathDestroy(XrPath *path)
|
||||
{
|
||||
XrPathDeinit(path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
XrPath *
|
||||
XrPathClone(XrPath *path)
|
||||
static void
|
||||
_XrPathAddOpBuf(XrPath *path, XrPathOpBuf *op)
|
||||
{
|
||||
XrPath *clone;
|
||||
op->next = NULL;
|
||||
op->prev = path->op_tail;
|
||||
|
||||
clone = XrPathCreate();
|
||||
XrPathInitCopy(clone, path);
|
||||
return clone;
|
||||
if (path->op_tail) {
|
||||
path->op_tail->next = op;
|
||||
} else {
|
||||
path->op_head = op;
|
||||
}
|
||||
|
||||
path->op_tail = op;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathGetCurrentPoint(XrPath *path, XPointDouble *pt)
|
||||
_XrPathNewOpBuf(XrPath *path)
|
||||
{
|
||||
XrSubPathGetCurrentPoint(path->tail, pt);
|
||||
}
|
||||
XrPathOpBuf *op;
|
||||
|
||||
int
|
||||
XrPathNumSubPaths(XrPath *path)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
int num_subpaths;
|
||||
|
||||
num_subpaths = 0;
|
||||
for (subpath = path->head; subpath; subpath = subpath->next) {
|
||||
num_subpaths++;
|
||||
}
|
||||
|
||||
return num_subpaths;
|
||||
op = _XrPathOpBufCreate();
|
||||
_XrPathAddOpBuf(path, op);
|
||||
}
|
||||
|
||||
static void
|
||||
_XrPathAddSubPath(XrPath *path, XrSubPath *subpath)
|
||||
_XrPathAddArgBuf(XrPath *path, XrPathArgBuf *arg)
|
||||
{
|
||||
subpath->next = NULL;
|
||||
arg->next = NULL;
|
||||
arg->prev = path->arg_tail;
|
||||
|
||||
if (path->tail) {
|
||||
path->tail->next = subpath;
|
||||
if (path->arg_tail) {
|
||||
path->arg_tail->next = arg;
|
||||
} else {
|
||||
path->head = subpath;
|
||||
path->arg_head = arg;
|
||||
}
|
||||
|
||||
path->tail = subpath;
|
||||
path->arg_tail = arg;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathNewSubPath(XrPath *path)
|
||||
_XrPathNewArgBuf(XrPath *path)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
subpath = XrSubPathCreate();
|
||||
_XrPathAddSubPath(path, subpath);
|
||||
arg = _XrPathArgBufCreate();
|
||||
_XrPathAddArgBuf(path, arg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XrPathAdd(XrPath *path, XrPathOp op, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
if (path->op_tail == NULL || path->op_tail->num_ops + 1 > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewOpBuf(path);
|
||||
}
|
||||
_XrPathOpBufAdd(path->op_tail, op);
|
||||
|
||||
if (path->arg_tail == NULL || path->arg_tail->num_pts + num_pts > XR_PATH_BUF_SZ) {
|
||||
_XrPathNewArgBuf(path);
|
||||
}
|
||||
_XrPathArgBufAdd(path->arg_tail, pts, num_pts);
|
||||
}
|
||||
|
||||
XrPathOpBuf *
|
||||
_XrPathOpBufCreate(void)
|
||||
{
|
||||
XrPathOpBuf *op;
|
||||
|
||||
op = malloc(sizeof(XrPathOpBuf));
|
||||
|
||||
op->num_ops = 0;
|
||||
op->next = NULL;
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathAddPoint(XrPath *path, const XPointDouble *pt)
|
||||
_XrPathOpBufDestroy(XrPathOpBuf *op)
|
||||
{
|
||||
XrSubPathAddPoint(path->tail, pt);
|
||||
op->num_ops = 0;
|
||||
free(op);
|
||||
}
|
||||
|
||||
void
|
||||
XrPathMoveTo(XrPath *path, const XPointDouble *pt)
|
||||
_XrPathOpBufAdd(XrPathOpBuf *op_buf, XrPathOp op)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
op_buf->op[op_buf->num_ops++] = op;
|
||||
}
|
||||
|
||||
subpath = path->tail;
|
||||
XrPathArgBuf *
|
||||
_XrPathArgBufCreate(void)
|
||||
{
|
||||
XrPathArgBuf *arg;
|
||||
|
||||
if (subpath == NULL || subpath->num_pts > 1) {
|
||||
XrPathNewSubPath(path);
|
||||
XrPathAddPoint(path, pt);
|
||||
} else {
|
||||
XrSubPathSetCurrentPoint(subpath, pt);
|
||||
arg = malloc(sizeof(XrPathArgBuf));
|
||||
|
||||
arg->num_pts = 0;
|
||||
arg->next = NULL;
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
void
|
||||
_XrPathArgBufDestroy(XrPathArgBuf *arg)
|
||||
{
|
||||
arg->num_pts = 0;
|
||||
free(arg);
|
||||
}
|
||||
|
||||
void
|
||||
_XrPathArgBufAdd(XrPathArgBuf *arg, XPointFixed *pts, int num_pts)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_pts; i++) {
|
||||
arg->pt[arg->num_pts++] = pts[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrPathLineTo(XrPath *path, const XPointDouble *pt)
|
||||
static void
|
||||
_TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
|
||||
{
|
||||
if (path->tail == NULL) {
|
||||
XrPathMoveTo(path, pt);
|
||||
} else {
|
||||
XrPathAddPoint(path, pt);
|
||||
}
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrPathClose(XrPath *path)
|
||||
XrPathStrokeTraps(XrPath *path, XrGState *gstate, XrTraps *traps)
|
||||
{
|
||||
if (path->tail) {
|
||||
XrSubPathClose(path->tail);
|
||||
XrPathNewSubPath(path);
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge };
|
||||
XrStroker stroker;
|
||||
|
||||
XrStrokerInit(&stroker, gstate, traps);
|
||||
|
||||
XrPathInterpret(path, XrPathDirectionForward, &cb, &stroker);
|
||||
|
||||
XrStrokerDeinit(&stroker);
|
||||
}
|
||||
|
||||
void
|
||||
XrPathFillTraps(XrPath *path, XrTraps *traps, int winding)
|
||||
{
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge };
|
||||
XrPolygon polygon;
|
||||
|
||||
XrPolygonInit(&polygon);
|
||||
|
||||
XrPathInterpret(path, XrPathDirectionForward, &cb, &polygon);
|
||||
XrTrapsTessellatePolygon(traps, &polygon, winding);
|
||||
|
||||
XrPolygonDeinit(&polygon);
|
||||
}
|
||||
|
||||
#define START_ARGS(n) \
|
||||
{ \
|
||||
if (dir != XrPathDirectionForward) \
|
||||
{ \
|
||||
if (arg_i == 0) { \
|
||||
arg_buf = arg_buf->prev; \
|
||||
arg_i = arg_buf->num_pts; \
|
||||
} \
|
||||
arg_i -= n; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NEXT_ARG(pt) \
|
||||
{ \
|
||||
(pt) = arg_buf->pt[arg_i]; \
|
||||
arg_i++; \
|
||||
if (arg_i >= arg_buf->num_pts) { \
|
||||
arg_buf = arg_buf->next; \
|
||||
arg_i = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define END_ARGS(n) \
|
||||
{ \
|
||||
if (dir != XrPathDirectionForward) \
|
||||
{ \
|
||||
arg_i -= n; \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure)
|
||||
{
|
||||
int i;
|
||||
XrPathOpBuf *op_buf;
|
||||
XrPathOp op;
|
||||
XrPathArgBuf *arg_buf = path->arg_head;
|
||||
int arg_i = 0;
|
||||
XPointFixed pt;
|
||||
XPointFixed current = {0, 0};
|
||||
XPointFixed first = {0, 0};
|
||||
int has_current = 0;
|
||||
int step = (dir == XrPathDirectionForward) ? 1 : -1;
|
||||
|
||||
for (op_buf = (dir == XrPathDirectionForward) ? path->op_head : path->op_tail;
|
||||
op_buf;
|
||||
op_buf = (dir == XrPathDirectionForward) ? op_buf->next : op_buf->prev)
|
||||
{
|
||||
int start, stop;
|
||||
if (dir == XrPathDirectionForward)
|
||||
{
|
||||
start = 0;
|
||||
stop = op_buf->num_ops;
|
||||
} else {
|
||||
start = op_buf->num_ops - 1;
|
||||
stop = -1;
|
||||
}
|
||||
|
||||
for (i=start; i != stop; i += step)
|
||||
{
|
||||
op = op_buf->op[i];
|
||||
|
||||
switch (op) {
|
||||
case XrPathOpMoveTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
break;
|
||||
case XrPathOpLineTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
current = pt;
|
||||
} else {
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
}
|
||||
break;
|
||||
case XrPathOpRelMoveTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
_TranslatePointFixed(&pt, ¤t);
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
break;
|
||||
case XrPathOpRelLineTo:
|
||||
START_ARGS(1);
|
||||
NEXT_ARG(pt);
|
||||
END_ARGS(1);
|
||||
_TranslatePointFixed(&pt, ¤t);
|
||||
if (has_current) {
|
||||
(*cb->AddEdge)(closure, ¤t, &pt);
|
||||
current = pt;
|
||||
} else {
|
||||
first = pt;
|
||||
current = pt;
|
||||
has_current = 1;
|
||||
}
|
||||
break;
|
||||
case XrPathOpClosePath:
|
||||
(*cb->AddEdge)(closure, ¤t, &first);
|
||||
current.x = 0;
|
||||
current.y = 0;
|
||||
first.x = 0;
|
||||
first.y = 0;
|
||||
has_current = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
104
xrpolygon.c
Normal file
104
xrpolygon.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xrint.h"
|
||||
|
||||
#define XR_POLYGON_GROWTH_INC 10
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional);
|
||||
|
||||
void
|
||||
XrPolygonInit(XrPolygon *poly)
|
||||
{
|
||||
poly->num_edges = 0;
|
||||
|
||||
poly->edges_size = 0;
|
||||
poly->edges = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonDeinit(XrPolygon *poly)
|
||||
{
|
||||
if (poly->edges_size) {
|
||||
free(poly->edges);
|
||||
poly->edges_size = 0;
|
||||
poly->num_edges = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrPolygonGrowBy(XrPolygon *poly, int additional)
|
||||
{
|
||||
XrEdge *new_edges;
|
||||
int old_size = poly->edges_size;
|
||||
int new_size = poly->num_edges + additional;
|
||||
|
||||
if (new_size <= poly->edges_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
poly->edges_size = new_size;
|
||||
new_edges = realloc(poly->edges, poly->edges_size * sizeof(XrEdge));
|
||||
|
||||
if (new_edges) {
|
||||
poly->edges = new_edges;
|
||||
} else {
|
||||
/* XXX: BUG: How do we really want to handle this out of memory error? */
|
||||
poly->edges_size = old_size;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrEdge *edge;
|
||||
XrPolygon *poly = closure;
|
||||
|
||||
/* drop horizontal edges */
|
||||
if (p1->y == p2->y) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (poly->num_edges >= poly->edges_size) {
|
||||
_XrPolygonGrowBy(poly, XR_POLYGON_GROWTH_INC);
|
||||
}
|
||||
|
||||
edge = &poly->edges[poly->num_edges];
|
||||
if (p1->y < p2->y) {
|
||||
edge->edge.p1 = *p1;
|
||||
edge->edge.p2 = *p2;
|
||||
edge->clockWise = True;
|
||||
} else {
|
||||
edge->edge.p1 = *p2;
|
||||
edge->edge.p2 = *p1;
|
||||
edge->clockWise = False;
|
||||
}
|
||||
|
||||
poly->num_edges++;
|
||||
}
|
||||
33
xrstate.c
33
xrstate.c
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xrint.h"
|
||||
|
|
|
|||
141
xrstroker.c
Normal file
141
xrstroker.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
/* private functions */
|
||||
static void
|
||||
_TranslatePoint(XPointFixed *pt, XPointFixed *offset);
|
||||
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps)
|
||||
{
|
||||
stroker->gstate = gstate;
|
||||
stroker->traps = traps;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerDeinit(XrStroker *stroker)
|
||||
{
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
static void
|
||||
_TranslatePoint(XPointFixed *pt, XPointFixed *offset)
|
||||
{
|
||||
pt->x += offset->x;
|
||||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
||||
{
|
||||
XrStroker *stroker = closure;
|
||||
XrGState *gstate = stroker->gstate;
|
||||
XrTraps *traps = stroker->traps;
|
||||
double mag, tmp;
|
||||
XPointDouble vector;
|
||||
XPointFixed offset;
|
||||
XPointFixed quad[4];
|
||||
|
||||
vector.x = XFixedToDouble(p2->x - p1->x);
|
||||
vector.y = XFixedToDouble(p2->y - p1->y);
|
||||
|
||||
mag = sqrt(vector.x * vector.x + vector.y * vector.y);
|
||||
if (mag == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
vector.x /= mag;
|
||||
vector.y /= mag;
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm_inverse, &vector);
|
||||
|
||||
tmp = vector.x;
|
||||
vector.x = vector.y * (gstate->line_width / 2.0);
|
||||
vector.y = - tmp * (gstate->line_width / 2.0);
|
||||
|
||||
XrTransformPointWithoutTranslate(&gstate->ctm, &vector);
|
||||
|
||||
offset.x = XDoubleToFixed(vector.x);
|
||||
offset.y = XDoubleToFixed(vector.y);
|
||||
|
||||
quad[0] = *p1;
|
||||
_TranslatePoint(&quad[0], &offset);
|
||||
quad[1] = *p2;
|
||||
_TranslatePoint(&quad[1], &offset);
|
||||
|
||||
offset.x = - offset.x;
|
||||
offset.y = - offset.y;
|
||||
|
||||
quad[2] = *p2;
|
||||
_TranslatePoint(&quad[2], &offset);
|
||||
quad[3] = *p1;
|
||||
_TranslatePoint(&quad[3], &offset);
|
||||
|
||||
XrTrapsTessellateConvexQuad(traps, quad);
|
||||
}
|
||||
|
||||
/* These functions aren't written yet... */
|
||||
#if 0
|
||||
static void
|
||||
_XrGStateStrokerCap(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_cap) {
|
||||
case XrLineCapRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapSquare:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineCapButt:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrGStateStrokerJoin(XrGState *gstate,
|
||||
const XPointDouble *p1, const XPointDouble *p2, const XPointDouble *p3,
|
||||
XrTraps *traps)
|
||||
{
|
||||
switch (gstate->line_join) {
|
||||
case XrLineJoinMiter:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinRound:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
case XrLineJoinBevel:
|
||||
default:
|
||||
/* XXX: NYI */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
150
xrsubpath.c
150
xrsubpath.c
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "xrint.h"
|
||||
|
||||
#define XR_SUBPATH_GROWTH_INC 10
|
||||
|
||||
XrSubPath *
|
||||
XrSubPathCreate(void)
|
||||
{
|
||||
XrSubPath *path;
|
||||
|
||||
path = malloc(sizeof(XrSubPath));
|
||||
|
||||
XrSubPathInit(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathInit(XrSubPath *path)
|
||||
{
|
||||
path->num_pts = 0;
|
||||
|
||||
path->pts_size = 0;
|
||||
path->pts = NULL;
|
||||
|
||||
path->closed = 0;
|
||||
|
||||
path->next = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathInitCopy(XrSubPath *path, XrSubPath *other)
|
||||
{
|
||||
*path = *other;
|
||||
|
||||
if (other->pts_size) {
|
||||
path->pts = malloc(path->pts_size * sizeof(XPointDouble));
|
||||
memcpy(path->pts, other->pts, path->num_pts * sizeof(XPointDouble));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathDeinit(XrSubPath *path)
|
||||
{
|
||||
if (path->pts_size) {
|
||||
free(path->pts);
|
||||
path->pts_size = 0;
|
||||
path->num_pts = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathDestroy(XrSubPath *path)
|
||||
{
|
||||
XrSubPathDeinit(path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
XrSubPath *
|
||||
XrSubPathClone(XrSubPath *path)
|
||||
{
|
||||
XrSubPath *clone;
|
||||
|
||||
clone = XrSubPathCreate();
|
||||
XrSubPathInitCopy(clone, path);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathGetCurrentPoint(XrSubPath *path, XPointDouble *pt)
|
||||
{
|
||||
if (path->num_pts) {
|
||||
*pt = path->pts[path->num_pts-1];
|
||||
} else {
|
||||
/* XXX: BUG: What to do for error handling? */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathSetCurrentPoint(XrSubPath *path, const XPointDouble *pt)
|
||||
{
|
||||
if (path->num_pts) {
|
||||
path->pts[path->num_pts - 1] = *pt;
|
||||
} else {
|
||||
/* XXX: BUG: What to do for error handling? */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_XrSubPathGrow(XrSubPath *path)
|
||||
{
|
||||
XPointDouble *new_pts;
|
||||
|
||||
path->pts_size += XR_SUBPATH_GROWTH_INC;
|
||||
new_pts = realloc(path->pts, path->pts_size * sizeof(XPointDouble));
|
||||
|
||||
if (new_pts) {
|
||||
path->pts = new_pts;
|
||||
} else {
|
||||
/* XXX: BUG: How do we really want to handle this out of memory error? */
|
||||
path->pts_size -= XR_SUBPATH_GROWTH_INC;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathAddPoint(XrSubPath *path, const XPointDouble *pt)
|
||||
{
|
||||
if (path->num_pts == path->pts_size) {
|
||||
_XrSubPathGrow(path);
|
||||
}
|
||||
|
||||
if (path->num_pts < path->pts_size) {
|
||||
path->pts[path->num_pts++] = *pt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrSubPathClose(XrSubPath *path)
|
||||
{
|
||||
path->closed = 1;
|
||||
}
|
||||
33
xrsurface.c
33
xrsurface.c
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "xrint.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +1,27 @@
|
|||
/*
|
||||
* $XFree86: $
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2002 Carl D. Worth
|
||||
*
|
||||
* 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 University
|
||||
* of Southern California not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. University of Southern California makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
* 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.
|
||||
*
|
||||
* UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL UNIVERSITY OF
|
||||
* SOUTHERN CALIFORNIA 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.
|
||||
*
|
||||
* Author: Carl Worth, USC, Information Sciences Institute */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
|
|
|||
210
xrtraps.c
210
xrtraps.c
|
|
@ -28,26 +28,25 @@
|
|||
|
||||
#define XR_TRAPS_GROWTH_INC 10
|
||||
|
||||
typedef struct _Edge Edge;
|
||||
|
||||
struct _Edge {
|
||||
XLineFixed edge;
|
||||
XFixed current_x;
|
||||
XFixed next_x;
|
||||
Bool clockWise;
|
||||
Edge *next, *prev;
|
||||
};
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
_XrTrapsGrowBy(XrTraps *traps, int additional);
|
||||
|
||||
void
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right);
|
||||
|
||||
void
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2);
|
||||
|
||||
static int
|
||||
_ComparePointFixedByY (const void *v1, const void *v2);
|
||||
|
||||
static int
|
||||
_CompareEdgeByTop (const void *v1, const void *v2);
|
||||
_CompareXrEdgeByTop (const void *v1, const void *v2);
|
||||
|
||||
static XFixed
|
||||
_ComputeX (XLineFixed *line, XFixed y);
|
||||
|
|
@ -61,12 +60,6 @@ _ComputeXIntercept (XLineFixed *l, double inverse_slope);
|
|||
static XFixed
|
||||
_ComputeIntersect (XLineFixed *l1, XLineFixed *l2);
|
||||
|
||||
static void
|
||||
_XrTrapsTessellateEdges (XrTraps *traps,
|
||||
Edge *edges,
|
||||
int nedges,
|
||||
int winding);
|
||||
|
||||
XrTraps *
|
||||
XrTrapsCreate(void)
|
||||
{
|
||||
|
|
@ -106,8 +99,8 @@ XrTrapsDestroy(XrTraps *traps)
|
|||
}
|
||||
|
||||
void
|
||||
XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right)
|
||||
_XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XLineFixed left, XLineFixed right)
|
||||
{
|
||||
XTrapezoid *trap;
|
||||
|
||||
|
|
@ -129,9 +122,9 @@ XrTrapsAddTrap(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
}
|
||||
|
||||
void
|
||||
XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
_XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
||||
XPointFixed left_p1, XPointFixed left_p2,
|
||||
XPointFixed right_p1, XPointFixed right_p2)
|
||||
{
|
||||
XLineFixed left;
|
||||
XLineFixed right;
|
||||
|
|
@ -142,7 +135,7 @@ XrTrapsAddTrapFromPoints(XrTraps *traps, XFixed top, XFixed bottom,
|
|||
right.p1 = right_p1;
|
||||
right.p2 = right_p2;
|
||||
|
||||
XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
_XrTrapsAddTrap(traps, top, bottom, left, right);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -180,132 +173,45 @@ _ComparePointFixedByY (const void *v1, const void *v2)
|
|||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointDouble *tri)
|
||||
XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3])
|
||||
{
|
||||
XPointFixed t[4];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
t[i].x = XDoubleToFixed(tri[i].x);
|
||||
t[i].y = XDoubleToFixed(tri[i].y);
|
||||
}
|
||||
|
||||
qsort(t, 3, sizeof(XPointFixed), _ComparePointFixedByY);
|
||||
|
||||
if (t[1].x > t[2].x) {
|
||||
XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[2], t[0], t[1]);
|
||||
XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[0], t[2], t[1], t[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[2], t[0], t[1]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[0], t[2], t[1], t[2]);
|
||||
} else {
|
||||
XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[1], t[0], t[2]);
|
||||
XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[1], t[2], t[0], t[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[0].y, t[1].y, t[0], t[1], t[0], t[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, t[1].y, t[2].y, t[1], t[2], t[0], t[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointDouble *quad)
|
||||
XrTrapsTessellateConvexQuad (XrTraps *traps, XPointFixed q[4])
|
||||
{
|
||||
XPointFixed q[4];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
q[i].x = XDoubleToFixed(quad[i].x);
|
||||
q[i].y = XDoubleToFixed(quad[i].y);
|
||||
}
|
||||
|
||||
qsort(q, 4, sizeof(XPointFixed), _ComparePointFixedByY);
|
||||
|
||||
if (q[1].x > q[2].x) {
|
||||
XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[2], q[0], q[1]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[0], q[2], q[1], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[2], q[3], q[1], q[3]);
|
||||
} else {
|
||||
XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[0].y, q[1].y, q[0], q[1], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[1].y, q[2].y, q[1], q[3], q[0], q[2]);
|
||||
_XrTrapsAddTrapFromPoints(traps, q[2].y, q[3].y, q[1], q[3], q[2], q[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellatePath (XrTraps *traps, XrPath *path, int winding)
|
||||
{
|
||||
XrSubPath *subpath;
|
||||
|
||||
for (subpath = path->head; subpath; subpath = subpath->next) {
|
||||
XrTrapsTessellateSubPath(traps, subpath, winding);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XrTrapsTessellateSubPath (XrTraps *traps, XrSubPath *subpath, int winding)
|
||||
{
|
||||
Edge *edges;
|
||||
int i, nedges, npoints = subpath->num_pts;
|
||||
XFixed x, y, prevx = 0, prevy = 0, firstx = 0, firsty = 0;
|
||||
XFixed top = 0, bottom = 0; /* GCCism */
|
||||
|
||||
edges = (Edge *) Xmalloc (npoints * sizeof (Edge));
|
||||
if (!edges)
|
||||
return;
|
||||
|
||||
_XrTrapsGrowBy(traps, npoints * npoints);
|
||||
|
||||
/* XXX: CLEANUP: This code is still in the same form it was in
|
||||
when I brought it over from Xrender. The right thing to do here
|
||||
is to probably move the edge information into XrPath/XrSubPath
|
||||
and construct all edges during path construction. */
|
||||
nedges = 0;
|
||||
for (i = 0; i <= npoints; i++) {
|
||||
if (i == npoints) {
|
||||
x = firstx;
|
||||
y = firsty;
|
||||
}
|
||||
else {
|
||||
x = XDoubleToFixed (subpath->pts[i].x);
|
||||
y = XDoubleToFixed (subpath->pts[i].y);
|
||||
}
|
||||
if (i) {
|
||||
if (y < top) {
|
||||
top = y;
|
||||
} else if (y > bottom) {
|
||||
bottom = y;
|
||||
}
|
||||
if (prevy < y) {
|
||||
edges[nedges].edge.p1.x = prevx;
|
||||
edges[nedges].edge.p1.y = prevy;
|
||||
edges[nedges].edge.p2.x = x;
|
||||
edges[nedges].edge.p2.y = y;
|
||||
edges[nedges].clockWise = True;
|
||||
nedges++;
|
||||
}
|
||||
else if (prevy > y) {
|
||||
edges[nedges].edge.p1.x = x;
|
||||
edges[nedges].edge.p1.y = y;
|
||||
edges[nedges].edge.p2.x = prevx;
|
||||
edges[nedges].edge.p2.y = prevy;
|
||||
edges[nedges].clockWise = False;
|
||||
nedges++;
|
||||
}
|
||||
/* drop horizontal edges */
|
||||
} else {
|
||||
top = y;
|
||||
bottom = y;
|
||||
firstx = x;
|
||||
firsty = y;
|
||||
}
|
||||
prevx = x;
|
||||
prevy = y;
|
||||
}
|
||||
|
||||
_XrTrapsTessellateEdges (traps, edges, nedges, winding);
|
||||
Xfree (edges);
|
||||
}
|
||||
|
||||
static int
|
||||
_CompareEdgeByTop (const void *v1, const void *v2)
|
||||
_CompareXrEdgeByTop (const void *v1, const void *v2)
|
||||
{
|
||||
const Edge *e1 = v1, *e2 = v2;
|
||||
const XrEdge *e1 = v1, *e2 = v2;
|
||||
int ret;
|
||||
|
||||
return e1->edge.p1.y - e2->edge.p1.y;
|
||||
ret = e1->edge.p1.y - e2->edge.p1.y;
|
||||
if (ret == 0)
|
||||
ret = e1->edge.p1.x - e2->edge.p1.x;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static XFixed
|
||||
|
|
@ -349,27 +255,27 @@ _ComputeIntersect (XLineFixed *l1, XLineFixed *l2)
|
|||
return XDoubleToFixed ((b2 - b1) / (m1 - m2));
|
||||
}
|
||||
|
||||
static void
|
||||
_XrTrapsTessellateEdges (XrTraps *traps,
|
||||
Edge *edges,
|
||||
int nedges,
|
||||
int winding)
|
||||
void
|
||||
XrTrapsTessellatePolygon (XrTraps *traps,
|
||||
XrPolygon *poly,
|
||||
int winding)
|
||||
{
|
||||
int inactive;
|
||||
Edge *active;
|
||||
Edge *e, *en, *next;
|
||||
XrEdge *active;
|
||||
XrEdge *e, *en, *ep, *next;
|
||||
XFixed y, next_y, intersect;
|
||||
int in_out;
|
||||
int in_out, num_edges = poly->num_edges;
|
||||
XrEdge *edges = poly->edges;
|
||||
|
||||
qsort (edges, nedges, sizeof (Edge), _CompareEdgeByTop);
|
||||
qsort (edges, num_edges, sizeof (XrEdge), _CompareXrEdgeByTop);
|
||||
|
||||
y = edges[0].edge.p1.y;
|
||||
active = 0;
|
||||
inactive = 0;
|
||||
while (active || inactive < nedges)
|
||||
while (active || inactive < num_edges)
|
||||
{
|
||||
/* insert new active edges into list */
|
||||
while (inactive < nedges)
|
||||
while (inactive < num_edges)
|
||||
{
|
||||
e = &edges[inactive];
|
||||
if (e->edge.p1.y > y)
|
||||
|
|
@ -377,11 +283,21 @@ _XrTrapsTessellateEdges (XrTraps *traps,
|
|||
/* move this edge into the active list */
|
||||
inactive++;
|
||||
e->next_x = _ComputeX (&e->edge, y);
|
||||
e->next = active;
|
||||
e->prev = 0;
|
||||
if (active)
|
||||
active->prev = e;
|
||||
active = e;
|
||||
|
||||
/* insert e at sorted position */
|
||||
for (en=active, ep=0; en; ep=en, en=en->next)
|
||||
{
|
||||
if (en->next_x > e->next_x)
|
||||
break;
|
||||
}
|
||||
e->next = en;
|
||||
e->prev = ep;
|
||||
if (ep)
|
||||
ep->next = e;
|
||||
else
|
||||
active = e;
|
||||
if (en)
|
||||
en->prev = e;
|
||||
}
|
||||
|
||||
/* find next inflection point */
|
||||
|
|
@ -402,7 +318,7 @@ _XrTrapsTessellateEdges (XrTraps *traps,
|
|||
}
|
||||
}
|
||||
/* check next inactive point */
|
||||
if (inactive < nedges && edges[inactive].edge.p1.y < next_y)
|
||||
if (inactive < num_edges && edges[inactive].edge.p1.y < next_y)
|
||||
next_y = edges[inactive].edge.p1.y;
|
||||
|
||||
/* compute x coordinates along this group */
|
||||
|
|
@ -479,7 +395,7 @@ _XrTrapsTessellateEdges (XrTraps *traps,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
_XrTrapsAddTrap(traps, y, next_y, e->edge, en->edge);
|
||||
}
|
||||
|
||||
y = next_y;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue