487 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			487 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
| 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
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include <string.h>
 | |
| #include <X11/X.h>
 | |
| #include <X11/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(
 | |
|     DrawablePtr pSrcDrawable,
 | |
|     DrawablePtr pDstDrawable,
 | |
|     int	rop,
 | |
|     RegionPtr prgnDst,
 | |
|     DDXPointPtr pptSrc,
 | |
|     unsigned long planemask)
 | |
| {
 | |
|     /* note: there must be some sort of trick behind,
 | |
|        passing a planemask value with all bits set
 | |
|        whilst using the current planemask for the bitPlane value. */
 | |
| #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(
 | |
|     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 = mfbGetstarttab((x)&0x1f); \
 | |
|     endmask = mfbGetendtab(((x)+(w)) & 0x1f); \
 | |
|     if (startmask) \
 | |
| 	nlw = (((w) - (32 - ((x)&0x1f))) >> 5); \
 | |
|     else \
 | |
| 	nlw = (w) >> 5;
 | |
| 
 | |
| #define mfbmaskpartialbits(x, w, mask) \
 | |
|     mask = mfbGetpartmasks((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
 | |
| #endif
 | |
| #if PSZ == 24
 | |
| cfbCopyPlane24to1
 | |
| #endif
 | |
| #if PSZ == 32
 | |
| cfbCopyPlane32to1
 | |
| #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 = 0, endmask = 0;
 | |
|     int			    niStart = 0, niEnd = 0;
 | |
|     int			    bitStart = 0, bitEnd = 0;
 | |
|     int			    nl, nlMiddle;
 | |
|     int			    nbox;
 | |
|     BoxPtr		    pbox;
 | |
|     int result;
 | |
| 
 | |
| 
 | |
|     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 */
 |