/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c,v 1.11 2001/10/28 03:34:04 tsi Exp $ */ #include "xaa.h" #include "xaalocal.h" #include "xaacexp.h" #include "xf86.h" #include "xf86_ansic.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) #else #define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc) #endif StippleScanlineProcPtr stipple_scanline_func[6] = { StipplePowerOfTwo, StippleUpTo32, StippleOver32, StipplePowerOfTwo_Inverted, StippleUpTo32_Inverted, StippleOver32_Inverted }; #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; }