#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xmd.h>
#include "servermd.h"
#include "gcstruct.h"
#include "window.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "cfb.h"
#include "cfbmskbits.h"
#include "mergerop.h"
#if PSZ == 8
#include "cfb8bit.h"
#endif
#define MFB_CONSTS_ONLY
#include "maskbits.h"
#include "mi.h"
#include "mispans.h"
#ifdef notdef
#include <stdio.h>
static
dumpspans(n, ppt, pwidth)
int n;
DDXPointPtr ppt;
int *pwidth;
{
fprintf(stderr,"%d spans\n", n);
while (n--) {
fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth);
ppt++;
pwidth++;
}
fprintf(stderr, "\n");
}
#endif
void
cfbUnnaturalTileFS(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;
void (*fill)(DrawablePtr, int, DDXPointPtr, int *, PixmapPtr, int, int, int, unsigned long);
int xrot, yrot;
if (!(pGC->planemask))
return;
#if PSZ == 24
if (pGC->tile.pixmap->drawable.width & 3)
#else
if (pGC->tile.pixmap->drawable.width & PIM)
#endif
{
fill = cfbFillSpanTileOddGeneral;
if ((pGC->planemask & PMSK) == PMSK)
{
if (pGC->alu == GXcopy)
fill = cfbFillSpanTileOddCopy;
}
}
else
{
fill = cfbFillSpanTile32sGeneral;
if ((pGC->planemask & PMSK) == PMSK)
{
if (pGC->alu == GXcopy)
fill = cfbFillSpanTile32sCopy;
}
}
n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
if ( n == 0 )
return;
pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if(!ppt || !pwidth)
{
if (ppt) DEALLOCATE_LOCAL(ppt);
if (pwidth) DEALLOCATE_LOCAL(pwidth);
return;
}
n = miClipSpans( cfbGetCompositeClip(pGC),
pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
xrot = pDrawable->x + pGC->patOrg.x;
yrot = pDrawable->y + pGC->patOrg.y;
(*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
DEALLOCATE_LOCAL(ppt);
DEALLOCATE_LOCAL(pwidth);
}
#if PSZ == 8
void
cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
DDXPointPtr ppt;
int *pwidth;
int *pwidthFree;
DDXPointPtr pptFree;
CfbBits *pdstBase;
int nlwDst;
register CfbBits *pdst;
PixmapPtr pStipple;
int nlw;
int x, y, w, xrem, xSrc, ySrc;
int stwidth, stippleWidth;
int stippleHeight;
register CfbBits bits, inputBits;
register int partBitsLeft;
int nextPartBits;
int bitsLeft, bitsWhole;
CfbBits *srcTemp, *srcStart;
CfbBits *psrcBase;
CfbBits startmask, endmask;
if (pGC->fillStyle == FillStippled)
cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
else
cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
if (cfb8StippleRRop == GXnoop)
return;
n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
if ( n == 0 )
return;
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( cfbGetCompositeClip(pGC),
pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
pStipple = pGC->stipple;
stwidth = pStipple->devKind >> PWSH;
stippleWidth = pStipple->drawable.width;
stippleHeight = pStipple->drawable.height;
psrcBase = (CfbBits *) pStipple->devPrivate.ptr;
cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
modulus (pGC->patOrg.x, stippleWidth, xSrc);
xSrc += pDrawable->x - stippleWidth;
modulus (pGC->patOrg.y, stippleHeight, ySrc);
ySrc += pDrawable->y - stippleHeight;
bitsWhole = stippleWidth;
while (n--)
{
x = ppt->x;
y = ppt->y;
ppt++;
w = *pwidth++;
pdst = pdstBase + y * nlwDst + (x >> PWSH);
y = (y - ySrc) % stippleHeight;
srcStart = psrcBase + y * stwidth;
xrem = ((x & ~(PGSZB-1)) - xSrc) % stippleWidth;
srcTemp = srcStart + (xrem >> MFB_PWSH);
bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
xrem &= MFB_PIM;
NextUnnaturalStippleWord
if (partBitsLeft < xrem)
FatalError ("cfbUnnaturalStippleFS bad partBitsLeft %d xrem %d",
partBitsLeft, xrem);
NextSomeBits (inputBits, xrem);
partBitsLeft -= xrem;
if (((x & PIM) + w) <= PPW)
{
maskpartialbits (x, w, startmask)
NextUnnaturalStippleBits
*pdst = MaskRRopPixels(*pdst,bits,startmask);
}
else
{
maskbits (x, w, startmask, endmask, nlw);
nextPartBits = (x & (PGSZB-1)) + w;
if (nextPartBits < partBitsLeft)
{
if (startmask)
{
MaskRRopBitGroup(pdst,GetBitGroup(inputBits),startmask)
pdst++;
NextBitGroup (inputBits);
}
while (nlw--)
{
RRopBitGroup (pdst, GetBitGroup (inputBits));
pdst++;
NextBitGroup (inputBits);
}
if (endmask)
{
MaskRRopBitGroup(pdst,GetBitGroup(inputBits),endmask)
}
}
else if (bitsLeft != bitsWhole && nextPartBits < partBitsLeft + bitsLeft)
{
NextUnnaturalStippleBitsFast
if (startmask)
{
*pdst = MaskRRopPixels(*pdst,bits,startmask);
pdst++;
NextUnnaturalStippleBitsFast
}
while (nlw--)
{
*pdst = RRopPixels(*pdst,bits);
pdst++;
NextUnnaturalStippleBitsFast
}
if (endmask)
*pdst = MaskRRopPixels (*pdst,bits,endmask);
}
else
{
NextUnnaturalStippleBits
if (startmask)
{
*pdst = MaskRRopPixels(*pdst,bits,startmask);
pdst++;
NextUnnaturalStippleBits
}
while (nlw--)
{
*pdst = RRopPixels(*pdst,bits);
pdst++;
NextUnnaturalStippleBits
}
if (endmask)
*pdst = MaskRRopPixels(*pdst,bits,endmask);
}
}
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
#else
void
cfbUnnaturalStippleFS(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;
CfbBits *addrlBase;
int nlwidth;
register CfbBits *pdst;
PixmapPtr pStipple;
register int w;
int width, x, xrem, xSrc, ySrc;
CfbBits tmpSrc, tmpDst1, tmpDst2;
int stwidth, stippleWidth;
CfbBits *psrcS;
int rop, stiprop = 0;
int stippleHeight;
int *pwidthFree;
DDXPointPtr pptFree;
CfbBits fgfill, bgfill;
if (!(pGC->planemask))
return;
n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
if ( n == 0 )
return;
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( cfbGetCompositeClip(pGC),
pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
rop = pGC->alu;
if (pGC->fillStyle == FillStippled) {
switch (rop) {
case GXand:
case GXcopy:
case GXnoop:
case GXor:
stiprop = rop;
break;
default:
stiprop = rop;
rop = GXcopy;
}
}
fgfill = PFILL(pGC->fgPixel);
bgfill = PFILL(pGC->bgPixel);
pStipple = pGC->stipple;
stwidth = pStipple->devKind / PGSZB;
stippleWidth = pStipple->drawable.width;
stippleHeight = pStipple->drawable.height;
cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrlBase)
modulus (pGC->patOrg.x, stippleWidth, xSrc);
xSrc += pDrawable->x - stippleWidth;
modulus (pGC->patOrg.y, stippleHeight, ySrc);
ySrc += pDrawable->y - stippleHeight;
while (n--)
{
iline = (ppt->y - ySrc) % stippleHeight;
x = ppt->x;
pdst = addrlBase + (ppt->y * nlwidth);
psrcS = (CfbBits *) pStipple->devPrivate.ptr + (iline * stwidth);
if (*pwidth)
{
width = *pwidth;
while(width > 0)
{
int xtemp;
#if PSZ != 32 || PPW != 1
int tmpx;
#endif
register CfbBits *ptemp;
register CfbBits *pdsttmp;
xrem = (x - xSrc) % stippleWidth;
#if PSZ == 24
w = 1;
#else
w = min((stippleWidth - xrem), width);
w = min(w, PPW - (x & PIM));
w = min(w, MFB_PPW - (x & MFB_PIM));
#endif
xtemp = (xrem & MFB_PIM);
ptemp = (CfbBits *)(psrcS + (xrem >> MFB_PWSH));
#if PSZ == 24
tmpx = x & 3;
pdsttmp = pdst + ((x * 3)>>2);
#else
#if PSZ != 32 || PPW != 1
tmpx = x & PIM;
#endif
pdsttmp = pdst + (x>>PWSH);
#endif
switch ( pGC->fillStyle ) {
case FillOpaqueStippled:
#if PSZ == 24
getstipplepixels24(ptemp, xtemp, 0, &bgfill, &tmpDst1, xrem);
getstipplepixels24(ptemp, xtemp, 1, &fgfill, &tmpDst2, xrem);
#else
getstipplepixels(ptemp, xtemp, w, 0, &bgfill, &tmpDst1);
getstipplepixels(ptemp, xtemp, w, 1, &fgfill, &tmpDst2);
#endif
break;
case FillStippled:
#if PSZ == 24
getbits24(pdsttmp, tmpSrc, x);
getstipplepixels24(ptemp, xtemp, 0, &tmpSrc, &tmpDst1, xrem);
#else
getbits(pdsttmp, tmpx, w, tmpSrc);
getstipplepixels(ptemp, xtemp, w, 0, &tmpSrc, &tmpDst1);
#endif
if (rop != stiprop) {
#if PSZ == 24
putbitsrop24(fgfill, 0, &tmpSrc, pGC->planemask, stiprop);
#else
putbitsrop(fgfill, 0, w, &tmpSrc, pGC->planemask, stiprop);
#endif
} else {
tmpSrc = fgfill;
}
#if PSZ == 24
getstipplepixels24(ptemp, xtemp, 1, &tmpSrc, &tmpDst2, xrem);
#else
getstipplepixels(ptemp, xtemp, w, 1, &tmpSrc, &tmpDst2);
#endif
break;
}
tmpDst2 |= tmpDst1;
#if PSZ == 24
putbitsrop24(tmpDst2, tmpx, pdsttmp, pGC->planemask, rop);
#else
putbitsrop(tmpDst2, tmpx, w, pdsttmp, pGC->planemask, rop);
#endif
x += w;
width -= w;
}
}
ppt++;
pwidth++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
#endif
#if PSZ == 8
void
cfb8Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GCPtr pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
DDXPointPtr ppt;
int *pwidth;
CfbBits *src;
int stippleHeight;
PixmapPtr stipple;
int nlwDst;
int x,y,w;
CfbBits startmask;
CfbBits endmask;
register CfbBits *dst;
register int nlw;
CfbBits *dstTmp;
int nlwTmp;
CfbBits *pbits;
register CfbBits xor;
register CfbBits mask;
register CfbBits bits;
int wEnd;
int *pwidthFree;
DDXPointPtr pptFree;
cfbPrivGCPtr devPriv;
devPriv = cfbGetGCPrivate(pGC);
cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
n = nInit * miFindMaxBand(pGC->pCompositeClip);
if ( n == 0 )
return;
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);
stipple = pGC->pRotatedPixmap;
src = (CfbBits *)stipple->devPrivate.ptr;
stippleHeight = stipple->drawable.height;
cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
while (n--)
{
w = *pwidth++;
x = ppt->x;
y = ppt->y;
ppt++;
dst = pbits + (y * nlwDst) + (x >> PWSH);
if (((x & PIM) + w) <= PPW)
{
maskpartialbits(x, w, startmask);
endmask = 0;
nlw = 0;
}
else
{
maskbits (x, w, startmask, endmask, nlw);
}
bits = src[y % stippleHeight];
RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
#if PPW == 4
if (cfb8StippleRRop == GXcopy)
{
xor = devPriv->xor;
if (w < (PGSZ*2))
{
if (startmask)
{
mask = cfb8PixelMasks[GetBitGroup(bits)];
*dst = (*dst & ~(mask & startmask)) |
(xor & (mask & startmask));
dst++;
RotBitsLeft (bits, PGSZB);
}
while (nlw--)
{
WriteBitGroup (dst,xor,GetBitGroup(bits))
dst++;
RotBitsLeft (bits, PGSZB);
}
if (endmask)
{
mask = cfb8PixelMasks[GetBitGroup(bits)];
*dst = (*dst & ~(mask & endmask)) |
(xor & (mask & endmask));
}
}
else
{
wEnd = 7 - (nlw & 7);
nlw = (nlw >> 3) + 1;
dstTmp = dst;
nlwTmp = nlw;
if (startmask)
{
mask = cfb8PixelMasks[GetBitGroup(bits)];
*dstTmp = (*dstTmp & ~(mask & startmask)) |
(xor & (mask & startmask));
dstTmp++;
RotBitsLeft (bits, PGSZB);
}
w = 7 - wEnd;
while (w--)
{
dst = dstTmp;
dstTmp++;
nlw = nlwTmp;
#if defined(__GNUC__) && defined(mc68020)
mask = cfb8PixelMasks[GetBitGroup(bits)];
xor = xor & mask;
mask = ~mask;
while (nlw--)
{
*dst = (*dst & mask) | xor;
dst += 8;
}
xor = devPriv->xor;
#else
#define SwitchBitsLoop(body) \
while (nlw--) \
{ \
body \
dst += 8; \
}
SwitchBitGroup(dst, xor, GetBitGroup(bits));
#undef SwitchBitsLoop
#endif
NextBitGroup (bits);
}
nlwTmp--;
w = wEnd + 1;
if (endmask)
{
mask = cfb8PixelMasks[GetBitGroup(bits)];
dst = dstTmp + (nlwTmp << 3);
*dst = (*dst & ~(mask & endmask)) |
(xor & (mask & endmask));
}
while (w--)
{
nlw = nlwTmp;
dst = dstTmp;
dstTmp++;
#if defined(__GNUC__) && defined(mc68020)
mask = cfb8PixelMasks[GetBitGroup(bits)];
xor = xor & mask;
mask = ~mask;
while (nlw--)
{
*dst = (*dst & mask) | xor;
dst += 8;
}
xor = devPriv->xor;
#else
#define SwitchBitsLoop(body) \
while (nlw--) \
{ \
body \
dst += 8; \
}
SwitchBitGroup(dst, xor, GetBitGroup(bits));
#undef SwitchBitsLoop
#endif
NextBitGroup (bits);
}
}
}
else
#endif
{
if (startmask)
{
xor = GetBitGroup(bits);
*dst = MaskRRopPixels(*dst, xor, startmask);
dst++;
RotBitsLeft (bits, PGSZB);
}
while (nlw--)
{
RRopBitGroup(dst, GetBitGroup(bits));
dst++;
RotBitsLeft (bits, PGSZB);
}
if (endmask)
{
xor = GetBitGroup(bits);
*dst = MaskRRopPixels(*dst, xor, endmask);
}
}
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
void
cfb8OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GCPtr pGC;
int nInit;
DDXPointPtr pptInit;
int *pwidthInit;
int fSorted;
{
int n;
DDXPointPtr ppt;
int *pwidth;
CfbBits *src;
int stippleHeight;
PixmapPtr stipple;
int nlwDst;
int x,y,w;
CfbBits startmask;
CfbBits endmask;
register CfbBits *dst;
register int nlw;
CfbBits *dstTmp;
int nlwTmp;
CfbBits *pbits;
register CfbBits xor;
register CfbBits bits;
int wEnd;
int *pwidthFree;
DDXPointPtr pptFree;
cfbPrivGCPtr devPriv;
devPriv = cfbGetGCPrivate(pGC);
cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
n = nInit * miFindMaxBand(pGC->pCompositeClip);
if ( n == 0 )
return;
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);
stipple = pGC->pRotatedPixmap;
src = (CfbBits *)stipple->devPrivate.ptr;
stippleHeight = stipple->drawable.height;
cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
while (n--)
{
w = *pwidth++;
x = ppt->x;
y = ppt->y;
ppt++;
dst = pbits + (y * nlwDst) + (x >> PWSH);
if (((x & PIM) + w) <= PPW)
{
maskpartialbits(x, w, startmask);
endmask = 0;
nlw = 0;
}
else
{
maskbits (x, w, startmask, endmask, nlw);
}
bits = src[y % stippleHeight];
RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
#if PPW == 4
if (cfb8StippleRRop == GXcopy)
{
xor = devPriv->xor;
if (w < PGSZ*2)
{
if (startmask)
{
*dst = (*dst & ~startmask) |
(GetPixelGroup (bits) & startmask);
dst++;
RotBitsLeft (bits, PGSZB);
}
while (nlw--)
{
*dst++ = GetPixelGroup(bits);
RotBitsLeft (bits, PGSZB);
}
if (endmask)
{
*dst = (*dst & ~endmask) |
(GetPixelGroup (bits) & endmask);
}
}
else
{
wEnd = 7 - (nlw & 7);
nlw = (nlw >> 3) + 1;
dstTmp = dst;
nlwTmp = nlw;
if (startmask)
{
*dstTmp = (*dstTmp & ~startmask) |
(GetPixelGroup (bits) & startmask);
dstTmp++;
RotBitsLeft (bits, PGSZB);
}
w = 7 - wEnd;
while (w--)
{
nlw = nlwTmp;
dst = dstTmp;
dstTmp++;
xor = GetPixelGroup (bits);
while (nlw--)
{
*dst = xor;
dst += 8;
}
NextBitGroup (bits);
}
nlwTmp--;
w = wEnd + 1;
if (endmask)
{
dst = dstTmp + (nlwTmp << 3);
*dst = (*dst & ~endmask) |
(GetPixelGroup (bits) & endmask);
}
while (w--)
{
nlw = nlwTmp;
dst = dstTmp;
dstTmp++;
xor = GetPixelGroup (bits);
while (nlw--)
{
*dst = xor;
dst += 8;
}
NextBitGroup (bits);
}
}
}
else
#endif
{
if (startmask)
{
xor = GetBitGroup(bits);
*dst = MaskRRopPixels(*dst, xor, startmask);
dst++;
RotBitsLeft (bits, PGSZB);
}
while (nlw--)
{
RRopBitGroup(dst, GetBitGroup(bits));
dst++;
RotBitsLeft (bits, PGSZB);
}
if (endmask)
{
xor = GetBitGroup(bits);
*dst = MaskRRopPixels(*dst, xor, endmask);
}
}
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
#endif