mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-26 03:00:17 +01:00
Add bevel joins
This commit is contained in:
parent
6b1903c40e
commit
e55de618e7
10 changed files with 132 additions and 36 deletions
|
|
@ -261,7 +261,7 @@ XrGStateClosePath(XrGState *gstate)
|
|||
void
|
||||
XrGStateStroke(XrGState *gstate)
|
||||
{
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge };
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge, XrStrokerDoneSubPath };
|
||||
|
||||
XrStroker stroker;
|
||||
XrTraps traps;
|
||||
|
|
@ -287,7 +287,7 @@ XrGStateStroke(XrGState *gstate)
|
|||
void
|
||||
XrGStateFill(XrGState *gstate)
|
||||
{
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge };
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge, XrPolygonDoneSubPath };
|
||||
|
||||
XrPolygon polygon;
|
||||
XrTraps traps;
|
||||
|
|
|
|||
|
|
@ -359,6 +359,9 @@ XrPolygonDeinit(XrPolygon *poly);
|
|||
void
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
void
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done);
|
||||
|
||||
/* xrstroke.c */
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps);
|
||||
|
|
|
|||
|
|
@ -257,11 +257,6 @@ _TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
|
|||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
}
|
||||
|
||||
#define START_ARGS(n) \
|
||||
{ \
|
||||
if (dir != XrPathDirectionForward) \
|
||||
|
|
|
|||
|
|
@ -102,3 +102,9 @@ XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
|
||||
poly->num_edges++;
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,10 +50,50 @@ _TranslatePoint(XPointFixed *pt, XPointFixed *offset)
|
|||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerJoin(XrStroker *stroker, XrStrokeFace *f1, XrStrokeFace *f2)
|
||||
static int
|
||||
XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XrGState *gstate = stroker->gstate;
|
||||
XPointFixed d_in, d_out;
|
||||
|
||||
d_in.x = in->cw.x - in->pt.x;
|
||||
d_in.y = in->cw.y - in->pt.y;
|
||||
d_out.x = out->cw.x - in->pt.x;
|
||||
d_out.y = out->cw.y - in->pt.y;
|
||||
|
||||
return d_out.y * d_in.x > d_in.y * d_out.x;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XrGState *gstate = stroker->gstate;
|
||||
int clockwise = XrStrokerFaceClockwise (in, out);
|
||||
|
||||
switch (gstate->stroke_style.line_join) {
|
||||
case XrLineJoinRound: {
|
||||
}
|
||||
case XrLineJoinMiter: {
|
||||
}
|
||||
case XrLineJoinBevel: {
|
||||
XPointFixed t[3];
|
||||
|
||||
t[0].x = in->pt.x;
|
||||
t[0].y = in->pt.y;
|
||||
if (clockwise) {
|
||||
t[1].x = in->cw.x;
|
||||
t[1].y = in->cw.y;
|
||||
t[2].x = out->cw.x;
|
||||
t[2].y = out->cw.y;
|
||||
} else {
|
||||
t[1].x = in->ccw.x;
|
||||
t[1].y = in->ccw.y;
|
||||
t[2].x = out->ccw.x;
|
||||
t[2].y = out->ccw.y;
|
||||
}
|
||||
XrTrapsTessellateTriangle (stroker->traps, t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -105,21 +145,25 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
_TranslatePoint(&quad[1], &offset_ccw);
|
||||
|
||||
quad[2] = *p2;
|
||||
_TranslatePoint(&quad[1], &offset_ccw);
|
||||
_TranslatePoint(&quad[2], &offset_ccw);
|
||||
|
||||
quad[3] = *p2;
|
||||
_TranslatePoint(&quad[2], &offset_cw);
|
||||
_TranslatePoint(&quad[3], &offset_cw);
|
||||
|
||||
face.ccw = quad[2];
|
||||
face.pt = *p2;
|
||||
face.cw = quad[3];
|
||||
face.cw = quad[0];
|
||||
face.pt = *p1;
|
||||
face.ccw = quad[1];
|
||||
|
||||
if (stroker->have_prev)
|
||||
XrStrokerJoin (stroker, &stroker->prev, &face);
|
||||
else
|
||||
else {
|
||||
stroker->have_prev = 1;
|
||||
stroker->first = face;
|
||||
stroker->prev = face;
|
||||
stroker->have_prev = 1;
|
||||
}
|
||||
|
||||
stroker->prev.ccw = quad[2];
|
||||
stroker->prev.pt = *p2;
|
||||
stroker->prev.cw = quad[3];
|
||||
|
||||
XrTrapsTessellateConvexQuad(traps, quad);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ XrGStateClosePath(XrGState *gstate)
|
|||
void
|
||||
XrGStateStroke(XrGState *gstate)
|
||||
{
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge };
|
||||
static XrPathCallbacks cb = { XrStrokerAddEdge, XrStrokerDoneSubPath };
|
||||
|
||||
XrStroker stroker;
|
||||
XrTraps traps;
|
||||
|
|
@ -287,7 +287,7 @@ XrGStateStroke(XrGState *gstate)
|
|||
void
|
||||
XrGStateFill(XrGState *gstate)
|
||||
{
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge };
|
||||
static XrPathCallbacks cb = { XrPolygonAddEdge, XrPolygonDoneSubPath };
|
||||
|
||||
XrPolygon polygon;
|
||||
XrTraps traps;
|
||||
|
|
|
|||
3
xrint.h
3
xrint.h
|
|
@ -359,6 +359,9 @@ XrPolygonDeinit(XrPolygon *poly);
|
|||
void
|
||||
XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2);
|
||||
|
||||
void
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done);
|
||||
|
||||
/* xrstroke.c */
|
||||
void
|
||||
XrStrokerInit(XrStroker *stroker, XrGState *gstate, XrTraps *traps);
|
||||
|
|
|
|||
5
xrpath.c
5
xrpath.c
|
|
@ -257,11 +257,6 @@ _TranslatePointFixed(XPointFixed *pt, XPointFixed *offset)
|
|||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
}
|
||||
|
||||
#define START_ARGS(n) \
|
||||
{ \
|
||||
if (dir != XrPathDirectionForward) \
|
||||
|
|
|
|||
|
|
@ -102,3 +102,9 @@ XrPolygonAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
|
||||
poly->num_edges++;
|
||||
}
|
||||
|
||||
void
|
||||
XrPolygonDoneSubPath (void *closure, XrSubPathDone done)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
66
xrstroker.c
66
xrstroker.c
|
|
@ -50,10 +50,50 @@ _TranslatePoint(XPointFixed *pt, XPointFixed *offset)
|
|||
pt->y += offset->y;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerJoin(XrStroker *stroker, XrStrokeFace *f1, XrStrokeFace *f2)
|
||||
static int
|
||||
XrStrokerFaceClockwise(XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XrGState *gstate = stroker->gstate;
|
||||
XPointFixed d_in, d_out;
|
||||
|
||||
d_in.x = in->cw.x - in->pt.x;
|
||||
d_in.y = in->cw.y - in->pt.y;
|
||||
d_out.x = out->cw.x - in->pt.x;
|
||||
d_out.y = out->cw.y - in->pt.y;
|
||||
|
||||
return d_out.y * d_in.x > d_in.y * d_out.x;
|
||||
}
|
||||
|
||||
void
|
||||
XrStrokerJoin(XrStroker *stroker, XrStrokeFace *in, XrStrokeFace *out)
|
||||
{
|
||||
XrGState *gstate = stroker->gstate;
|
||||
int clockwise = XrStrokerFaceClockwise (in, out);
|
||||
|
||||
switch (gstate->stroke_style.line_join) {
|
||||
case XrLineJoinRound: {
|
||||
}
|
||||
case XrLineJoinMiter: {
|
||||
}
|
||||
case XrLineJoinBevel: {
|
||||
XPointFixed t[3];
|
||||
|
||||
t[0].x = in->pt.x;
|
||||
t[0].y = in->pt.y;
|
||||
if (clockwise) {
|
||||
t[1].x = in->cw.x;
|
||||
t[1].y = in->cw.y;
|
||||
t[2].x = out->cw.x;
|
||||
t[2].y = out->cw.y;
|
||||
} else {
|
||||
t[1].x = in->ccw.x;
|
||||
t[1].y = in->ccw.y;
|
||||
t[2].x = out->ccw.x;
|
||||
t[2].y = out->ccw.y;
|
||||
}
|
||||
XrTrapsTessellateTriangle (stroker->traps, t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -105,21 +145,25 @@ XrStrokerAddEdge(void *closure, XPointFixed *p1, XPointFixed *p2)
|
|||
_TranslatePoint(&quad[1], &offset_ccw);
|
||||
|
||||
quad[2] = *p2;
|
||||
_TranslatePoint(&quad[1], &offset_ccw);
|
||||
_TranslatePoint(&quad[2], &offset_ccw);
|
||||
|
||||
quad[3] = *p2;
|
||||
_TranslatePoint(&quad[2], &offset_cw);
|
||||
_TranslatePoint(&quad[3], &offset_cw);
|
||||
|
||||
face.ccw = quad[2];
|
||||
face.pt = *p2;
|
||||
face.cw = quad[3];
|
||||
face.cw = quad[0];
|
||||
face.pt = *p1;
|
||||
face.ccw = quad[1];
|
||||
|
||||
if (stroker->have_prev)
|
||||
XrStrokerJoin (stroker, &stroker->prev, &face);
|
||||
else
|
||||
else {
|
||||
stroker->have_prev = 1;
|
||||
stroker->first = face;
|
||||
stroker->prev = face;
|
||||
stroker->have_prev = 1;
|
||||
}
|
||||
|
||||
stroker->prev.ccw = quad[2];
|
||||
stroker->prev.pt = *p2;
|
||||
stroker->prev.cw = quad[3];
|
||||
|
||||
XrTrapsTessellateConvexQuad(traps, quad);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue