diff options
Diffstat (limited to 'cfb/cfbcppl.c')
-rw-r--r-- | cfb/cfbcppl.c | 486 |
1 files changed, 486 insertions, 0 deletions
diff --git a/cfb/cfbcppl.c b/cfb/cfbcppl.c new file mode 100644 index 000000000..20ef24e1c --- /dev/null +++ b/cfb/cfbcppl.c @@ -0,0 +1,486 @@ +/* + * $TOG: cfb8cppl.c /main/16 1998/02/09 14:04:13 kaleb $ + * +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author: Keith Packard, MIT X Consortium + */ +/* $XFree86: xc/programs/Xserver/cfb/cfbcppl.c,v 1.6 2001/12/14 19:59:22 dawes Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "cfb.h" +#if PSZ == 8 +#undef PSZ /* for maskbits.h */ +#include "maskbits.h" +#define PSZ 8 +#include "mergerop.h" +#endif + + +void +cfbCopyImagePlane (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask) + DrawablePtr pSrcDrawable; + DrawablePtr pDstDrawable; + int rop; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; +{ +#if PSZ == 8 + cfbCopyPlane8to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + (unsigned long) ~0L, planemask); +#endif +#if PSZ == 16 + cfbCopyPlane16to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + (unsigned long) ~0L, planemask); +#endif +#if PSZ == 24 + cfbCopyPlane24to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + (unsigned long) ~0L, planemask); +#endif +#if PSZ == 32 + cfbCopyPlane32to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + (unsigned long) ~0L, planemask); +#endif +} + +#if PSZ == 8 + +#if BITMAP_BIT_ORDER == MSBFirst +#define LeftMost (MFB_PPW-1) +#define StepBit(bit, inc) ((bit) -= (inc)) +#else +#define LeftMost 0 +#define StepBit(bit, inc) ((bit) += (inc)) +#endif + +#define GetBits(psrc, nBits, curBit, bitPos, bits) {\ + bits = 0; \ + while (nBits--) \ + { \ + bits |= (PixelType)(((*psrc++ >> bitPos) & 1)) << curBit; \ + StepBit (curBit, 1); \ + } \ +} + +void +cfbCopyPlane8to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask, bitPlane) + DrawablePtr pSrcDrawable; + DrawablePtr pDstDrawable; + int rop; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; + unsigned long bitPlane; +{ + int srcx, srcy, dstx, dsty, width, height; + unsigned char *psrcBase; + PixelType *pdstBase; + int widthSrc, widthDst; + unsigned char *psrcLine; + PixelType *pdstLine; + register unsigned char *psrc; + register int i; + register int curBit; + register int bitPos; + register CfbBits bits; + register PixelType *pdst; + PixelType startmask, endmask; + int niStart = 0, niEnd = 0; + int bitStart = 0, bitEnd = 0; + int nl, nlMiddle; + int nbox; + BoxPtr pbox; + MROP_DECLARE() + + if (!(planemask & 1)) + return; + + if (rop != GXcopy) + MROP_INITIALIZE (rop, planemask); + + cfbGetByteWidthAndPointer (pSrcDrawable, widthSrc, psrcBase) + + mfbGetPixelWidthAndPointer (pDstDrawable, widthDst, pdstBase) + + bitPos = ffs (bitPlane) - 1; + + nbox = REGION_NUM_RECTS(prgnDst); + pbox = REGION_RECTS(prgnDst); + while (nbox--) + { + dstx = pbox->x1; + dsty = pbox->y1; + srcx = pptSrc->x; + srcy = pptSrc->y; + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + pbox++; + pptSrc++; + psrcLine = psrcBase + srcy * widthSrc + srcx; + pdstLine = mfbScanline(pdstBase, dstx, dsty, widthDst); + dstx &= MFB_PIM; + if (dstx + width <= MFB_PPW) + { + maskpartialbits(dstx, width, startmask); + nlMiddle = 0; + endmask = 0; + } + else + { + maskbits (dstx, width, startmask, endmask, nlMiddle); + } + if (startmask) + { + niStart = min(MFB_PPW - dstx, width); + bitStart = LeftMost; + StepBit (bitStart, dstx); + } + if (endmask) + { + niEnd = (dstx + width) & MFB_PIM; + bitEnd = LeftMost; + } + if (rop == GXcopy) + { + while (height--) + { + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + mfbScanlineInc(pdstLine, widthDst); + if (startmask) + { + i = niStart; + curBit = bitStart; + GetBits (psrc, i, curBit, bitPos, bits); + *pdst = (*pdst & ~startmask) | bits; + pdst++; + } + nl = nlMiddle; + while (nl--) + { + i = MFB_PPW; + curBit = LeftMost; + GetBits (psrc, i, curBit, bitPos, bits); + *pdst++ = bits; + } + if (endmask) + { + i = niEnd; + curBit = bitEnd; + GetBits (psrc, i, curBit, bitPos, bits); + *pdst = (*pdst & ~endmask) | bits; + } + } + } + else + { + while (height--) + { + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + mfbScanlineInc(pdstLine, widthDst); + if (startmask) + { + i = niStart; + curBit = bitStart; + GetBits (psrc, i, curBit, bitPos, bits); + *pdst = MROP_MASK(bits, *pdst, startmask); + pdst++; + } + nl = nlMiddle; + while (nl--) + { + i = MFB_PPW; + curBit = LeftMost; + GetBits (psrc, i, curBit, bitPos, bits); + *pdst = MROP_SOLID(bits, *pdst); + pdst++; + } + if (endmask) + { + i = niEnd; + curBit = bitEnd; + GetBits (psrc, i, curBit, bitPos, bits); + *pdst = MROP_MASK (bits, *pdst, endmask); + } + } + } + } +} + +#else /* PSZ == 8 */ + +#define mfbmaskbits(x, w, startmask, endmask, nlw) \ + startmask = starttab[(x)&0x1f]; \ + endmask = endtab[((x)+(w)) & 0x1f]; \ + if (startmask) \ + nlw = (((w) - (32 - ((x)&0x1f))) >> 5); \ + else \ + nlw = (w) >> 5; + +#define mfbmaskpartialbits(x, w, mask) \ + mask = partmasks[(x)&0x1f][(w)&0x1f]; + +#define LeftMost 0 +#define StepBit(bit, inc) ((bit) += (inc)) + + +#if PSZ == 24 +#define GetBits(psrc, nBits, curBit, bitPos, bits) {\ + bits = 0; \ + while (nBits--) \ + { \ + if (bitPos < 8) \ + { \ + bits |= ((*psrc++ >> bitPos) & 1) << curBit; \ + psrc += 2; \ + } \ + else if (bitPos < 16) \ + { \ + psrc++; \ + bits |= ((*psrc++ >> (bitPos - 8)) & 1) << curBit; \ + psrc++; \ + } \ + else \ + { \ + psrc += 2; \ + bits |= ((*psrc++ >> (bitPos - 16)) & 1) << curBit; \ + } \ + StepBit (curBit, 1); \ + } \ +} +#else +#define GetBits(psrc, nBits, curBit, bitPos, bits) {\ + bits = 0; \ + while (nBits--) \ + { \ + bits |= ((*psrc++ >> bitPos) & 1) << curBit; \ + StepBit (curBit, 1); \ + } \ +} +#endif + +void +#if PSZ == 16 +cfbCopyPlane16to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + planemask, bitPlane) +#endif +#if PSZ == 24 +cfbCopyPlane24to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + planemask, bitPlane) +#endif +#if PSZ == 32 +cfbCopyPlane32to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, + planemask, bitPlane) +#endif + DrawablePtr pSrcDrawable; + DrawablePtr pDstDrawable; + int rop; + RegionPtr prgnDst; + DDXPointPtr pptSrc; + unsigned long planemask; + unsigned long bitPlane; +{ + int srcx, srcy, dstx, dsty, width, height; + CfbBits *psrcBase; + CfbBits *pdstBase; + int widthSrc, widthDst; +#if PSZ == 16 + unsigned short *psrcLine; + register unsigned short *psrc; +#endif +#if PSZ == 24 + unsigned char *psrcLine; + register unsigned char *psrc; +#endif +#if PSZ == 32 + unsigned int *psrcLine; + register unsigned int *psrc; +#endif + unsigned int *pdstLine; + register unsigned int *pdst; + register int i; + register int curBit; + register int bitPos; + register unsigned int bits; + unsigned int startmask, endmask; + int niStart = 0, niEnd = 0; + int bitStart = 0, bitEnd = 0; + int nl, nlMiddle; + int nbox; + BoxPtr pbox; + int result; + + extern int starttab[32], endtab[32]; + extern unsigned int partmasks[32][32]; + + + if (!(planemask & 1)) + return; + + /* must explicitly ask for "int" widths, as code below expects it */ + /* on some machines (Alpha), "long" and "int" are not the same size */ + cfbGetTypedWidthAndPointer (pSrcDrawable, widthSrc, psrcBase, int, CfbBits) + cfbGetTypedWidthAndPointer (pDstDrawable, widthDst, pdstBase, int, CfbBits) + +#if PSZ == 16 + widthSrc <<= 1; +#endif +#if PSZ == 24 + widthSrc <<= 2; +#endif + + bitPos = ffs (bitPlane) - 1; + + nbox = REGION_NUM_RECTS(prgnDst); + pbox = REGION_RECTS(prgnDst); + while (nbox--) + { + dstx = pbox->x1; + dsty = pbox->y1; + srcx = pptSrc->x; + srcy = pptSrc->y; + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + pbox++; + pptSrc++; +#if PSZ == 16 + psrcLine = (unsigned short *)psrcBase + srcy * widthSrc + srcx; +#endif +#if PSZ == 24 + psrcLine = (unsigned char *)psrcBase + srcy * widthSrc + srcx * 3; +#endif +#if PSZ == 32 + psrcLine = (unsigned int *)psrcBase + srcy * widthSrc + srcx; +#endif + pdstLine = (unsigned int *)pdstBase + dsty * widthDst + (dstx >> 5); + if (dstx + width <= 32) + { + mfbmaskpartialbits(dstx, width, startmask); + nlMiddle = 0; + endmask = 0; + } + else + { + mfbmaskbits (dstx, width, startmask, endmask, nlMiddle); + } + if (startmask) + { + niStart = 32 - (dstx & 0x1f); + bitStart = LeftMost; + StepBit (bitStart, (dstx & 0x1f)); + } + if (endmask) + { + niEnd = (dstx + width) & 0x1f; + bitEnd = LeftMost; + } + if (rop == GXcopy) + { + while (height--) + { + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + pdstLine += widthDst; + if (startmask) + { + i = niStart; + curBit = bitStart; + GetBits (psrc, i, curBit, bitPos, bits); + + *pdst = (*pdst & ~startmask) | bits; + pdst++; + } + nl = nlMiddle; + while (nl--) + { + i = 32; + curBit = LeftMost; + GetBits (psrc, i, curBit, bitPos, bits); + *pdst++ = bits; + } + if (endmask) + { + i = niEnd; + curBit = bitEnd; + GetBits (psrc, i, curBit, bitPos, bits); + + *pdst = (*pdst & ~endmask) | bits; + } + } + } + else + { + while (height--) + { + psrc = psrcLine; + pdst = pdstLine; + psrcLine += widthSrc; + pdstLine += widthDst; + if (startmask) + { + i = niStart; + curBit = bitStart; + GetBits (psrc, i, curBit, bitPos, bits); + DoRop (result, rop, bits, *pdst); + + *pdst = (*pdst & ~startmask) | + (result & startmask); + pdst++; + } + nl = nlMiddle; + while (nl--) + { + i = 32; + curBit = LeftMost; + GetBits (psrc, i, curBit, bitPos, bits); + DoRop (result, rop, bits, *pdst); + *pdst = result; + ++pdst; + } + if (endmask) + { + i = niEnd; + curBit = bitEnd; + GetBits (psrc, i, curBit, bitPos, bits); + DoRop (result, rop, bits, *pdst); + + *pdst = (*pdst & ~endmask) | + (result & endmask); + } + } + } + } +} + +#endif /* PSZ == 8 */ |