#include "X.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "regionstr.h"
#include "scrnintstr.h"
#include "mistruct.h"
#include "ilbm.h"
#include "maskbits.h"
#include "miline.h"
void
#ifdef POLYSEGMENT
ilbmSegmentSS(pDrawable, pGC, nseg, pSeg)
DrawablePtr pDrawable;
GCPtr pGC;
int nseg;
register xSegment *pSeg;
#else
ilbmLineSS(pDrawable, pGC, mode, npt, pptInit)
DrawablePtr pDrawable;
GCPtr pGC;
int mode;
int npt;
DDXPointPtr pptInit;
#endif
{
int nboxInit;
register int nbox;
BoxPtr pboxInit;
register BoxPtr pbox;
#ifndef POLYSEGMENT
register DDXPointPtr ppt;
#endif
unsigned int oc1;
unsigned int oc2;
PixelType *addrlBase;
PixelType *addrl;
int nlwidth;
int xorg, yorg;
int adx;
int ady;
int signdx;
int signdy;
int e, e1, e2;
int len;
int axis;
int octant;
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
int depthDst;
int d;
int auxDst;
unsigned char *rrops;
register int y1, y2;
register int x1, x2;
RegionPtr cclip;
cclip = pGC->pCompositeClip;
rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
pboxInit = REGION_RECTS(cclip);
nboxInit = REGION_NUM_RECTS(cclip);
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
addrlBase);
xorg = pDrawable->x;
yorg = pDrawable->y;
#ifdef POLYSEGMENT
while (nseg--)
#else
ppt = pptInit;
x2 = ppt->x + xorg;
y2 = ppt->y + yorg;
while (--npt)
#endif
{
nbox = nboxInit;
pbox = pboxInit;
#ifdef POLYSEGMENT
x1 = pSeg->x1 + xorg;
y1 = pSeg->y1 + yorg;
x2 = pSeg->x2 + xorg;
y2 = pSeg->y2 + yorg;
pSeg++;
#else
x1 = x2;
y1 = y2;
++ppt;
if (mode == CoordModePrevious) {
xorg = x1;
yorg = y1;
}
x2 = ppt->x + xorg;
y2 = ppt->y + yorg;
#endif
if (x1 == x2)
{
if (y1 > y2) {
register int tmp;
tmp = y2;
y2 = y1 + 1;
y1 = tmp + 1;
#ifdef POLYSEGMENT
if (pGC->capStyle != CapNotLast)
y1--;
#endif
}
#ifdef POLYSEGMENT
else if (pGC->capStyle != CapNotLast)
y2++;
#endif
while ((nbox) && (pbox->y2 <= y1)) {
pbox++;
nbox--;
}
if (nbox) {
while ((nbox) && (y2 >= pbox->y1)) {
if ((x1 >= pbox->x1) && (x1 < pbox->x2)) {
int y1t, y2t;
y1t = max(y1, pbox->y1);
y2t = min(y2, pbox->y2);
if (y1t != y2t)
ilbmVertS(addrlBase, nlwidth, auxDst, depthDst, x1, y1t,
y2t-y1t, rrops);
}
nbox--;
pbox++;
}
}
#ifndef POLYSEGMENT
y2 = ppt->y + yorg;
#endif
} else if (y1 == y2) {
if (x1 > x2) {
register int tmp;
tmp = x2;
x2 = x1 + 1;
x1 = tmp + 1;
#ifdef POLYSEGMENT
if (pGC->capStyle != CapNotLast)
x1--;
#endif
}
#ifdef POLYSEGMENT
else if (pGC->capStyle != CapNotLast)
x2++;
#endif
while ((nbox) && (pbox->y2 <= y1)) {
pbox++;
nbox--;
}
if ((nbox) && (pbox->y1 <= y1)) {
int tmp;
tmp = pbox->y1;
while ((nbox) && (pbox->y1 == tmp)) {
int x1t, x2t;
if (pbox->x2 <= x1) {
nbox--;
pbox++;
continue;
}
if (pbox->x1 >= x2) {
nbox = 0;
break;
}
x1t = max(x1, pbox->x1);
x2t = min(x2, pbox->x2);
if (x1t != x2t)
ilbmHorzS(addrlBase, nlwidth, auxDst, depthDst, x1t, y1,
x2t-x1t, rrops);
nbox--;
pbox++;
}
}
#ifndef POLYSEGMENT
x2 = ppt->x + xorg;
#endif
}
else
{
CalcLineDeltas(x1, y1, x2, y2, adx, ady,
signdx, signdy, 1, 1, octant);
if (adx > ady) {
axis = X_AXIS;
e1 = ady << 1;
e2 = e1 - (adx << 1);
e = e1 - adx;
} else {
axis = Y_AXIS;
e1 = adx << 1;
e2 = e1 - (ady << 1);
e = e1 - ady;
SetYMajorOctant(octant);
}
FIXUP_ERROR(e, octant, bias);
while (nbox--) {
oc1 = 0;
oc2 = 0;
OUTCODES(oc1, x1, y1, pbox);
OUTCODES(oc2, x2, y2, pbox);
if ((oc1 | oc2) == 0) {
if (axis == X_AXIS)
len = adx;
else
len = ady;
#ifdef POLYSEGMENT
if (pGC->capStyle != CapNotLast)
len++;
#endif
ilbmBresS(addrlBase, nlwidth, auxDst, depthDst, signdx, signdy,
axis, x1, y1, e, e1, e2, len, rrops);
break;
} else if (oc1 & oc2) {
pbox++;
} else {
int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
int clip1 = 0, clip2 = 0;
int clipdx, clipdy;
int err;
if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1,
pbox->y2-1,
&new_x1, &new_y1, &new_x2, &new_y2,
adx, ady, &clip1, &clip2,
octant, bias, oc1, oc2) == -1) {
pbox++;
continue;
}
if (axis == X_AXIS)
len = abs(new_x2 - new_x1);
else
len = abs(new_y2 - new_y1);
#ifdef POLYSEGMENT
if (clip2 != 0 || pGC->capStyle != CapNotLast)
len++;
#else
len += (clip2 != 0);
#endif
if (len) {
if (clip1) {
clipdx = abs(new_x1 - x1);
clipdy = abs(new_y1 - y1);
if (axis == X_AXIS)
err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
else
err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
}
else
err = e;
ilbmBresS(addrlBase, nlwidth, auxDst, depthDst, signdx,
signdy, axis, new_x1, new_y1, err, e1, e2, len,
rrops);
}
pbox++;
}
}
}
}
#ifndef POLYSEGMENT
if ((pGC->capStyle != CapNotLast) &&
((ppt->x + xorg != pptInit->x + pDrawable->x) ||
(ppt->y + yorg != pptInit->y + pDrawable->y) ||
(ppt == pptInit + 1))) {
nbox = nboxInit;
pbox = pboxInit;
while (nbox--) {
if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && (x2 < pbox->x2) &&
(y2 < pbox->y2)) {
for (d = 0; d < depthDst; d++) {
addrl = ilbmScanline(addrlBase, x2, y2, auxDst);
addrlBase += nlwidth;
switch (rrops[d]) {
case RROP_BLACK:
*addrl &= rmask[x2 & PIM];
break;
case RROP_WHITE:
*addrl |= mask[x2 & PIM];
break;
case RROP_INVERT:
*addrl ^= mask[x2 & PIM];
break;
case RROP_NOP:
break;
}
}
break;
} else
pbox++;
}
}
#endif
}
void
#ifdef POLYSEGMENT
ilbmSegmentSD(pDrawable, pGC, nseg, pSeg)
DrawablePtr pDrawable;
register GCPtr pGC;
int nseg;
register xSegment *pSeg;
#else
ilbmLineSD(pDrawable, pGC, mode, npt, pptInit)
DrawablePtr pDrawable;
register GCPtr pGC;
int mode;
int npt;
DDXPointPtr pptInit;
#endif
{
int nboxInit;
register int nbox;
BoxPtr pboxInit;
register BoxPtr pbox;
#ifndef POLYSEGMENT
register DDXPointPtr ppt;
#endif
register unsigned int oc1;
register unsigned int oc2;
PixelType *addrlBase;
PixelType *addrl;
int nlwidth;
int auxDst;
int depthDst;
int xorg, yorg;
int adx;
int ady;
int signdx;
int signdy;
int e, e1, e2;
int len;
int axis;
int octant;
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
int x1, x2, y1, y2;
RegionPtr cclip;
unsigned char *rrops;
unsigned char bgrrops[AFB_MAX_DEPTH];
unsigned char *pDash;
int dashOffset;
int numInDashList;
int dashIndex;
int isDoubleDash;
int dashIndexTmp, dashOffsetTmp;
int unclippedlen;
int d;
cclip = pGC->pCompositeClip;
rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
pboxInit = REGION_RECTS(cclip);
nboxInit = REGION_NUM_RECTS(cclip);
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
addrlBase);
pDash = (unsigned char *) pGC->dash;
numInDashList = pGC->numInDashList;
isDoubleDash = (pGC->lineStyle == LineDoubleDash);
dashIndex = 0;
dashOffset = 0;
miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
numInDashList, &dashOffset);
if (isDoubleDash)
ilbmReduceRop (pGC->alu, pGC->bgPixel, pGC->planemask, pGC->depth,
bgrrops);
xorg = pDrawable->x;
yorg = pDrawable->y;
#ifdef POLYSEGMENT
while (nseg--)
#else
ppt = pptInit;
x2 = ppt->x + xorg;
y2 = ppt->y + yorg;
while (--npt)
#endif
{
nbox = nboxInit;
pbox = pboxInit;
#ifdef POLYSEGMENT
x1 = pSeg->x1 + xorg;
y1 = pSeg->y1 + yorg;
x2 = pSeg->x2 + xorg;
y2 = pSeg->y2 + yorg;
pSeg++;
#else
x1 = x2;
y1 = y2;
++ppt;
if (mode == CoordModePrevious) {
xorg = x1;
yorg = y1;
}
x2 = ppt->x + xorg;
y2 = ppt->y + yorg;
#endif
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
1, 1, octant);
if (adx > ady) {
axis = X_AXIS;
e1 = ady << 1;
e2 = e1 - (adx << 1);
e = e1 - adx;
unclippedlen = adx;
} else {
axis = Y_AXIS;
e1 = adx << 1;
e2 = e1 - (ady << 1);
e = e1 - ady;
unclippedlen = ady;
SetYMajorOctant(octant);
}
FIXUP_ERROR(e, octant, bias);
while (nbox--) {
oc1 = 0;
oc2 = 0;
OUTCODES(oc1, x1, y1, pbox);
OUTCODES(oc2, x2, y2, pbox);
if ((oc1 | oc2) == 0) {
#ifdef POLYSEGMENT
if (pGC->capStyle != CapNotLast)
unclippedlen++;
dashIndexTmp = dashIndex;
dashOffsetTmp = dashOffset;
ilbmBresD(&dashIndexTmp, pDash, numInDashList, &dashOffsetTmp,
isDoubleDash, addrlBase, nlwidth, auxDst, depthDst,
signdx, signdy, axis, x1, y1, e, e1, e2, unclippedlen,
rrops, bgrrops);
break;
#else
ilbmBresD(&dashIndex, pDash, numInDashList, &dashOffset,
isDoubleDash, addrlBase, nlwidth, auxDst, depthDst,
signdx, signdy, axis, x1, y1, e, e1, e2, unclippedlen,
rrops, bgrrops);
goto dontStep;
#endif
} else if (oc1 & oc2) {
pbox++;
} else {
int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
int clip1 = 0, clip2 = 0;
int clipdx, clipdy;
int err;
if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, pbox->y2-1,
&new_x1, &new_y1, &new_x2, &new_y2,
adx, ady, &clip1, &clip2,
octant, bias, oc1, oc2) == -1) {
pbox++;
continue;
}
dashIndexTmp = dashIndex;
dashOffsetTmp = dashOffset;
if (clip1) {
int dlen;
if (axis == X_AXIS)
dlen = abs(new_x1 - x1);
else
dlen = abs(new_y1 - y1);
miStepDash (dlen, &dashIndexTmp, pDash,
numInDashList, &dashOffsetTmp);
}
if (axis == X_AXIS)
len = abs(new_x2 - new_x1);
else
len = abs(new_y2 - new_y1);
#ifdef POLYSEGMENT
if (clip2 != 0 || pGC->capStyle != CapNotLast)
len++;
#else
len += (clip2 != 0);
#endif
if (len) {
if (clip1) {
clipdx = abs(new_x1 - x1);
clipdy = abs(new_y1 - y1);
if (axis == X_AXIS)
err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
else
err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
}
else
err = e;
ilbmBresD(&dashIndexTmp, pDash, numInDashList, &dashOffsetTmp,
isDoubleDash, addrlBase, nlwidth, auxDst, depthDst,
signdx, signdy, axis, new_x1, new_y1, err, e1, e2,
len, rrops, bgrrops);
}
pbox++;
}
}
#ifndef POLYSEGMENT
miStepDash (unclippedlen, &dashIndex, pDash,
numInDashList, &dashOffset);
dontStep: ;
#endif
}
#ifndef POLYSEGMENT
if ((pGC->capStyle != CapNotLast) &&
((dashIndex & 1) == 0 || isDoubleDash) &&
((ppt->x + xorg != pptInit->x + pDrawable->x) ||
(ppt->y + yorg != pptInit->y + pDrawable->y) ||
(ppt == pptInit + 1))) {
nbox = nboxInit;
pbox = pboxInit;
while (nbox--) {
if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && (x2 < pbox->x2) &&
(y2 < pbox->y2)) {
int rop;
for (d = 0; d < depthDst; d++) {
addrl = ilbmScanline(addrlBase, x2, y2, auxDst);
addrlBase += nlwidth;
rop = rrops[d];
if (dashIndex & 1)
rop = bgrrops[d];
switch (rop) {
case RROP_BLACK:
*addrl &= rmask[x2 & PIM];
break;
case RROP_WHITE:
*addrl |= mask[x2 & PIM];
break;
case RROP_INVERT:
*addrl ^= mask[x2 & PIM];
break;
case RROP_NOP:
break;
}
}
break;
} else
pbox++;
}
}
#endif
}