#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include "windowstr.h"
#include "regionstr.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "afb.h"
#include "maskbits.h"
void
afbSolidFillArea (pDraw, nbox, pbox, rrops)
DrawablePtr pDraw;
int nbox;
BoxPtr pbox;
register unsigned char *rrops;
{
int nlwidth;
int w;
register int h;
register PixelType *p;
register int nlw;
register PixelType startmask;
register PixelType endmask;
register int nlwExtra;
int nlwMiddle;
PixelType *pbits;
PixelType *saveP;
int saveH;
int depthDst;
int sizeDst;
register int d;
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
pbits);
while (nbox--) {
w = pbox->x2 - pbox->x1;
saveH = pbox->y2 - pbox->y1;
saveP = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
if ( ((pbox->x1 & PIM) + w) < PPW) {
for (d = 0; d < depthDst; d++) {
h = saveH;
p = saveP;
saveP += sizeDst;
maskpartialbits(pbox->x1, w, startmask);
nlwExtra = nlwidth;
switch (rrops[d]) {
case RROP_BLACK:
Duff(h, *p &= ~startmask; afbScanlineInc(p, nlwExtra));
break;
case RROP_WHITE:
Duff(h, *p |= startmask; afbScanlineInc(p, nlwExtra));
break;
case RROP_INVERT:
Duff(h, *p ^= startmask; afbScanlineInc(p, nlwExtra));
break;
case RROP_NOP:
break;
}
}
} else {
maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
for (d = 0; d < depthDst; d++) {
h = saveH;
p = saveP;
saveP += sizeDst;
nlwExtra = nlwidth - nlwMiddle;
if (startmask && endmask) {
nlwExtra -= 1;
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
nlw = nlwMiddle;
*p &= ~startmask;
p++;
Duff(nlw, *p++ = 0);
*p &= ~endmask;
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
nlw = nlwMiddle;
*p |= startmask;
p++;
Duff(nlw, *p++ = ~0);
*p |= endmask;
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
nlw = nlwMiddle;
*p ^= startmask;
p++;
Duff(nlw, *p++ ^= ~0);
*p ^= endmask;
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_NOP:
break;
}
} else if (startmask && !endmask) {
nlwExtra -= 1;
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
nlw = nlwMiddle;
*p &= ~startmask;
p++;
Duff(nlw, *p++ = 0);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
nlw = nlwMiddle;
*p |= startmask;
p++;
Duff(nlw, *p++ = ~0);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
nlw = nlwMiddle;
*p ^= startmask;
p++;
Duff(nlw, *p++ ^= ~0);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_NOP:
break;
}
} else if (!startmask && endmask) {
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
nlw = nlwMiddle;
Duff(nlw, *p++ = 0);
*p &= ~endmask;
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
nlw = nlwMiddle;
Duff(nlw, *p++ = ~0);
*p |= endmask;
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
nlw = nlwMiddle;
Duff(nlw, *p++ ^= ~0);
*p ^= endmask;
afbScanlineInc(p, nlwExtra);
}
case RROP_NOP:
break;
}
} else {
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
nlw = nlwMiddle;
Duff(nlw, *p++ = 0);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
nlw = nlwMiddle;
Duff(nlw, *p++ = ~0);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
nlw = nlwMiddle;
Duff(nlw, *p++ ^= ~0);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_NOP:
break;
}
}
}
}
pbox++;
}
}
void
afbStippleAreaPPW (pDraw, nbox, pbox, pstipple, rrops)
DrawablePtr pDraw;
int nbox;
BoxPtr pbox;
PixmapPtr pstipple;
unsigned char *rrops;
{
register PixelType *psrc;
int tileHeight;
register PixelType srcpix;
int nlwidth;
int w;
register int nlw;
register PixelType *p;
register int h;
PixelType startmask;
PixelType endmask;
int nlwMiddle;
int nlwExtra;
int sizeDst;
int depthDst;
int d;
int saveIy;
register int iy;
PixelType *pbits;
PixelType *pBase;
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
pBase);
tileHeight = pstipple->drawable.height;
psrc = (PixelType *)(pstipple->devPrivate.ptr);
while (nbox--) {
w = pbox->x2 - pbox->x1;
saveIy = pbox->y1 % tileHeight;
pbits = pBase;
if ( ((pbox->x1 & PIM) + w) < PPW) {
maskpartialbits(pbox->x1, w, startmask);
nlwExtra = nlwidth;
for (d = 0; d < depthDst; d++) {
p = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
pbits += sizeDst;
iy = saveIy;
h = pbox->y2 - pbox->y1;
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
*p &= ~(srcpix & startmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
*p |= (srcpix & startmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
*p ^= (srcpix & startmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_NOP:
break;
}
}
} else {
maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
for (d = 0; d < depthDst; d++) {
nlwExtra = nlwidth - nlwMiddle;
p = afbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
pbits += sizeDst;
iy = saveIy;
h = pbox->y2 - pbox->y1;
if (startmask && endmask) {
nlwExtra -= 1;
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
*p &= ~(srcpix & startmask);
p++;
Duff (nlw, *p++ &= ~srcpix);
*p &= ~(srcpix & endmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
*p |= (srcpix & startmask);
p++;
Duff (nlw, *p++ |= srcpix);
*p |= (srcpix & endmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
*p ^= (srcpix & startmask);
p++;
Duff (nlw, *p++ ^= srcpix);
*p ^= (srcpix & endmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_NOP:
break;
}
} else if (startmask && !endmask) {
nlwExtra -= 1;
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
*p &= ~(srcpix & startmask);
p++;
Duff(nlw, *p++ &= ~srcpix);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
*p |= (srcpix & startmask);
p++;
Duff(nlw, *p++ |= srcpix);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
*p ^= (srcpix & startmask);
p++;
Duff(nlw, *p++ ^= srcpix);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_NOP:
break;
}
} else if (!startmask && endmask) {
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
Duff(nlw, *p++ &= ~srcpix);
*p &= ~(srcpix & endmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
Duff(nlw, *p++ |= srcpix);
*p |= (srcpix & endmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
Duff(nlw, *p++ ^= srcpix);
*p ^= (srcpix & endmask);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_NOP:
break;
}
} else {
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
Duff(nlw, *p++ &= ~srcpix);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_WHITE:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
Duff(nlw, *p++ |= srcpix);
afbScanlineInc(p, nlwExtra);
}
break;
case RROP_INVERT:
while (h--) {
srcpix = psrc[iy];
iy = ++iy < tileHeight ? iy : 0;
nlw = nlwMiddle;
Duff(nlw, *p++ ^= srcpix);
afbScanlineInc(p, nlwExtra);
}
break;
}
}
}
}
pbox++;
}
}
void
afbStippleArea (pDraw, nbox, pbox, pTile, xOff, yOff, rrops)
DrawablePtr pDraw;
int nbox;
BoxPtr pbox;
PixmapPtr pTile;
int xOff;
int yOff;
unsigned char *rrops;
{
register PixelType *psrc;
int nlwidth;
register int h;
register PixelType *pdst;
int sizeDst;
int depthDst;
int tileLine;
int iline;
int w, width, x, xSrc, ySrc, srcStartOver, nend;
int tlwidth, rem, tileWidth, tileHeight, endinc;
int saveW;
register int rop;
PixelType *psrcT;
int d;
int nstart;
PixelType startmask;
PixelType endmask;
int nlMiddle;
int iy;
PixelType *pBase;
PixelType *saveP;
PixelType *pStartDst;
PixelType *pStartTile;
int saveH;
afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
pBase);
tileHeight = pTile->drawable.height;
tileWidth = pTile->drawable.width;
tlwidth = pTile->devKind / sizeof (PixelType);
xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth);
ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight);
while (nbox--) {
saveW = pbox->x2 - pbox->x1;
iline = (pbox->y1 - ySrc) % tileHeight;
psrcT = (PixelType *) pTile->devPrivate.ptr;
tileLine = iline * tlwidth;
saveH = pbox->y2 - pbox->y1;
saveP = afbScanline(pBase, pbox->x1, pbox->y1, nlwidth);
for (d = 0; d < depthDst; d++, saveP += sizeDst) {
h = saveH;
pStartDst = saveP;
pStartTile = psrcT + tileLine;
iy = iline;
while (h--) {
x = pbox->x1;
width = saveW;
pdst = pStartDst;
rop = rrops[d];
while(width > 0) {
psrc = pStartTile;
w = min(tileWidth, width);
if((rem = (x - xSrc) % tileWidth) != 0) {
w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
endinc = rem / BITMAP_SCANLINE_PAD;
getandputrrop((psrc + endinc), (rem & PIM), (x & PIM),
w, pdst, rop)
if((x & PIM) + w >= PPW)
pdst++;
} else if(((x & PIM) + w) < PPW) {
putbitsrrop(*psrc, x & PIM, w, pdst, rop);
} else {
maskbits(x, w, startmask, endmask, nlMiddle);
if (startmask)
nstart = PPW - (x & PIM);
else
nstart = 0;
if (endmask)
nend = (x + w) & PIM;
else
nend = 0;
srcStartOver = nstart > PLST;
if(startmask) {
putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
pdst++;
if(srcStartOver)
psrc++;
}
while(nlMiddle--) {
getandputrrop0(psrc, nstart, PPW, pdst, rop);
pdst++;
psrc++;
}
if(endmask) {
getandputrrop0(psrc, nstart, nend, pdst, rop);
}
}
x += w;
width -= w;
}
pStartDst += nlwidth;
if (++iy >= tileHeight) {
iy = 0;
pStartTile = psrcT;
} else
pStartTile += tlwidth;
}
}
pbox++;
}
}