Added triangle tessellation. Converted bevel joins from polygons to triangles.

This commit is contained in:
Carl Worth 2003-01-28 07:23:54 +00:00
parent f93c88efbf
commit 1507f1c795
7 changed files with 110 additions and 18 deletions

View file

@ -1,3 +1,11 @@
2003-01-28 Carl Worth <cworth@east.isi.edu>
* xrtraps.c (_XrTrapsTessellateTriangle): Restored triangle
tessellation functionality, (I think it's correct this time).
* xrstroker.c (_XrStrokerJoin): Bevel joins now use triangle
tessellation rather than polygon tessellation.
2003-01-24 Carl Worth <cworth@east.isi.edu>
* xrpolygon.c (_XrPolygonAddEdge): Fixed to handle multiple

View file

@ -773,6 +773,9 @@ _XrTrapsInit(XrTraps *traps);
void
_XrTrapsDeinit(XrTraps *traps);
XrStatus
_XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3]);
XrStatus
_XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4]);

View file

@ -113,7 +113,6 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
XrStatus status;
XrGState *gstate = stroker->gstate;
int clockwise = _XrStrokerFaceClockwise (in, out);
XrPolygon polygon;
XPointFixed *inpt, *outpt;
/* XXX: There might be a more natural place to check for the
@ -133,13 +132,18 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
inpt = &in->ccw;
outpt = &out->ccw;
}
_XrPolygonInit (&polygon);
switch (gstate->line_join) {
case XrLineJoinRound:
status = XrStatusSuccess;
break;
case XrLineJoinMiter: {
XrPolygon polygon;
XDouble c = (-in->vector.x * out->vector.x)+(-in->vector.y * out->vector.y);
XDouble ml = gstate->miter_limit;
_XrPolygonInit (&polygon);
if (2 <= ml * ml * (1 - c)) {
XDouble x1, y1, x2, y2;
XDouble mx, my;
@ -171,19 +175,23 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
_XrPolygonAddEdge (&polygon, inpt, &outer);
_XrPolygonAddEdge (&polygon, &outer, outpt);
_XrPolygonAddEdge (&polygon, outpt, &in->pt);
status = _XrTrapsTessellatePolygon (stroker->traps,
&polygon,
XrFillRuleWinding);
_XrPolygonDeinit (&polygon);
break;
}
/* fall through ... */
}
case XrLineJoinBevel:
_XrPolygonAddEdge (&polygon, &in->pt, inpt);
_XrPolygonAddEdge (&polygon, inpt, outpt);
_XrPolygonAddEdge (&polygon, outpt, &in->pt);
case XrLineJoinBevel: {
XPointFixed tri[3];
tri[0] = in->pt;
tri[1] = *inpt;
tri[2] = *outpt;
status = _XrTrapsTessellateTriangle (stroker->traps, tri);
break;
}
status = _XrTrapsTessellatePolygon (stroker->traps, &polygon, XrFillRuleWinding);
_XrPolygonDeinit (&polygon);
}
return status;
}

View file

@ -161,6 +161,37 @@ _ComparePointFixedByY (const void *av, const void *bv)
return ret;
}
XrStatus
_XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3])
{
XLineFixed line;
double intersect;
qsort(t, 3, sizeof(XPointFixed), _ComparePointFixedByY);
/* horizontal top edge requires special handling */
if (t[0].y == t[1].y) {
if (t[0].x < t[1].x)
_XrTrapsAddTrapFromPoints (traps, t[1].y, t[2].y, t[0], t[2], t[1], t[2]);
else
_XrTrapsAddTrapFromPoints (traps, t[1].y, t[2].y, t[1], t[2], t[0], t[2]);
return;
}
line.p1 = t[0];
line.p2 = t[1];
intersect = _ComputeX (&line, t[2].y);
if (intersect < t[2].x) {
_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]);
} else {
_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]);
}
}
XrStatus
_XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4])
{

View file

@ -773,6 +773,9 @@ _XrTrapsInit(XrTraps *traps);
void
_XrTrapsDeinit(XrTraps *traps);
XrStatus
_XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3]);
XrStatus
_XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4]);

View file

@ -113,7 +113,6 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
XrStatus status;
XrGState *gstate = stroker->gstate;
int clockwise = _XrStrokerFaceClockwise (in, out);
XrPolygon polygon;
XPointFixed *inpt, *outpt;
/* XXX: There might be a more natural place to check for the
@ -133,13 +132,18 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
inpt = &in->ccw;
outpt = &out->ccw;
}
_XrPolygonInit (&polygon);
switch (gstate->line_join) {
case XrLineJoinRound:
status = XrStatusSuccess;
break;
case XrLineJoinMiter: {
XrPolygon polygon;
XDouble c = (-in->vector.x * out->vector.x)+(-in->vector.y * out->vector.y);
XDouble ml = gstate->miter_limit;
_XrPolygonInit (&polygon);
if (2 <= ml * ml * (1 - c)) {
XDouble x1, y1, x2, y2;
XDouble mx, my;
@ -171,19 +175,23 @@ _XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
_XrPolygonAddEdge (&polygon, inpt, &outer);
_XrPolygonAddEdge (&polygon, &outer, outpt);
_XrPolygonAddEdge (&polygon, outpt, &in->pt);
status = _XrTrapsTessellatePolygon (stroker->traps,
&polygon,
XrFillRuleWinding);
_XrPolygonDeinit (&polygon);
break;
}
/* fall through ... */
}
case XrLineJoinBevel:
_XrPolygonAddEdge (&polygon, &in->pt, inpt);
_XrPolygonAddEdge (&polygon, inpt, outpt);
_XrPolygonAddEdge (&polygon, outpt, &in->pt);
case XrLineJoinBevel: {
XPointFixed tri[3];
tri[0] = in->pt;
tri[1] = *inpt;
tri[2] = *outpt;
status = _XrTrapsTessellateTriangle (stroker->traps, tri);
break;
}
status = _XrTrapsTessellatePolygon (stroker->traps, &polygon, XrFillRuleWinding);
_XrPolygonDeinit (&polygon);
}
return status;
}

View file

@ -161,6 +161,37 @@ _ComparePointFixedByY (const void *av, const void *bv)
return ret;
}
XrStatus
_XrTrapsTessellateTriangle (XrTraps *traps, XPointFixed t[3])
{
XLineFixed line;
double intersect;
qsort(t, 3, sizeof(XPointFixed), _ComparePointFixedByY);
/* horizontal top edge requires special handling */
if (t[0].y == t[1].y) {
if (t[0].x < t[1].x)
_XrTrapsAddTrapFromPoints (traps, t[1].y, t[2].y, t[0], t[2], t[1], t[2]);
else
_XrTrapsAddTrapFromPoints (traps, t[1].y, t[2].y, t[1], t[2], t[0], t[2]);
return;
}
line.p1 = t[0];
line.p2 = t[1];
intersect = _ComputeX (&line, t[2].y);
if (intersect < t[2].x) {
_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]);
} else {
_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]);
}
}
XrStatus
_XrTrapsTessellateRectangle (XrTraps *traps, XPointFixed q[4])
{