#include "X.h"
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "miline.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "tga_regs.h"
extern void
TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask);
extern void
TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
int dir);
extern void
TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
int octant, int flags);
extern void
TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
int octant);
extern void
TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
int err);
extern void
TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
unsigned int planemask, int length,
unsigned char *pattern);
extern void
TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2,
int octant, int flags, int phase);
extern void
TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len,
int err, int phase);
extern void
TGASync(ScrnInfoPtr pScrn);
void TGAPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
xSegment *pSeg);
void TGAPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
DDXPointPtr pptInit);
void TGAPolySegmentDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg,
xSegment *pSeg);
void TGAPolyLinesDashed(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
DDXPointPtr pptInit);
void
#ifdef POLYSEGMENT
TGAPolySegment(
DrawablePtr pDrawable,
GCPtr pGC,
int nseg,
xSegment *pSeg
#else
TGAPolyLines(
DrawablePtr pDrawable,
GCPtr pGC,
int mode,
int npt,
DDXPointPtr pptInit
#endif
){
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
int xorg = pDrawable->x;
int yorg = pDrawable->y;
int nbox;
BoxPtr pbox;
#ifndef POLYSEGMENT
DDXPointPtr ppt;
#endif
int x1, x2, y1, y2, tmp, len;
#ifdef POLYSEGMENT
#else
#endif
if(!nboxInit)
return;
TGASetupForSolidLine(infoRec->pScrn, pGC->fgPixel, pGC->alu,
pGC->planemask);
#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) {
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--;
}
while(nbox && (y2 >= pbox->y1)) {
if ((x1 >= pbox->x1) && (x1 < pbox->x2)) {
tmp = max(y1, pbox->y1);
len = min(y2, pbox->y2) - tmp;
if (len)
TGASubsequentSolidHorVertLine(infoRec->pScrn, x1, tmp,
len, DEGREES_270);
}
nbox--;
pbox++;
}
#ifndef POLYSEGMENT
y2 = ppt->y + yorg;
#endif
} else if (y1 == y2) {
if (x1 > x2) {
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 orig_y = pbox->y1;
while(nbox && (orig_y == pbox->y1)) {
if (pbox->x2 <= x1) {
nbox--;
pbox++;
continue;
}
if (pbox->x1 >= x2) {
nbox = 0;
break;
}
tmp = max(x1, pbox->x1);
len = min(x2, pbox->x2) - tmp;
if (len)
TGASubsequentSolidHorVertLine(infoRec->pScrn, tmp,
y1, len, DEGREES_0);
nbox--;
pbox++;
}
}
#ifndef POLYSEGMENT
x2 = ppt->x + xorg;
#endif
} else{
unsigned int oc1, oc2;
int dmin, dmaj, e, octant;
if((dmaj = x2 - x1) < 0) {
dmaj = -dmaj;
octant = XDECREASING;
} else octant = 0;
if((dmin = y2 - y1) < 0) {
dmin = -dmin;
octant |= YDECREASING;
}
if(dmin >= dmaj){
tmp = dmin; dmin = dmaj; dmaj = tmp;
octant |= YMAJOR;
}
e = -dmaj - ((bias >> octant) & 1);
len = dmaj;
dmin *= 2;
dmaj *= 2;
while(nbox--) {
oc1 = oc2 = 0;
OUTCODES(oc1, x1, y1, pbox);
OUTCODES(oc2, x2, y2, pbox);
if (!(oc1 | oc2)) {
TGASubsequentSolidLine(infoRec->pScrn, x1, y1, x2, y2,
octant,
#ifdef POLYSEGMENT
(pGC->capStyle != CapNotLast) ? 0 :
#endif
OMIT_LAST
);
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 err, adx, ady;
if(octant & YMAJOR) {
ady = dmaj /= 2;
adx = dmin /= 2;
} else {
ady = dmin /= 2;
adx = dmaj /= 2;
}
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 (octant & YMAJOR)
len = abs(new_y2 - new_y1);
else
len = abs(new_x2 - new_x1);
#ifdef POLYSEGMENT
if (clip2 != 0 || pGC->capStyle != CapNotLast)
len++;
#else
len += (clip2 != 0);
#endif
if (len) {
int abserr, clipdx, clipdy;
if (clip1) {
clipdx = abs(new_x1 - x1);
clipdy = abs(new_y1 - y1);
if (octant & YMAJOR)
err = e + clipdy*dmin - clipdx*dmaj;
else
err = e + clipdx*dmin - clipdy*dmaj;
} else
err = e;
#define range infoRec->SolidBresenhamLineErrorTermBits
abserr = abs(err);
while((abserr & range) ||
(dmaj & range) ||
(dmin & range)) {
dmin /= 2;
dmaj /= 2;
abserr /= 2;
err /= 2;
}
TGASetupForClippedLine(infoRec->pScrn, x1, y1, x2,
y2, octant);
TGASubsequentClippedSolidLine(infoRec->pScrn,
new_x1, new_y1, len,
err);
}
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))
{
TGASubsequentSolidHorVertLine(infoRec->pScrn, x2, y2, 1,
DEGREES_0);
break;
}
else
pbox++;
}
}
#endif
TGASync(infoRec->pScrn);
return;
}
#undef range
void
#ifdef POLYSEGMENT
TGAPolySegmentDashed(
DrawablePtr pDrawable,
GCPtr pGC,
int nseg,
xSegment *pSeg
#else
TGAPolyLinesDashed(
DrawablePtr pDrawable,
GCPtr pGC,
int mode,
int npt,
DDXPointPtr pptInit
#endif
){
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
int xorg = pDrawable->x;
int yorg = pDrawable->y;
int nbox;
BoxPtr pbox;
#ifndef POLYSEGMENT
DDXPointPtr ppt;
#endif
unsigned int oc1, oc2;
int dmin, dmaj, e, octant;
int x1, x2, y1, y2, tmp, len, offset;
int PatternLength, PatternOffset;
#ifdef POLYSEGMENT
#else
#endif
if(!nboxInit)
return;
PatternLength = pGCPriv->DashLength;
PatternOffset = pGC->dashOffset % PatternLength;
TGASetupForDashedLine(infoRec->pScrn, pGC->fgPixel,
(pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1,
pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern);
#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((dmaj = x2 - x1) < 0) {
dmaj = -dmaj;
octant = XDECREASING;
} else octant = 0;
if((dmin = y2 - y1) < 0) {
dmin = -dmin;
octant |= YDECREASING;
}
if(dmin >= dmaj){
tmp = dmin; dmin = dmaj; dmaj = tmp;
octant |= YMAJOR;
}
e = -dmaj - ((bias >> octant) & 1);
len = dmaj;
dmin <<= 1;
dmaj <<= 1;
while(nbox--) {
oc1 = oc2 = 0;
OUTCODES(oc1, x1, y1, pbox);
OUTCODES(oc2, x2, y2, pbox);
if (!(oc1 | oc2)) {
TGASubsequentDashedLine(infoRec->pScrn, x1, y1, x2, y2,
octant,
#ifdef POLYSEGMENT
(pGC->capStyle != CapNotLast) ? 0 :
#endif
OMIT_LAST, PatternOffset);
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 err, adx, ady;
if(octant & YMAJOR) {
ady = dmaj >> 1;
adx = dmin >> 1;
} else {
ady = dmin >> 1;
adx = dmaj >> 1;
}
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 (octant & YMAJOR)
len = abs(new_y2 - new_y1);
else
len = abs(new_x2 - new_x1);
#ifdef POLYSEGMENT
if (clip2 != 0 || pGC->capStyle != CapNotLast)
len++;
#else
len += (clip2 != 0);
#endif
if (len) {
int abserr, clipdx, clipdy;
if (clip1) {
clipdx = abs(new_x1 - x1);
clipdy = abs(new_y1 - y1);
if (octant & YMAJOR)
err = e + clipdy*dmin - clipdx*dmaj;
else
err = e + clipdx*dmin - clipdy*dmaj;
} else
err = e;
#define range infoRec->DashedBresenhamLineErrorTermBits
abserr = abs(err);
while((abserr & range) ||
(dmaj & range) ||
(dmin & range)) {
dmin >>= 1;
dmaj >>= 1;
abserr >>= 1;
err /= 2;
}
if(octant & YMAJOR)
offset = abs(new_y1 - y1);
else
offset = abs(new_x1 - x1);
offset += PatternOffset;
offset %= PatternLength;
TGASetupForClippedLine(infoRec->pScrn, x1, x2, y1, y2,
octant);
TGASubsequentClippedDashedLine(infoRec->pScrn, new_x1,
new_y1, len, err,
PatternOffset);
}
pbox++;
}
}
#ifndef POLYSEGMENT
len = abs(y2 - y1);
tmp = abs(x2 - x1);
PatternOffset += (len > tmp) ? len : tmp;
PatternOffset %= PatternLength;
#endif
}
#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))
{
TGASubsequentDashedLine(infoRec->pScrn, x2, y2, x2, y2, 0, 0,
PatternOffset);
break;
} else
pbox++;
}
}
#endif
TGASync(infoRec->pScrn);
return;
}