#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <math.h>
#include "misc.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include <X11/X.h>
#include "windowstr.h"
#include "gcstruct.h"
#include "regionstr.h"
#include "miwideline.h"
#include "mi.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#define DRAW_POINT(pScrn, x, y) \
if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1); \
else XAAPointHelper(pScrn, x, y)
#define FILL_RECT(pScrn, x, y, w, h) \
if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); \
else XAAFillRectHelper(pScrn, x, y, w, h)
#define FILL_SPAN(pScrn, x, y, w) \
if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, 1); \
else XAASpanHelper(pScrn, x, y, w)
#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
if (ybase == edgey) { \
if (edgeleft) { \
if (edge->x > xcl) \
xcl = edge->x; \
} else { \
if (edge->x < xcr) \
xcr = edge->x; \
} \
edgey++; \
edge->x += edge->stepx; \
edge->e += edge->dx; \
if (edge->e > 0) { \
edge->x += edge->signdx; \
edge->e -= edge->dy; \
} \
}
static void
XAAPointHelper(ScrnInfoPtr pScrn, int x, int y)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
BoxPtr extents = infoRec->ClipBox;
if((x >= extents->x1) && (x < extents->x2) &&
(y >= extents->y1) && (y < extents->y2))
(*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1);
}
static void
XAAFillRectHelper(ScrnInfoPtr pScrn, int x1, int y1, int dx, int dy)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
BoxPtr extents = infoRec->ClipBox;
int x2 = x1 + dx;
int y2 = y1 + dy;
if(x1 < extents->x1) x1 = extents->x1;
if(x2 >= extents->x2) x2 = extents->x2;
if((dx = x2 - x1)<1) return;
if(y1 < extents->y1) y1 = extents->y1;
if(y2 >= extents->y2) y2 = extents->y2;
if((dy = y2 - y1)<1) return;
(*infoRec->SubsequentSolidFillRect)(pScrn, x1, y1, dx, dy);
}
static void
XAASpanHelper(ScrnInfoPtr pScrn, int x1, int y, int width)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
BoxPtr extents = infoRec->ClipBox;
int x2;
if((y < extents->y1) || (y >= extents->y2)) return;
x2 = x1 + width;
if(x1 < extents->x1) x1 = extents->x1;
if(x2 > extents->x2) x2 = extents->x2;
width = x2 - x1;
if(width > 0)
(*infoRec->SubsequentSolidFillRect)(pScrn, x1, y, width, 1);
}
#define FixError(x, dx, dy, e, sign, step, h) { \
e += (h) * dx; \
x += (h) * step; \
if(e > 0) { \
x += e * sign/dy; \
e %= dy; \
if(e) { \
x += sign; \
e -= dy; \
} \
} \
}
static void
XAAFillPolyHelper (
GCPtr pGC,
int y,
int overall_height,
PolyEdgePtr left, PolyEdgePtr right,
int left_count, int right_count )
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
BoxPtr extents = infoRec->ClipBox;
int left_x, left_e, left_stepx, left_signdx, left_dy, left_dx;
int right_x, right_e, right_stepx, right_signdx, right_dy, right_dx;
int height, left_height, right_height;
int xorg;
Bool hardClip;
if((y >= extents->y2) || ((y + overall_height) <= extents->y1))
return;
left_x = left_e = left_stepx = left_signdx = left_dy = left_dx = 0;
right_x = right_e = right_stepx = right_signdx = right_dy = right_dx = 0;
left_height = right_height = 0;
xorg = 0;
hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
while ((left_count || left_height) && (right_count || right_height)) {
if (!left_height && left_count) {
left_height = left->height;
left_x = left->x + xorg;
left_stepx = left->stepx;
left_signdx = left->signdx;
left_e = left->e;
left_dy = left->dy;
left_dx = left->dx;
left_count--;
left++;
}
if (!right_height && right_count) {
right_height = right->height;
right_x = right->x + xorg + 1;
right_stepx = right->stepx;
right_signdx = right->signdx;
right_e = right->e;
right_dy = right->dy;
right_dx = right->dx;
right_count--;
right++;
}
height = (left_height > right_height) ? right_height : left_height;
left_height -= height;
right_height -= height;
if(hardClip && infoRec->SubsequentSolidFillTrap && (height > 6)) {
int right_DX, left_DX;
right_DX = (right_dx * right_signdx) + (right_stepx * right_dy);
left_DX = (left_dx * left_signdx) + (left_stepx * left_dy);
(*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn, y, height,
left_x, left_DX, left_dy, left_e,
right_x - 1, right_DX, right_dy, right_e);
FixError(left_x, left_dx, left_dy, left_e, left_signdx,
left_stepx, height);
FixError(right_x, right_dx, right_dy, right_e, right_signdx,
right_stepx, height);
y += height;
continue;
}
while (height--) {
if(right_x > left_x) {
FILL_SPAN(infoRec->pScrn, left_x, y, right_x - left_x);
}
y++;
left_x += left_stepx;
left_e += left_dx;
if (left_e > 0) {
left_x += left_signdx;
left_e -= left_dy;
}
right_x += right_stepx;
right_e += right_dx;
if (right_e > 0) {
right_x += right_signdx;
right_e -= right_dy;
}
}
}
}
static void
XAAWideSegment (
GCPtr pGC,
int x1, int y1, int x2, int y2,
Bool projectLeft, Bool projectRight,
LineFacePtr leftFace, LineFacePtr rightFace )
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
double l, L, r;
double xa, ya;
double projectXoff, projectYoff;
double k;
double maxy;
int x, y;
int dx, dy;
int finaly;
PolyEdgePtr left, right;
PolyEdgePtr top, bottom;
int lefty, righty, topy, bottomy;
int signdx;
PolyEdgeRec lefts[2], rights[2];
LineFacePtr tface;
int lw = pGC->lineWidth;
Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
if ((y2 < y1) || ((y2 == y1) && (x2 < x1))) {
x = x1;
x1 = x2;
x2 = x;
y = y1;
y1 = y2;
y2 = y;
x = projectLeft;
projectLeft = projectRight;
projectRight = x;
tface = leftFace;
leftFace = rightFace;
rightFace = tface;
}
dy = y2 - y1;
signdx = 1;
dx = x2 - x1;
if (dx < 0)
signdx = -1;
leftFace->x = x1;
leftFace->y = y1;
leftFace->dx = dx;
leftFace->dy = dy;
rightFace->x = x2;
rightFace->y = y2;
rightFace->dx = -dx;
rightFace->dy = -dy;
if (!dy) {
rightFace->xa = 0;
rightFace->ya = (double) lw / 2.0;
rightFace->k = -(double) (lw * dx) / 2.0;
leftFace->xa = 0;
leftFace->ya = -rightFace->ya;
leftFace->k = rightFace->k;
x = x1;
if (projectLeft)
x -= (lw >> 1);
y = y1 - (lw >> 1);
dx = x2 - x;
if (projectRight)
dx += ((lw + 1) >> 1);
dy = lw;
FILL_RECT(infoRec->pScrn, x, y, dx, dy);
} else if (!dx) {
leftFace->xa = (double) lw / 2.0;
leftFace->ya = 0;
leftFace->k = (double) (lw * dy) / 2.0;
rightFace->xa = -leftFace->xa;
rightFace->ya = 0;
rightFace->k = leftFace->k;
y = y1;
if (projectLeft)
y -= lw >> 1;
x = x1 - (lw >> 1);
dy = y2 - y;
if (projectRight)
dy += ((lw + 1) >> 1);
dx = lw;
FILL_RECT(infoRec->pScrn, x, y, dx, dy);
} else {
l = ((double) lw) / 2.0;
L = sqrt((double)(dx*dx + dy*dy));
if (dx < 0) {
right = &rights[1];
left = &lefts[0];
top = &rights[0];
bottom = &lefts[1];
} else {
right = &rights[0];
left = &lefts[1];
top = &lefts[0];
bottom = &rights[1];
}
r = l / L;
ya = -r * dx;
xa = r * dy;
projectXoff = -ya;
projectYoff = xa;
k = l * L;
leftFace->xa = xa;
leftFace->ya = ya;
leftFace->k = k;
rightFace->xa = -xa;
rightFace->ya = -ya;
rightFace->k = k;
if (projectLeft)
righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
k, dx, dy, x1, y1, 0, right);
else
righty = miPolyBuildEdge (xa, ya,
k, dx, dy, x1, y1, 0, right);
ya = -ya;
xa = -xa;
k = - k;
if (projectLeft)
lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
k, dx, dy, x1, y1, 1, left);
else
lefty = miPolyBuildEdge (xa, ya,
k, dx, dy, x1, y1, 1, left);
if (signdx > 0) {
ya = -ya;
xa = -xa;
}
if (projectLeft) {
double xap = xa - projectXoff;
double yap = ya - projectYoff;
topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
-dy, dx, x1, y1, dx > 0, top);
}
else
topy = miPolyBuildEdge(xa, ya, 0.0,
-dy, dx, x1, y1, dx > 0, top);
if (projectRight) {
double xap = xa + projectXoff;
double yap = ya + projectYoff;
bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
-dy, dx, x2, y2, dx < 0, bottom);
maxy = -ya + projectYoff;
} else {
bottomy = miPolyBuildEdge (xa, ya, 0.0,
-dy, dx, x2, y2, dx < 0, bottom);
maxy = -ya;
}
finaly = ICEIL (maxy) + y2;
if (dx < 0) {
left->height = bottomy - lefty;
right->height = finaly - righty;
top->height = righty - topy;
} else {
right->height = bottomy - righty;
left->height = finaly - lefty;
top->height = lefty - topy;
}
bottom->height = finaly - bottomy;
XAAFillPolyHelper (pGC, topy,
bottom->height + bottomy - topy, lefts, rights, 2, 2);
}
}
static void
XAALineArcI (GCPtr pGC, int xorg, int yorg)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
int x, y, e, ex;
int slw = pGC->lineWidth;
Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
y = (slw >> 1) + 1;
if (slw & 1)
e = - ((y << 2) + 3);
else
e = - (y << 3);
ex = -4;
x = 0;
while (y) {
e += (y << 3) - 4;
while (e >= 0) {
x++;
e += (ex = -((x << 3) + 4));
}
y--;
slw = (x << 1) + 1;
if ((e == ex) && (slw > 1))
slw--;
FILL_SPAN(infoRec->pScrn, xorg - x, yorg - y, slw);
if ((y != 0) && ((slw > 1) || (e != ex))) {
FILL_SPAN(infoRec->pScrn, xorg - x, yorg + y, slw);
}
}
}
static void
XAALineArcD (
GCPtr pGC,
double xorg,
double yorg,
PolyEdgePtr edge1,
int edgey1,
Bool edgeleft1,
PolyEdgePtr edge2,
int edgey2,
Bool edgeleft2 )
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
double radius, x0, y0, el, er, yk, xlk, xrk, k;
int xbase, ybase, y, boty, xl, xr, xcl, xcr;
int ymin, ymax;
Bool edge1IsMin, edge2IsMin;
int ymin1, ymin2;
Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
xbase = floor(xorg);
x0 = xorg - xbase;
ybase = ICEIL (yorg);
y0 = yorg - ybase;
xlk = x0 + x0 + 1.0;
xrk = x0 + x0 - 1.0;
yk = y0 + y0 - 1.0;
radius = ((double)pGC->lineWidth) / 2.0;
y = floor(radius - y0 + 1.0);
ybase -= y;
ymin = ybase;
ymax = 65536;
edge1IsMin = FALSE;
ymin1 = edgey1;
if (edge1->dy >= 0) {
if (!edge1->dy) {
if (edgeleft1)
edge1IsMin = TRUE;
else
ymax = edgey1;
edgey1 = 65536;
} else if ((edge1->signdx < 0) == edgeleft1)
edge1IsMin = TRUE;
}
edge2IsMin = FALSE;
ymin2 = edgey2;
if (edge2->dy >= 0) {
if (!edge2->dy) {
if (edgeleft2)
edge2IsMin = TRUE;
else
ymax = edgey2;
edgey2 = 65536;
} else if ((edge2->signdx < 0) == edgeleft2)
edge2IsMin = TRUE;
}
if (edge1IsMin) {
ymin = ymin1;
if (edge2IsMin && (ymin1 > ymin2))
ymin = ymin2;
} else if (edge2IsMin)
ymin = ymin2;
el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
er = el + xrk;
xl = 1;
xr = 0;
if (x0 < 0.5) {
xl = 0;
el -= xlk;
}
boty = (y0 < -0.5) ? 1 : 0;
if (ybase + y - boty > ymax)
boty = ymax - ybase - y;
while (y > boty) {
k = (y << 1) + yk;
er += k;
while (er > 0.0) {
xr++;
er += xrk - (xr << 1);
}
el += k;
while (el >= 0.0) {
xl--;
el += (xl << 1) - xlk;
}
y--;
ybase++;
if (ybase < ymin)
continue;
xcl = xl + xbase;
xcr = xr + xbase;
CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
if(xcr >= xcl) {
FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
}
}
er = xrk - (xr << 1) - er;
el = (xl << 1) - xlk - el;
boty = floor(-y0 - radius + 1.0);
if (ybase + y - boty > ymax)
boty = ymax - ybase - y;
while (y > boty) {
k = (y << 1) + yk;
er -= k;
while ((er >= 0.0) && (xr >= 0)) {
xr--;
er += xrk - (xr << 1);
}
el -= k;
while ((el > 0.0) && (xl <= 0)) {
xl++;
el += (xl << 1) - xlk;
}
y--;
ybase++;
if (ybase < ymin)
continue;
xcl = xl + xbase;
xcr = xr + xbase;
CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
if(xcr >= xcl) {
FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
}
}
}
static void
XAALineArc (
GCPtr pGC,
LineFacePtr leftFace,
LineFacePtr rightFace,
double xorg,
double yorg,
Bool isInt )
{
int xorgi, yorgi;
PolyEdgeRec edge1, edge2;
int edgey1, edgey2;
Bool edgeleft1, edgeleft2;
if (isInt) {
xorgi = leftFace ? leftFace->x : rightFace->x;
yorgi = leftFace ? leftFace->y : rightFace->y;
} else {
xorgi = yorgi = 0;
}
edgey1 = 65536;
edgey2 = 65536;
edge1.x = 0;
edge1.dy = -1;
edge2.x = 0;
edge2.dy = -1;
edgeleft1 = FALSE;
edgeleft2 = FALSE;
if ((pGC->lineWidth > 2) &&
((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) ||
(pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))) {
if (isInt) {
xorg = (double) xorgi;
yorg = (double) yorgi;
}
if (leftFace && rightFace)
miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
&edgey1, &edgey2, &edgeleft1, &edgeleft2);
else if (leftFace)
edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
else if (rightFace)
edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);
isInt = FALSE;
}
if (isInt) {
if(pGC->lineWidth == 1) {
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
DRAW_POINT(infoRec->pScrn, xorgi, yorgi);
} else
XAALineArcI(pGC, xorgi, yorgi);
} else
XAALineArcD(pGC, xorg, yorg, &edge1, edgey1, edgeleft1,
&edge2, edgey2, edgeleft2);
}
static void
XAALineJoin (
GCPtr pGC,
LineFacePtr pLeft,
LineFacePtr pRight )
{
double mx = 0, my = 0;
double denom = 0;
PolyVertexRec vertices[4];
PolySlopeRec slopes[4];
int edgecount;
PolyEdgeRec left[4], right[4];
int nleft, nright;
int y, height;
int swapslopes;
int joinStyle = pGC->joinStyle;
int lw = pGC->lineWidth;
if (lw == 1) {
if ((pLeft->dx >= 0) == (pRight->dx <= 0))
return;
if (joinStyle != JoinRound) {
denom = - pLeft->dx * (double)pRight->dy + pRight->dx *
(double)pLeft->dy;
if (denom == 0.0)
return;
}
if (joinStyle != JoinMiter) {
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
DRAW_POINT(infoRec->pScrn, pLeft->x, pLeft->y);
return;
}
} else {
if (joinStyle == JoinRound) {
XAALineArc(pGC, pLeft, pRight,(double)0.0, (double)0.0, TRUE);
return;
}
denom = - pLeft->dx * (double)pRight->dy + pRight->dx *
(double)pLeft->dy;
if (denom == 0.0)
return;
}
swapslopes = 0;
if (denom > 0) {
pLeft->xa = -pLeft->xa;
pLeft->ya = -pLeft->ya;
pLeft->dx = -pLeft->dx;
pLeft->dy = -pLeft->dy;
} else {
swapslopes = 1;
pRight->xa = -pRight->xa;
pRight->ya = -pRight->ya;
pRight->dx = -pRight->dx;
pRight->dy = -pRight->dy;
}
vertices[0].x = pRight->xa;
vertices[0].y = pRight->ya;
slopes[0].dx = -pRight->dy;
slopes[0].dy = pRight->dx;
slopes[0].k = 0;
vertices[1].x = 0;
vertices[1].y = 0;
slopes[1].dx = pLeft->dy;
slopes[1].dy = -pLeft->dx;
slopes[1].k = 0;
vertices[2].x = pLeft->xa;
vertices[2].y = pLeft->ya;
if (joinStyle == JoinMiter) {
my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx ))/
denom;
if (pLeft->dy != 0)
mx = pLeft->xa + (my - pLeft->ya) *
(double) pLeft->dx / (double) pLeft->dy;
else
mx = pRight->xa + (my - pRight->ya) *
(double) pRight->dx / (double) pRight->dy;
if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
joinStyle = JoinBevel;
}
if (joinStyle == JoinMiter) {
slopes[2].dx = pLeft->dx;
slopes[2].dy = pLeft->dy;
slopes[2].k = pLeft->k;
if (swapslopes) {
slopes[2].dx = -slopes[2].dx;
slopes[2].dy = -slopes[2].dy;
slopes[2].k = -slopes[2].k;
}
vertices[3].x = mx;
vertices[3].y = my;
slopes[3].dx = pRight->dx;
slopes[3].dy = pRight->dy;
slopes[3].k = pRight->k;
if (swapslopes) {
slopes[3].dx = -slopes[3].dx;
slopes[3].dy = -slopes[3].dy;
slopes[3].k = -slopes[3].k;
}
edgecount = 4;
} else {
double scale, dx, dy, adx, ady;
adx = dx = pRight->xa - pLeft->xa;
ady = dy = pRight->ya - pLeft->ya;
if (adx < 0)
adx = -adx;
if (ady < 0)
ady = -ady;
scale = ady;
if (adx > ady)
scale = adx;
slopes[2].dx = (dx * 65536) / scale;
slopes[2].dy = (dy * 65536) / scale;
slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
(pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
edgecount = 3;
}
y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
left, right, &nleft, &nright, &height);
XAAFillPolyHelper(pGC, y, height, left, right, nleft, nright);
}
void
XAAPolylinesWideSolid (
DrawablePtr pDrawable,
GCPtr pGC,
int mode,
int npt,
DDXPointPtr pPts )
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
int x1, y1, x2, y2;
Bool projectLeft, projectRight;
LineFaceRec leftFace, rightFace, prevRightFace, firstFace;
int first = TRUE;
Bool somethingDrawn = FALSE;
Bool selfJoin = FALSE;
int xorg = pDrawable->x;
int yorg = pDrawable->y;
Bool hardClip = FALSE;
if(!REGION_NUM_RECTS(pGC->pCompositeClip))
return;
if(REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
miWideLine(pDrawable, pGC, mode, npt, pPts);
return;
}
x2 = pPts->x;
y2 = pPts->y;
if (npt > 1) {
if (mode == CoordModePrevious) {
int nptTmp;
register DDXPointPtr pPtsTmp;
x1 = x2;
y1 = y2;
nptTmp = npt;
pPtsTmp = pPts + 1;
while (--nptTmp) {
x1 += pPtsTmp->x;
y1 += pPtsTmp->y;
++pPtsTmp;
}
if ((x2 == x1) && (y2 == y1))
selfJoin = TRUE;
} else if ((x2 == pPts[npt-1].x) && (y2 == pPts[npt-1].y))
selfJoin = TRUE;
}
projectLeft = ((pGC->capStyle == CapProjecting) && !selfJoin);
projectRight = FALSE;
(*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
pGC->planemask);
infoRec->ClipBox = &pGC->pCompositeClip->extents;
if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL) {
hardClip = TRUE;
(*infoRec->SetClippingRectangle)(infoRec->pScrn,
infoRec->ClipBox->x1, infoRec->ClipBox->y1,
infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
}
x2 += xorg;
y2 += yorg;
while (--npt) {
x1 = x2;
y1 = y2;
++pPts;
x2 = pPts->x;
y2 = pPts->y;
if (mode == CoordModePrevious) {
x2 += x1;
y2 += y1;
} else {
x2 += xorg;
y2 += yorg;
}
if ((x1 != x2) || (y1 != y2)) {
somethingDrawn = TRUE;
if ((npt == 1) && (pGC->capStyle == CapProjecting) && !selfJoin)
projectRight = TRUE;
XAAWideSegment(pGC, x1, y1, x2, y2,
projectLeft, projectRight, &leftFace, &rightFace);
if (first) {
if (selfJoin)
firstFace = leftFace;
else if (pGC->capStyle == CapRound) {
if (pGC->lineWidth == 1) {
DRAW_POINT(infoRec->pScrn, x1, y1);
} else
XAALineArc(pGC,&leftFace, (LineFacePtr) NULL,
(double)0.0, (double)0.0,TRUE);
}
} else
XAALineJoin (pGC, &leftFace, &prevRightFace);
prevRightFace = rightFace;
first = FALSE;
projectLeft = FALSE;
}
if (npt == 1 && somethingDrawn) {
if (selfJoin)
XAALineJoin (pGC, &firstFace, &rightFace);
else if (pGC->capStyle == CapRound) {
if (pGC->lineWidth == 1) {
DRAW_POINT(infoRec->pScrn, x2, y2);
} else
XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
(double)0.0, (double)0.0,TRUE);
}
}
}
if (!somethingDrawn) {
projectLeft = (pGC->capStyle == CapProjecting);
XAAWideSegment (pGC, x2, y2, x2, y2, projectLeft, projectLeft,
&leftFace, &rightFace);
if (pGC->capStyle == CapRound) {
XAALineArc (pGC, &leftFace, (LineFacePtr) NULL,
(double)0.0, (double)0.0, TRUE);
rightFace.dx = -1;
XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
(double)0.0, (double)0.0, TRUE);
}
}
infoRec->ClipBox = NULL;
if(hardClip)
(*infoRec->DisableClipping)(infoRec->pScrn);
SET_SYNC_FLAG(infoRec);
}