aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/xaa/xaaStipple.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/xaa/xaaStipple.c')
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaStipple.c866
1 files changed, 866 insertions, 0 deletions
diff --git a/xorg-server/hw/xfree86/xaa/xaaStipple.c b/xorg-server/hw/xfree86/xaa/xaaStipple.c
new file mode 100644
index 000000000..0dd8e9fcf
--- /dev/null
+++ b/xorg-server/hw/xfree86/xaa/xaaStipple.c
@@ -0,0 +1,866 @@
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+
+static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
+static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);
+
+#ifdef TRIPLE_BITS
+#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
+#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc3)
+#else
+#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
+#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc)
+#endif
+
+StippleScanlineProcPtr stipple_scanline_func[6] = {
+ StipplePowerOfTwo,
+ StippleUpTo32,
+ StippleOver32,
+ StipplePowerOfTwo_Inverted,
+ StippleUpTo32_Inverted,
+ StippleOver32_Inverted
+};
+
+StippleScanlineProcPtr *stipple_get_scanline_func(void) {
+ return stipple_scanline_func;
+}
+
+#ifdef FIXEDBASE
+# define DEST(i) *dest
+# define RETURN(i) return(dest)
+#else
+# define DEST(i) dest[i]
+# define RETURN(i) return(dest + i)
+#endif
+
+
+/* TRIPLE_BITS pattern expansion */
+#ifdef TRIPLE_BITS
+#define EXPAND_PAT \
+ CARD32 pat1 = byte_expand3[pat & 0xFF], \
+ pat2 = byte_expand3[(pat & 0xFF00) >> 8], \
+ pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \
+ pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \
+ patA = pat1 | (pat2 << 24), \
+ patB = (pat2 >> 8) | (pat3 << 16), \
+ patC = (pat3 >> 16) | (pat4 << 8)
+#ifdef FIXED_BASE
+#define WRITE_PAT1 { \
+ *dest = patA; }
+#define WRITE_PAT2 { \
+ *dest = patA; \
+ *dest = patB; }
+#define WRITE_PAT3 { \
+ *dest = patA; \
+ *dest = patB; \
+ *dest = patC; }
+#else
+#define WRITE_PAT1 { \
+ *(dest++) = patA; }
+#define WRITE_PAT2 { \
+ *(dest) = patA; \
+ *(dest + 1) = patB; \
+ dest += 2; }
+#define WRITE_PAT3 { \
+ *(dest) = patA; \
+ *(dest + 1) = patB; \
+ *(dest + 2) = patC; \
+ dest += 3; }
+#endif
+#endif
+
+
+#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS)
+
+unsigned int XAAShiftMasks[32] = {
+ /* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */
+ 0x00000000 , SHIFT_R(0xFFFFFFFF,31),
+ SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29),
+ SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27),
+ SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25),
+ SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23),
+ SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21),
+ SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19),
+ SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17),
+ SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15),
+ SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13),
+ SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11),
+ SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9),
+ SHIFT_R(0xFFFFFFFF,8), SHIFT_R(0xFFFFFFFF,7),
+ SHIFT_R(0xFFFFFFFF,6), SHIFT_R(0xFFFFFFFF,5),
+ SHIFT_R(0xFFFFFFFF,4), SHIFT_R(0xFFFFFFFF,3),
+ SHIFT_R(0xFFFFFFFF,2), SHIFT_R(0xFFFFFFFF,1)
+};
+
+#endif
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillColorExpandRects3)(
+#else
+EXPNAME(XAAFillColorExpandRects)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int srcwidth = pPix->devKind;
+ int dwords, srcy, srcx, funcNo = 2, h;
+ unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
+ unsigned char *srcp;
+ int flag;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidRects) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(nBox--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
+#else
+ dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
+#endif
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ h = pBox->y2 - pBox->y1;
+ flag = (infoRec->CPUToScreenColorExpandFillFlags
+ & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ srcy = (pBox->y1 - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (pBox->x1 - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (srcwidth * srcy) + src;
+
+#ifndef FIXEDBASE
+ if((dwords * h) <= infoRec->ColorExpandRange) {
+ while(h--) {
+ base = (*StippleFunc)(
+ base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+ } else
+#endif
+ while(h--) {
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+
+ if (flag) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ pBox++;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillColorExpandSpans3)(
+#else
+EXPNAME(XAAFillColorExpandSpans)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int dwords, srcy, srcx, funcNo = 2;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidSpans)(
+ pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(n--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * *pwidth + 31) >> 5;
+#else
+ dwords = (*pwidth + 31) >> 5;
+#endif
+
+ srcy = (ppt->y - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (ppt->x - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
+ *pwidth, 1, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+
+ if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD)
+ && (dwords & 0x01)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+#ifndef FIXEDBASE
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillScanlineColorExpandRects3)(
+#else
+EXPNAME(XAAFillScanlineColorExpandRects)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int srcwidth = pPix->devKind;
+ int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
+ unsigned char *src = pPix->devPrivate.ptr;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidRects) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(nBox--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
+#else
+ dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
+#endif
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ h = pBox->y2 - pBox->y1;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);
+
+ bufferNo = 0;
+
+ srcy = (pBox->y1 - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (pBox->x1 - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (srcwidth * srcy) + src;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillScanlineColorExpandSpans3)(
+#else
+EXPNAME(XAAFillScanlineColorExpandSpans)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int dwords, srcy, srcx, funcNo = 2;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidSpans)(
+ pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+
+ while(n--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * *pwidth + 31) >> 5;
+#else
+ dwords = (*pwidth + 31) >> 5;
+#endif
+
+ srcy = (ppt->y - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (ppt->x - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, ppt->x, ppt->y, *pwidth, 1, 0);
+
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
+
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ ppt++; pwidth++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+static CARD32 *
+StipplePowerOfTwo(
+ CARD32* dest, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src;
+ if(width < 32) {
+ pat &= XAAShiftMasks[width];
+ while(width < 32) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ }
+
+ if(shift)
+ pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
+
+#ifdef MSBFIRST
+ pat = SWAP_BITS_IN_BYTES(pat);
+#endif
+
+#ifdef TRIPLE_BITS
+ {
+ EXPAND_PAT;
+
+ while(dwords >= 3) {
+ WRITE_PAT3;
+ dwords -= 3;
+ }
+ if (dwords == 2) {
+ WRITE_PAT2;
+ } else if (dwords == 1) {
+ WRITE_PAT1;
+ }
+
+ return dest;
+ }
+#else /* TRIPLE_BITS */
+ while(dwords >= 4) {
+ DEST(0) = pat;
+ DEST(1) = pat;
+ DEST(2) = pat;
+ DEST(3) = pat;
+ dwords -= 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!dwords) return dest;
+ DEST(0) = pat;
+ if(dwords == 1) RETURN(1);
+ DEST(1) = pat;
+ if(dwords == 2) RETURN(2);
+ DEST(2) = pat;
+ RETURN(3);
+#endif /* TRIPLE_BITS */
+}
+
+static CARD32 *
+StipplePowerOfTwo_Inverted(
+ CARD32* dest, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src;
+ if(width < 32) {
+ pat &= XAAShiftMasks[width];
+ while(width < 32) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ }
+
+ if(shift)
+ pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
+
+#ifdef MSBFIRST
+ pat = SWAP_BITS_IN_BYTES(pat);
+#endif
+
+ pat = ~pat;
+
+#ifdef TRIPLE_BITS
+ {
+ EXPAND_PAT;
+
+ while(dwords >= 3) {
+ WRITE_PAT3;
+ dwords -= 3;
+ }
+ if (dwords == 2) {
+ WRITE_PAT2;
+ } else if (dwords == 1) {
+ WRITE_PAT1;
+ }
+
+ return dest;
+ }
+#else /* TRIPLE_BITS */
+ while(dwords >= 4) {
+ DEST(0) = pat;
+ DEST(1) = pat;
+ DEST(2) = pat;
+ DEST(3) = pat;
+ dwords -= 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!dwords) return dest;
+ DEST(0) = pat;
+ if(dwords == 1) RETURN(1);
+ DEST(1) = pat;
+ if(dwords == 2) RETURN(2);
+ DEST(2) = pat;
+ RETURN(3);
+#endif /* TRIPLE_BITS */
+}
+
+
+static CARD32 *
+StippleUpTo32(
+ CARD32* base, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src & XAAShiftMasks[width];
+
+ while(width <= 15) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ pat |= SHIFT_L(pat,width);
+
+ while(dwords--) {
+ CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift);
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ shift += 32;
+ shift %= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleUpTo32_Inverted(
+ CARD32* base, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src & XAAShiftMasks[width];
+
+ while(width <= 15) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ pat |= SHIFT_L(pat,width);
+
+ while(dwords--) {
+ CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift));
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ shift += 32;
+ shift %= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleOver32(
+ CARD32* base, CARD32* src,
+ int offset, int width, int dwords
+){
+ CARD32* srcp;
+ CARD32 bits;
+ int bitsleft, shift, usable;
+
+ while(dwords--) {
+ bitsleft = width - offset;
+ srcp = src + (offset >> 5);
+ shift = offset & 31;
+ usable = 32 - shift;
+
+ if(bitsleft < 32) {
+ if(bitsleft <= usable) {
+ bits = SHIFT_L(*src,bitsleft) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
+ } else {
+ bits = SHIFT_L(*src,bitsleft) |
+ (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
+ }
+ }
+ else if(shift)
+ bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
+ else
+ bits = *srcp;
+
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ offset += 32;
+ offset %= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleOver32_Inverted(
+ CARD32* base, CARD32* src,
+ int offset, int width, int dwords
+){
+ CARD32* srcp;
+ CARD32 bits;
+ int bitsleft, shift, usable;
+
+ while(dwords--) {
+ bitsleft = width - offset;
+ srcp = src + (offset >> 5);
+ shift = offset & 31;
+ usable = 32 - shift;
+
+ if(bitsleft < 32) {
+ if(bitsleft <= usable) {
+ bits = SHIFT_L(*src,bitsleft) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
+ } else {
+ bits = SHIFT_L(*src,bitsleft) |
+ (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
+ }
+ }
+ else if(shift)
+ bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
+ else
+ bits = *srcp;
+
+ bits = ~bits;
+
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ offset += 32;
+ offset %= width;
+ }
+ return base;
+}