#include "X.h"
#include "Xmd.h"
#include "gcstruct.h"
#include "window.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "ilbm.h"
#include "maskbits.h"
#include "mergerop.h"
#include "servermd.h"
#include "mi.h"
#include "mispans.h"
void
ilbmSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GCPtr pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
register DDXPointPtr ppt;
register int *pwidth;
PixelType *addrlBase;
PixelType *pBase;
int nlwidth;
register PixelType *addrl;
register int nlmiddle;
register PixelType startmask;
register PixelType endmask;
int *pwidthFree;
DDXPointPtr pptFree;
int depthDst;
int auxDst;
int d;
unsigned char *rrops;
n = nInit * miFindMaxBand(pGC->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if (!pptFree || !pwidthFree) {
if (pptFree)
DEALLOCATE_LOCAL(pptFree);
if (pwidthFree)
DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
pBase);
rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
while (n--) {
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
if (*pwidth) {
addrl = addrlBase;
switch (rrops[d]) {
case RROP_BLACK:
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl &= ~startmask;
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask)
*addrl++ &= ~startmask;
Duff (nlmiddle, *addrl++ = 0x0);
if (endmask)
*addrl &= ~endmask;
}
break;
case RROP_WHITE:
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl |= startmask;
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask)
*addrl++ |= startmask;
Duff (nlmiddle, *addrl++ = ~0);
if (endmask)
*addrl |= endmask;
}
break;
case RROP_INVERT:
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl ^= startmask;
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask)
*addrl++ ^= startmask;
Duff (nlmiddle, *addrl++ ^= ~0);
if (endmask)
*addrl ^= endmask;
}
break;
case RROP_NOP:
break;
}
}
}
pwidth++;
ppt++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
void
ilbmStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
register DDXPointPtr ppt;
register int *pwidth;
PixelType *addrlBase;
PixelType *pBase;
int nlwidth;
register PixelType *addrl;
register PixelType src;
register int nlmiddle;
register PixelType startmask;
register PixelType endmask;
PixmapPtr pStipple;
PixelType *psrc;
int tileHeight;
int *pwidthFree;
DDXPointPtr pptFree;
int d;
int depthDst;
int auxDst;
unsigned char *rrops;
n = nInit * miFindMaxBand(pGC->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if (!pptFree || !pwidthFree) {
if (pptFree)
DEALLOCATE_LOCAL(pptFree);
if (pwidthFree)
DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
pBase);
pStipple = pGC->pRotatedPixmap;
tileHeight = pStipple->drawable.height;
psrc = (PixelType *)(pStipple->devPrivate.ptr);
rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
while (n--) {
src = psrc[ppt->y % tileHeight];
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
addrl = addrlBase;
switch (rrops[d]) {
case RROP_BLACK:
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl &= ~(src & startmask);
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask)
*addrl++ &= ~(src & startmask);
Duff (nlmiddle, *addrl++ &= ~src);
if (endmask)
*addrl &= ~(src & endmask);
}
break;
case RROP_WHITE:
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl |= (src & startmask);
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask)
*addrl++ |= (src & startmask);
Duff (nlmiddle, *addrl++ |= src);
if (endmask)
*addrl |= (src & endmask);
}
break;
case RROP_INVERT:
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl ^= (src & startmask);
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask)
*addrl++ ^= (src & startmask);
Duff (nlmiddle, *addrl++ ^= src);
if (endmask)
*addrl ^= (src & endmask);
}
break;
case RROP_NOP:
break;
}
}
pwidth++;
ppt++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
void
ilbmTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
register DDXPointPtr ppt;
register int *pwidth;
PixelType *addrlBase;
PixelType *pBase;
int nlwidth;
register PixelType *addrl;
register PixelType src;
register int nlmiddle;
register PixelType startmask;
register PixelType endmask;
PixmapPtr pTile;
PixelType *psrc;
int tileHeight;
int rop;
int *pwidthFree;
DDXPointPtr pptFree;
int auxDst;
int depthDst;
int d;
n = nInit * miFindMaxBand(pGC->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if (!pptFree || !pwidthFree) {
if (pptFree)
DEALLOCATE_LOCAL(pptFree);
if (pwidthFree)
DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
pBase);
pTile = pGC->pRotatedPixmap;
tileHeight = pTile->drawable.height;
psrc = (PixelType *)(pTile->devPrivate.ptr);
rop = pGC->alu;
switch (rop) {
case GXcopy:
#define DoMaskCopyRop(src,dst,mask) ((dst) & ~(mask) | (src) & (mask))
while (n--) {
if (*pwidth) {
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
if (!(pGC->planemask & (1 << d)))
continue;
addrl = addrlBase;
src = psrc[ppt->y % tileHeight + tileHeight * d];
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl = DoMaskCopyRop (src, *addrl, startmask);
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask) {
*addrl = DoMaskCopyRop (src, *addrl, startmask);
addrl++;
}
while (nlmiddle--) {
*addrl = src;
addrl++;
}
if (endmask)
*addrl = DoMaskCopyRop (src, *addrl, endmask);
}
}
}
pwidth++;
ppt++;
}
break;
default:
{
register DeclareMergeRop ();
InitializeMergeRop(rop,~0);
while (n--) {
if (*pwidth) {
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
if (!(pGC->planemask & (1 << d)))
continue;
addrl = addrlBase;
src = psrc[ppt->y % tileHeight + tileHeight * d];
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl = DoMaskMergeRop (src, *addrl, startmask);
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask) {
*addrl = DoMaskMergeRop (src, *addrl, startmask);
addrl++;
}
while (nlmiddle--) {
*addrl = DoMergeRop (src, *addrl);
addrl++;
}
if (endmask)
*addrl = DoMaskMergeRop (src, *addrl, endmask);
}
}
}
pwidth++;
ppt++;
}
break;
}
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
void
ilbmOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
register DDXPointPtr ppt;
register int *pwidth;
PixelType *addrlBase;
PixelType *pBase;
int nlwidth;
register PixelType *addrl;
register PixelType src;
register int nlmiddle;
register PixelType startmask;
register PixelType endmask;
PixmapPtr pTile;
PixelType *psrc;
int tileHeight;
int rop;
unsigned char *rropsOS;
int *pwidthFree;
DDXPointPtr pptFree;
int auxDst;
int depthDst;
int d;
n = nInit * miFindMaxBand(pGC->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if (!pptFree || !pwidthFree) {
if (pptFree)
DEALLOCATE_LOCAL(pptFree);
if (pwidthFree)
DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
pBase);
pTile = pGC->pRotatedPixmap;
tileHeight = pTile->drawable.height;
psrc = (PixelType *)(pTile->devPrivate.ptr);
rop = pGC->alu;
rropsOS = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rropOS;
switch (rop) {
case GXcopy:
#define DoMaskCopyRop(src,dst,mask) ((dst) & ~(mask) | (src) & (mask))
while (n--) {
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
if (*pwidth) {
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
switch (rropsOS[d]) {
case RROP_BLACK:
src = 0;
break;
case RROP_WHITE:
src = ~0;
break;
case RROP_INVERT:
src = ~psrc[ppt->y % tileHeight];
break;
case RROP_COPY:
src = psrc[ppt->y % tileHeight];
break;
case RROP_NOP:
continue;
}
addrl = addrlBase;
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl = DoMaskCopyRop (src, *addrl, startmask);
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask) {
*addrl = DoMaskCopyRop (src, *addrl, startmask);
addrl++;
}
while (nlmiddle--) {
*addrl = src;
addrl++;
}
if (endmask)
*addrl = DoMaskCopyRop (src, *addrl, endmask);
}
}
}
pwidth++;
ppt++;
}
break;
default:
{
register DeclareMergeRop ();
InitializeMergeRop(rop,~0);
while (n--) {
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
if (*pwidth) {
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
switch (rropsOS[d]) {
case RROP_BLACK:
src = 0;
break;
case RROP_WHITE:
src = ~0;
break;
case RROP_INVERT:
src = ~psrc[ppt->y % tileHeight];
break;
case RROP_COPY:
src = psrc[ppt->y % tileHeight];
break;
case RROP_NOP:
continue;
}
addrl = addrlBase;
if ( ((ppt->x & PIM) + *pwidth) < PPW) {
maskpartialbits(ppt->x, *pwidth, startmask);
*addrl = DoMaskMergeRop (src, *addrl, startmask);
} else {
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
if (startmask) {
*addrl = DoMaskMergeRop (src, *addrl, startmask);
addrl++;
}
while (nlmiddle--) {
*addrl = DoMergeRop (src, *addrl);
addrl++;
}
if (endmask)
*addrl = DoMaskMergeRop (src, *addrl, endmask);
}
}
}
pwidth++;
ppt++;
}
break;
}
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
void
ilbmUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int iline;
int n;
register DDXPointPtr ppt;
register int *pwidth;
PixelType *addrlBase;
PixelType *pBase;
int nlwidth;
register PixelType *pdst;
register PixelType *psrc;
register int nlMiddle;
register int rop, nstart;
PixelType startmask;
PixmapPtr pTile;
int w, width, x, xSrc, ySrc, srcStartOver, nend;
int tlwidth, rem, tileWidth, tileHeight, endinc;
PixelType endmask, *psrcT;
int *pwidthFree;
DDXPointPtr pptFree;
int auxDst;
int sizeTile;
int depthDst;
register int d;
n = nInit * miFindMaxBand(pGC->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if (!pptFree || !pwidthFree) {
if (pptFree)
DEALLOCATE_LOCAL(pptFree);
if (pwidthFree)
DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
pTile = pGC->tile.pixmap;
tlwidth = pTile->devKind/PGSZB;
rop = pGC->alu;
xSrc = pDrawable->x;
ySrc = pDrawable->y;
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
pBase);
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
sizeTile = tlwidth * tileHeight;
xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
while (n--) {
iline = (ppt->y - ySrc) % tileHeight;
psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
for (d = 0; d < depthDst; d++, psrcT += sizeTile, addrlBase += nlwidth) {
if (!(pGC->planemask & (1 << d)))
continue;
if (*pwidth) {
x = ppt->x;
pdst = addrlBase;
width = *pwidth;
while (width > 0) {
psrc = psrcT;
w = min(tileWidth, width);
if ((rem = (x - xSrc) % tileWidth) != 0) {
w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
endinc = rem / BITMAP_SCANLINE_PAD;
getandputrop((psrc+endinc), (rem&PIM), (x & PIM), w, pdst, rop);
if ((x & PIM) + w >= PPW)
pdst++;
} else if (((x & PIM) + w) < PPW) {
putbitsrop(*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) {
putbitsrop(*psrc, (x & PIM), nstart, pdst, rop);
pdst++;
if (srcStartOver)
psrc++;
}
while (nlMiddle--) {
getandputrop0(psrc, nstart, PPW, pdst, rop);
pdst++;
psrc++;
}
if (endmask) {
getandputrop0(psrc, nstart, nend, pdst, rop);
}
}
x += w;
width -= w;
}
}
}
ppt++;
pwidth++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
void
ilbmUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
register DDXPointPtr ppt;
register int *pwidth;
int iline;
PixelType *addrlBase;
PixelType *pBase;
int nlwidth;
register PixelType *pdst;
register PixelType *psrc;
register int nlMiddle;
register int rop, nstart;
PixelType startmask;
PixmapPtr pTile;
int w, width, x, xSrc, ySrc, srcStartOver, nend;
PixelType endmask, *psrcT;
int tlwidth, rem, tileWidth, endinc;
int tileHeight;
int *pwidthFree;
DDXPointPtr pptFree;
unsigned char *rrops;
register int d;
int auxDst;
int depthDst;
n = nInit * miFindMaxBand(pGC->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if (!pptFree || !pwidthFree) {
if (pptFree)
DEALLOCATE_LOCAL(pptFree);
if (pwidthFree)
DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
pTile = pGC->stipple;
tlwidth = pTile->devKind/PGSZB;
xSrc = pDrawable->x;
ySrc = pDrawable->y;
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
pBase);
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
while (n--) {
iline = (ppt->y - ySrc) % tileHeight;
psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
rop = rrops[d];
if (rop == RROP_NOP)
continue;
pdst = addrlBase;
x = ppt->x;
if (*pwidth) {
width = *pwidth;
while (width > 0) {
psrc = psrcT;
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;
}
}
}
ppt++;
pwidth++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
void
ilbmUnnaturalOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int iline;
int n;
register DDXPointPtr ppt;
register int *pwidth;
PixelType *addrlBase;
PixelType *pBase;
int nlwidth;
register PixelType *pdst;
register PixelType *psrc;
register int nlMiddle;
register int d;
register PixelType tmpsrc;
register PixelType tmpdst;
register int alu, nstart;
register unsigned char *rropsOS;
PixelType startmask;
PixmapPtr pTile;
int w, width, x, xSrc, ySrc, srcStartOver, nend;
int tlwidth, rem, tileWidth, tileHeight, endinc;
PixelType endmask, *psrcT;
int *pwidthFree;
DDXPointPtr pptFree;
int auxDst;
int sizeTile;
int depthDst;
n = nInit * miFindMaxBand(pGC->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if (!pptFree || !pwidthFree) {
if (pptFree)
DEALLOCATE_LOCAL(pptFree);
if (pwidthFree)
DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
pTile = pGC->stipple;
tlwidth = pTile->devKind/PGSZB;
alu = pGC->alu;
xSrc = pDrawable->x;
ySrc = pDrawable->y;
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
pBase);
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
rropsOS = ilbmGetGCPrivate(pGC)->rropOS;
xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
while (n--) {
iline = (ppt->y - ySrc) % tileHeight;
psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {
if (!(pGC->planemask & (1 << d)))
continue;
if (*pwidth) {
x = ppt->x;
pdst = addrlBase;
width = *pwidth;
while (width > 0) {
psrc = psrcT;
w = min(tileWidth, width);
if ((rem = (x - xSrc) % tileWidth) != 0) {
w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
endinc = rem / BITMAP_SCANLINE_PAD;
switch (rropsOS[d]) {
case RROP_BLACK:
tmpsrc = 0;
break;
case RROP_WHITE:
tmpsrc = ~0;
break;
case RROP_COPY:
getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
break;
case RROP_INVERT:
getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
tmpsrc = ~tmpsrc;
break;
}
if (alu != GXcopy) {
getbits (pdst, (x & PIM), w, tmpdst);
DoRop (tmpsrc, alu, tmpsrc, tmpdst);
}
putbits (tmpsrc, (x & PIM), w, pdst);
if ((x & PIM) + w >= PPW)
pdst++;
} else if (((x & PIM) + w) < PPW) {
switch (rropsOS[d]) {
case RROP_BLACK:
tmpsrc = 0;
break;
case RROP_WHITE:
tmpsrc = ~0;
break;
case RROP_COPY:
tmpsrc = *psrc;
break;
case RROP_INVERT:
tmpsrc = ~*psrc;
break;
}
if (alu != GXcopy) {
getbits (pdst, (x & PIM), w, tmpdst);
DoRop (tmpsrc, alu, tmpsrc, tmpdst);
}
putbits (tmpsrc, (x & PIM), w, pdst);
} 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) {
switch (rropsOS[d]) {
case RROP_BLACK:
tmpsrc = 0;
break;
case RROP_WHITE:
tmpsrc = ~0;
break;
case RROP_COPY:
tmpsrc = *psrc;
break;
case RROP_INVERT:
tmpsrc = ~*psrc;
break;
}
if (alu != GXcopy) {
getbits (pdst, (x & PIM), nstart, tmpdst);
DoRop (tmpsrc, alu, tmpsrc, tmpdst);
}
putbits (tmpsrc, (x & PIM), nstart, pdst);
pdst++;
if (srcStartOver)
psrc++;
}
while (nlMiddle--) {
switch (rropsOS[d]) {
case RROP_BLACK:
tmpsrc = 0;
break;
case RROP_WHITE:
tmpsrc = ~0;
break;
case RROP_COPY:
getbits (psrc, nstart, PPW, tmpsrc);
break;
case RROP_INVERT:
getbits (psrc, nstart, PPW, tmpsrc);
tmpsrc = ~tmpsrc;
break;
}
if (alu != GXcopy) {
tmpdst = *pdst;
DoRop (tmpsrc, alu, tmpsrc, tmpdst);
}
*pdst++ = tmpsrc;
psrc++;
}
if (endmask) {
switch (rropsOS[d]) {
case RROP_BLACK:
tmpsrc = 0;
break;
case RROP_WHITE:
tmpsrc = ~0;
break;
case RROP_COPY:
getbits (psrc, nstart, nend, tmpsrc);
break;
case RROP_INVERT:
getbits (psrc, nstart, nend, tmpsrc);
tmpsrc = ~tmpsrc;
break;
}
if (alu != GXcopy) {
tmpdst = *pdst;
DoRop (tmpsrc, alu, tmpsrc, tmpdst);
}
putbits (tmpsrc, 0, nend, pdst);
}
}
x += w;
width -= w;
}
}
}
ppt++;
pwidth++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}