#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <stdlib.h>
#include "xf4bpp.h"
#include "OScompiler.h"
#include "mfbmap.h"
#include "mfb.h"
#include "maskbits.h"
#include "mi.h"
#include "miline.h"
#include "vgaVideo.h"
#include "wm3.h"
#include "xf86str.h"
extern ScrnInfoPtr *xf86Screens;
#ifdef POLYSEGMENT
static void DoV16SegmentSS(
DrawablePtr, GCPtr, int, xSegment*
);
void
xf4bppSegmentSS (pDrawable, pGC, nseg, pSeg)
DrawablePtr pDrawable;
GCPtr pGC;
int nseg;
register xSegment *pSeg;
{
if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
miPolySegment(pDrawable, pGC, nseg, pSeg);
} else {
DO_WM3(pGC,DoV16SegmentSS (pDrawable, pGC, nseg, pSeg));
}
}
#else
static void DoV16LineSS(
DrawablePtr, GCPtr, int, int, DDXPointPtr
);
void
xf4bppLineSS (pDrawable, pGC, mode, npt, pptInit)
DrawablePtr pDrawable;
GCPtr pGC;
int mode;
int npt;
DDXPointPtr pptInit;
{
if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
miZeroLine(pDrawable, pGC, mode, npt, pptInit);
} else {
DO_WM3(pGC,DoV16LineSS (pDrawable, pGC, mode, npt, pptInit));
}
}
#endif
static void
#ifdef POLYSEGMENT
DoV16SegmentSS (pDrawable, pGC, nseg, pSeg)
DrawablePtr pDrawable;
GCPtr pGC;
int nseg;
register xSegment *pSeg;
#else
DoV16LineSS (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;
#ifndef POLYSEGMENT
PixelType *addrl;
#endif
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);
register int y1, y2;
register int x1, x2;
RegionPtr cclip;
#ifndef POLYSEGMENT
int alu = pGC->alu;
#endif
if (!(pGC->planemask & 0x0F))
return;
cclip = pGC->pCompositeClip;
pboxInit = REGION_RECTS(cclip);
nboxInit = REGION_NUM_RECTS(cclip);
nlwidth = BYTES_PER_LINE(pDrawable) >> 2;
addrlBase = (PixelType *)VIDBASE(pDrawable);
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)
{
xf4bppVertS (addrlBase, nlwidth,
x1, y1t, y2t-y1t);
}
}
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)
{
xf4bppHorzS (addrlBase, nlwidth,
x1t, y1, x2t-x1t);
}
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
xf4bppBresS (addrlBase, nlwidth,
signdx, signdy, axis, x1, y1,
e, e1, e2, len);
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;
xf4bppBresS (addrlBase, nlwidth,
signdx, signdy, axis, new_x1, new_y1,
err, e1, e2, len);
}
pbox++;
}
}
}
}
#ifndef POLYSEGMENT
if ((pGC->capStyle != CapNotLast) &&
((ppt->x + xorg != pptInit->x + pDrawable->x) ||
(ppt->y + yorg != pptInit->y + pDrawable->y) ||
(ppt == pptInit + 1)))
{
PixelType _mask;
if (alu == RROP_BLACK)
_mask = mfbGetrmask(x2 & PIM);
else
_mask = mfbGetmask(x2 & PIM);
nbox = nboxInit;
pbox = pboxInit;
while (nbox--)
{
if ((x2 >= pbox->x1) &&
(y2 >= pbox->y1) &&
(x2 < pbox->x2) &&
(y2 < pbox->y2))
{
addrl = mfbScanline(addrlBase, x2, y2, nlwidth);
UPDRW(addrl,_mask);
break;
}
else
pbox++;
}
}
#endif
}
#ifdef POLYSEGMENT
static void DoV16SegmentSD(
DrawablePtr, GCPtr, int, xSegment*
);
void
xf4bppSegmentSD (pDrawable, pGC, nseg, pSeg)
DrawablePtr pDrawable;
GCPtr pGC;
int nseg;
register xSegment *pSeg;
{
if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
miPolySegment(pDrawable, pGC, nseg, pSeg);
} else {
DO_WM3(pGC,DoV16SegmentSD (pDrawable, pGC, nseg, pSeg));
}
}
#else
static void DoV16LineSD(
DrawablePtr, GCPtr, int, int, DDXPointPtr
);
void
xf4bppLineSD (pDrawable, pGC, mode, npt, pptInit)
DrawablePtr pDrawable;
GCPtr pGC;
int mode;
int npt;
DDXPointPtr pptInit;
{
if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
miZeroDashLine(pDrawable, pGC, mode, npt, pptInit);
} else {
DO_WM3(pGC,DoV16LineSD (pDrawable, pGC, mode, npt, pptInit));
}
}
#endif
static void
#ifdef POLYSEGMENT
DoV16SegmentSD (pDrawable, pGC, nseg, pSeg)
DrawablePtr pDrawable;
register GCPtr pGC;
int nseg;
register xSegment *pSeg;
#else
DoV16LineSD( 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 *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 x1, x2, y1, y2;
RegionPtr cclip;
int fgink, bgink;
unsigned char *pDash;
int dashOffset;
int numInDashList;
int dashIndex;
int isDoubleDash;
int dashIndexTmp, dashOffsetTmp;
int unclippedlen;
if (!(pGC->planemask & 0x0F))
return;
cclip = pGC->pCompositeClip;
fgink = bgink = pGC->fgPixel;
pboxInit = REGION_RECTS(cclip);
nboxInit = REGION_NUM_RECTS(cclip);
nlwidth = BYTES_PER_LINE(pDrawable) >> 2;
addrl = (PixelType *)VIDBASE(pDrawable);
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)
bgink = pGC->bgPixel;
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;
xf4bppBresD (pDrawable, fgink, bgink,
&dashIndexTmp, pDash, numInDashList,
&dashOffsetTmp, isDoubleDash,
addrl, nlwidth,
signdx, signdy, axis, x1, y1,
e, e1, e2, unclippedlen);
break;
#else
xf4bppBresD (pDrawable, fgink, bgink,
&dashIndex, pDash, numInDashList,
&dashOffset, isDoubleDash,
addrl, nlwidth,
signdx, signdy, axis, x1, y1,
e, e1, e2, unclippedlen);
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;
xf4bppBresD (pDrawable, fgink, bgink,
&dashIndexTmp, pDash, numInDashList,
&dashOffsetTmp, isDoubleDash,
addrl, nlwidth,
signdx, signdy, axis, new_x1, new_y1,
err, e1, e2, len);
}
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))
{
unsigned long _mask;
_mask = mfbGetmask(x2 & PIM);
addrl = mfbScanline(addrl, x2, y2, nlwidth);
UPDRW(addrl,_mask);
break;
}
else
pbox++;
}
}
#endif
}
#if 0
#ifndef POLYSEGMENT
int
mfbClipLine(pbox, box,
ppt1Orig, ppt1, ppt2,
adx, ady, signdx, signdy, axis,
pclip1, pclip2)
BoxPtr pbox;
BoxRec box;
DDXPointPtr ppt1Orig, ppt1, ppt2;
int adx, ady;
int signdx, signdy;
register int axis;
int *pclip1, *pclip2;
{
DDXPointRec pt1Orig, pt1, pt2;
register int swapped = 0;
int clipDone = 0;
register unsigned int utmp;
register int oc1, oc2;
int clip1, clip2;
pt1Orig = *ppt1Orig;
pt1 = *ppt1;
pt2 = *ppt2;
clip1 = 0;
clip2 = 0;
do
{
oc1 = 0;
oc2 = 0;
OUTCODES(oc1, pt1.x, pt1.y, pbox);
OUTCODES(oc2, pt2.x, pt2.y, pbox);
if (oc1 & oc2)
clipDone = -1;
else if ((oc1 | oc2) == 0)
{
clipDone = 1;
if (swapped)
{
SWAPPT(pt1, pt2);
SWAPINT(oc1, oc2);
SWAPINT(clip1, clip2);
}
}
else
{
if (!oc1)
{
SWAPPT(pt1, pt2);
SWAPINT(oc1, oc2);
SWAPINT(clip1, clip2);
swapped = !swapped;
}
clip1 |= oc1;
if (oc1 & OUT_LEFT)
{
pt1.x = box.x1;
utmp = abs(box.x1 - pt1Orig.x);
utmp *= ady;
if(axis==X_AXIS)
{
pt1.y = pt1Orig.y + SignTimes(signdy, round(utmp, adx));
}
else
{
utmp <<= 1;
if (swapped)
utmp += ady;
else
utmp -= ady;
pt1.y = pt1Orig.y + SignTimes(signdy, ceiling(utmp, 2*adx));
if (swapped)
pt1.y -= signdy;
}
}
else if (oc1 & OUT_ABOVE)
{
pt1.y = box.y1;
utmp = abs(box.y1 - pt1Orig.y);
utmp *= adx;
if (axis == Y_AXIS)
{
pt1.x = pt1Orig.x + SignTimes(signdx, round(utmp, ady));
}
else
{
utmp <<= 1;
if (swapped)
utmp += adx;
else
utmp -= adx;
pt1.x = pt1Orig.x + SignTimes(signdx, ceiling(utmp, 2*ady));
if (swapped)
pt1.x -= signdx;
}
}
else if (oc1 & OUT_RIGHT)
{
pt1.x = box.x2;
utmp = abs(pt1Orig.x - box.x2);
utmp *= ady;
if (axis == X_AXIS)
{
pt1.y = pt1Orig.y + SignTimes(signdy, round(utmp, adx));
}
else
{
utmp <<= 1;
if (swapped)
utmp += ady;
else
utmp -= ady;
pt1.y = pt1Orig.y + SignTimes(signdy, ceiling(utmp, 2*adx));
if (swapped)
pt1.y -= signdy;
}
}
else if (oc1 & OUT_BELOW)
{
pt1.y = box.y2;
utmp = abs(pt1Orig.y - box.y2);
utmp *= adx;
if (axis == Y_AXIS)
{
pt1.x = pt1Orig.x + SignTimes(signdx, round(utmp, ady));
}
else
{
utmp <<= 1;
if (swapped)
utmp += adx;
else
utmp -= adx;
pt1.x = pt1Orig.x + SignTimes(signdx, ceiling(utmp, 2*ady));
if (swapped)
pt1.x -= signdx;
}
}
}
} while(!clipDone);
*ppt1 = pt1;
*ppt2 = pt2;
*pclip1 = clip1;
*pclip2 = clip2;
return clipDone;
}
#endif
#endif