#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdlib.h>
#include <X11/X.h>
#include <X11/Xmd.h>
#include <X11/Xproto.h>
#include "gcstruct.h"
#include "windowstr.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "regionstr.h"
#include "mi.h"
#include "cfb.h"
#include "cfbmskbits.h"
#include "cfb8bit.h"
#include "fastblt.h"
#define MFB_CONSTS_ONLY
#include "maskbits.h"
#if PSZ == 8
#define cfbCopyPlane1toN cfbCopyPlane1to8
#define cfbCopyPlaneNto1 cfbCopyPlane8to1
#else
static unsigned int FgPixel, BgPixel;
# if PSZ == 16
#define cfbCopyPlane1toN cfbCopyPlane1to16
#define cfbCopyPlaneNto1 cfbCopyPlane16to1
# endif
# if PSZ == 24
#define cfbCopyPlane1toN cfbCopyPlane1to24
#define cfbCopyPlaneNto1 cfbCopyPlane24to1
# endif
# if PSZ == 32
#define cfbCopyPlane1toN cfbCopyPlane1to32
#define cfbCopyPlaneNto1 cfbCopyPlane32to1
# endif
#endif
RegionPtr
cfbBitBlt (
register DrawablePtr pSrcDrawable,
register DrawablePtr pDstDrawable,
GC *pGC,
int srcx, int srcy,
int width, int height,
int dstx, int dsty,
void (*doBitBlt)(
DrawablePtr ,
DrawablePtr ,
int ,
RegionPtr ,
DDXPointPtr ,
unsigned long ),
unsigned long bitPlane)
{
RegionPtr prgnSrcClip = NULL;
Bool freeSrcClip = FALSE;
RegionPtr prgnExposed;
RegionRec rgnDst;
DDXPointPtr pptSrc;
register DDXPointPtr ppt;
register BoxPtr pbox;
int i;
register int dx;
register int dy;
xRectangle origSource;
DDXPointRec origDest;
int numRects;
BoxRec fastBox;
int fastClip = 0;
int fastExpose = 0;
origSource.x = srcx;
origSource.y = srcy;
origSource.width = width;
origSource.height = height;
origDest.x = dstx;
origDest.y = dsty;
if ((pSrcDrawable != pDstDrawable) &&
pSrcDrawable->pScreen->SourceValidate)
{
(*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
}
srcx += pSrcDrawable->x;
srcy += pSrcDrawable->y;
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
{
if ((pSrcDrawable == pDstDrawable) &&
(pGC->clientClipType == CT_NONE))
{
prgnSrcClip = cfbGetCompositeClip(pGC);
}
else
{
fastClip = 1;
}
}
else
{
if (pGC->subWindowMode == IncludeInferiors)
{
if (!((WindowPtr) pSrcDrawable)->parent &&
REGION_NOTEMPTY (pSrcDrawable->pScreen,
&((WindowPtr) pSrcDrawable)->borderClip))
{
fastClip = 1;
}
else if ((pSrcDrawable == pDstDrawable) &&
(pGC->clientClipType == CT_NONE))
{
prgnSrcClip = cfbGetCompositeClip(pGC);
}
else
{
prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
freeSrcClip = TRUE;
}
}
else
{
prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
}
}
fastBox.x1 = srcx;
fastBox.y1 = srcy;
fastBox.x2 = srcx + width;
fastBox.y2 = srcy + height;
if (fastClip)
{
fastExpose = 1;
if (fastBox.x1 < pSrcDrawable->x)
{
fastBox.x1 = pSrcDrawable->x;
fastExpose = 0;
}
if (fastBox.y1 < pSrcDrawable->y)
{
fastBox.y1 = pSrcDrawable->y;
fastExpose = 0;
}
if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
{
fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
fastExpose = 0;
}
if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
{
fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
fastExpose = 0;
}
}
else
{
REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
}
dstx += pDstDrawable->x;
dsty += pDstDrawable->y;
if (pDstDrawable->type == DRAWABLE_WINDOW)
{
if (!((WindowPtr)pDstDrawable)->realized)
{
if (!fastClip)
REGION_UNINIT(pGC->pScreen, &rgnDst);
if (freeSrcClip)
REGION_DESTROY(pGC->pScreen, prgnSrcClip);
return NULL;
}
}
dx = srcx - dstx;
dy = srcy - dsty;
if (fastClip)
{
RegionPtr cclip;
fastBox.x1 -= dx;
fastBox.x2 -= dx;
fastBox.y1 -= dy;
fastBox.y2 -= dy;
cclip = cfbGetCompositeClip(pGC);
if (REGION_NUM_RECTS(cclip) == 1)
{
BoxPtr pBox = REGION_RECTS(cclip);
if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
{
REGION_NULL(pGC->pScreen, &rgnDst);
}
else
{
REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
}
}
else
{
fastClip = 0;
REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
}
}
else
{
REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
}
if (!fastClip)
{
REGION_INTERSECT(pGC->pScreen, &rgnDst,
&rgnDst,
cfbGetCompositeClip(pGC));
}
numRects = REGION_NUM_RECTS(&rgnDst);
if (numRects && width && height)
{
if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
sizeof(DDXPointRec))))
{
REGION_UNINIT(pGC->pScreen, &rgnDst);
if (freeSrcClip)
REGION_DESTROY(pGC->pScreen, prgnSrcClip);
return NULL;
}
pbox = REGION_RECTS(&rgnDst);
ppt = pptSrc;
for (i = numRects; --i >= 0; pbox++, ppt++)
{
ppt->x = pbox->x1 + dx;
ppt->y = pbox->y1 + dy;
}
(*doBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask);
DEALLOCATE_LOCAL(pptSrc);
}
prgnExposed = NULL;
if (pGC->fExpose)
{
if (!fastExpose)
prgnExposed =
miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
origSource.x, origSource.y,
(int)origSource.width,
(int)origSource.height,
origDest.x, origDest.y, bitPlane);
}
REGION_UNINIT(pGC->pScreen, &rgnDst);
if (freeSrcClip)
REGION_DESTROY(pGC->pScreen, prgnSrcClip);
return prgnExposed;
}
RegionPtr
cfbCopyPlaneReduce (
register DrawablePtr pSrcDrawable,
register DrawablePtr pDstDrawable,
GC *pGC,
int srcx, int srcy,
int width, int height,
int dstx, int dsty,
void (*doCopyPlane)(
DrawablePtr ,
DrawablePtr ,
int ,
RegionPtr ,
DDXPointPtr ,
unsigned long ,
unsigned long ),
unsigned long bitPlane)
{
RegionPtr prgnSrcClip = NULL;
Bool freeSrcClip = FALSE;
RegionPtr prgnExposed;
RegionRec rgnDst;
DDXPointPtr pptSrc;
register DDXPointPtr ppt;
register BoxPtr pbox;
int i;
register int dx;
register int dy;
xRectangle origSource;
DDXPointRec origDest;
int numRects;
BoxRec fastBox;
int fastClip = 0;
int fastExpose = 0;
origSource.x = srcx;
origSource.y = srcy;
origSource.width = width;
origSource.height = height;
origDest.x = dstx;
origDest.y = dsty;
if ((pSrcDrawable != pDstDrawable) &&
pSrcDrawable->pScreen->SourceValidate)
{
(*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
}
srcx += pSrcDrawable->x;
srcy += pSrcDrawable->y;
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
{
if ((pSrcDrawable == pDstDrawable) &&
(pGC->clientClipType == CT_NONE))
{
prgnSrcClip = cfbGetCompositeClip(pGC);
}
else
{
fastClip = 1;
}
}
else
{
if (pGC->subWindowMode == IncludeInferiors)
{
if (!((WindowPtr) pSrcDrawable)->parent &&
REGION_NOTEMPTY (pSrcDrawable->pScreen,
&((WindowPtr) pSrcDrawable)->borderClip))
{
fastClip = 1;
}
else if ((pSrcDrawable == pDstDrawable) &&
(pGC->clientClipType == CT_NONE))
{
prgnSrcClip = cfbGetCompositeClip(pGC);
}
else
{
prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
freeSrcClip = TRUE;
}
}
else
{
prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
}
}
fastBox.x1 = srcx;
fastBox.y1 = srcy;
fastBox.x2 = srcx + width;
fastBox.y2 = srcy + height;
if (fastClip)
{
fastExpose = 1;
if (fastBox.x1 < pSrcDrawable->x)
{
fastBox.x1 = pSrcDrawable->x;
fastExpose = 0;
}
if (fastBox.y1 < pSrcDrawable->y)
{
fastBox.y1 = pSrcDrawable->y;
fastExpose = 0;
}
if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
{
fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
fastExpose = 0;
}
if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
{
fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
fastExpose = 0;
}
}
else
{
REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
}
dstx += pDstDrawable->x;
dsty += pDstDrawable->y;
if (pDstDrawable->type == DRAWABLE_WINDOW)
{
if (!((WindowPtr)pDstDrawable)->realized)
{
if (!fastClip)
REGION_UNINIT(pGC->pScreen, &rgnDst);
if (freeSrcClip)
REGION_DESTROY(pGC->pScreen, prgnSrcClip);
return NULL;
}
}
dx = srcx - dstx;
dy = srcy - dsty;
if (fastClip)
{
RegionPtr cclip;
fastBox.x1 -= dx;
fastBox.x2 -= dx;
fastBox.y1 -= dy;
fastBox.y2 -= dy;
cclip = cfbGetCompositeClip(pGC);
if (REGION_NUM_RECTS(cclip) == 1)
{
BoxPtr pBox = REGION_RECTS(cclip);
if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
{
REGION_NULL(pGC->pScreen, &rgnDst);
}
else
{
REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
}
}
else
{
fastClip = 0;
REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
}
}
else
{
REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
}
if (!fastClip)
{
REGION_INTERSECT(pGC->pScreen, &rgnDst,
&rgnDst,
cfbGetCompositeClip(pGC));
}
numRects = REGION_NUM_RECTS(&rgnDst);
if (numRects && width && height)
{
if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
sizeof(DDXPointRec))))
{
REGION_UNINIT(pGC->pScreen, &rgnDst);
if (freeSrcClip)
REGION_DESTROY(pGC->pScreen, prgnSrcClip);
return NULL;
}
pbox = REGION_RECTS(&rgnDst);
ppt = pptSrc;
for (i = numRects; --i >= 0; pbox++, ppt++)
{
ppt->x = pbox->x1 + dx;
ppt->y = pbox->y1 + dy;
}
(*doCopyPlane) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask, bitPlane);
DEALLOCATE_LOCAL(pptSrc);
}
prgnExposed = NULL;
if (pGC->fExpose)
{
if (!fastExpose)
prgnExposed =
miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
origSource.x, origSource.y,
(int)origSource.width,
(int)origSource.height,
origDest.x, origDest.y, bitPlane);
}
REGION_UNINIT(pGC->pScreen, &rgnDst);
if (freeSrcClip)
REGION_DESTROY(pGC->pScreen, prgnSrcClip);
return prgnExposed;
}
void
cfbDoBitblt (pSrc, pDst, alu, prgnDst, pptSrc, planemask)
DrawablePtr pSrc, pDst;
int alu;
RegionPtr prgnDst;
DDXPointPtr pptSrc;
unsigned long planemask;
{
void (*doBitBlt)(
DrawablePtr ,
DrawablePtr ,
int ,
RegionPtr ,
DDXPointPtr ,
unsigned long )
= cfbDoBitbltGeneral;
if ((planemask & PMSK) == PMSK) {
switch (alu) {
case GXcopy:
doBitBlt = cfbDoBitbltCopy;
break;
case GXxor:
doBitBlt = cfbDoBitbltXor;
break;
case GXor:
doBitBlt = cfbDoBitbltOr;
break;
}
}
(*doBitBlt) (pSrc, pDst, alu, prgnDst, pptSrc, planemask);
}
RegionPtr
cfbCopyArea(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty)
register DrawablePtr pSrcDrawable;
register DrawablePtr pDstDrawable;
GC *pGC;
int srcx, srcy;
int width, height;
int dstx, dsty;
{
void (*doBitBlt) (
DrawablePtr ,
DrawablePtr ,
int ,
RegionPtr ,
DDXPointPtr ,
unsigned long );
doBitBlt = cfbDoBitbltCopy;
if (pGC->alu != GXcopy || (pGC->planemask & PMSK) != PMSK)
{
doBitBlt = cfbDoBitbltGeneral;
if ((pGC->planemask & PMSK) == PMSK)
{
switch (pGC->alu) {
case GXxor:
doBitBlt = cfbDoBitbltXor;
break;
case GXor:
doBitBlt = cfbDoBitbltOr;
break;
}
}
}
return cfbBitBlt (pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, 0L);
}
#if PSZ == 8
void
cfbCopyPlane1to8 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask)
DrawablePtr pSrcDrawable;
DrawablePtr pDstDrawable;
int rop;
RegionPtr prgnDst;
DDXPointPtr pptSrc;
unsigned long planemask;
{
int srcx, srcy;
int dstx, dsty;
int width, height;
int xoffSrc;
int xoffDst;
CfbBits *psrcBase, *pdstBase;
int widthSrc;
int widthDst;
CfbBits *psrcLine, *pdstLine;
register CfbBits *psrc, *pdst;
register CfbBits bits, tmp;
register int leftShift;
register int rightShift;
CfbBits startmask;
CfbBits endmask;
register int nlMiddle;
register int nl;
int firstoff = 0;
int secondoff = 0;
CfbBits src;
int nbox;
BoxPtr pbox;
int pixelsRemainingOnRightEdge;
cfbGetLongWidthAndPointer (pSrcDrawable, widthSrc, psrcBase)
cfbGetLongWidthAndPointer (pDstDrawable, widthDst, pdstBase)
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 >> MFB_PWSH);
pdstLine = pdstBase + dsty * widthDst + (dstx >> PWSH);
xoffSrc = srcx & MFB_PIM;
xoffDst = dstx & PIM;
if (xoffDst + width < PPW)
{
maskpartialbits(dstx, width, startmask);
endmask = 0;
nlMiddle = 0;
}
else
{
maskbits(dstx, width, startmask, endmask, nlMiddle);
}
if (startmask)
{
firstoff = xoffSrc - xoffDst;
if (firstoff > (MFB_PPW-PPW))
secondoff = MFB_PPW - firstoff;
if (xoffDst)
{
srcx += (PPW-xoffDst);
xoffSrc = srcx & MFB_PIM;
}
}
leftShift = xoffSrc;
rightShift = MFB_PPW - leftShift;
pixelsRemainingOnRightEdge = (nlMiddle & 7) * PPW +
((dstx + width) & PIM);
if (cfb8StippleRRop == GXcopy)
{
while (height--)
{
psrc = psrcLine;
pdst = pdstLine;
psrcLine += widthSrc;
pdstLine += widthDst;
bits = *psrc++;
if (startmask)
{
if (firstoff < 0)
tmp = BitRight (bits, -firstoff);
else
{
tmp = BitLeft (bits, firstoff);
if (firstoff >= (MFB_PPW-PPW))
{
bits = *psrc++;
if (firstoff != (MFB_PPW-PPW))
tmp |= BitRight (bits, secondoff);
}
}
*pdst = (*pdst & ~startmask) | (GetPixelGroup(tmp) & startmask);
pdst++;
}
nl = nlMiddle;
while (nl >= 8)
{
nl -= 8;
tmp = BitLeft(bits, leftShift);
bits = *psrc++;
if (rightShift != MFB_PPW)
tmp |= BitRight(bits, rightShift);
#ifdef FAST_CONSTANT_OFFSET_MODE
# define StorePixels(pdst,o,pixels) (pdst)[o] = (pixels)
# define EndStep(pdst,o) (pdst) += (o)
# define StoreRopPixels(pdst,o,and,xor) (pdst)[o] = DoRRop((pdst)[o],and,xor);
#else
# define StorePixels(pdst,o,pixels) *(pdst)++ = (pixels)
# define EndStep(pdst,o)
# define StoreRopPixels(pdst,o,and,xor) *(pdst) = DoRRop(*(pdst),and,xor); (pdst)++;
#endif
#define Step(c) NextBitGroup(c);
#define StoreBitsPlain(o,c) StorePixels(pdst,o,GetPixelGroup(c))
#define StoreRopBitsPlain(o,c) StoreRopPixels(pdst,o,\
cfb8StippleAnd[GetBitGroup(c)], \
cfb8StippleXor[GetBitGroup(c)])
#define StoreBits0(c) StoreBitsPlain(0,c)
#define StoreRopBits0(c) StoreRopBitsPlain(0,c)
#if (BITMAP_BIT_ORDER == MSBFirst)
# define StoreBits(o,c) StoreBitsPlain(o,c)
# define StoreRopBits(o,c) StoreRopBitsPlain(o,c)
# define FirstStep(c) Step(c)
#else
#if PGSZ == 64
# define StoreBits(o,c) StorePixels(pdst,o, (cfb8Pixels[c & 0xff]))
# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \
(cfb8StippleAnd[c & 0xff]), \
(cfb8StippleXor[c & 0xff]))
# define FirstStep(c) c = BitLeft (c, 8);
#else
# define StoreBits(o,c) StorePixels(pdst,o,*((CfbBits *)\
(((char *) cfb8Pixels) + (c & 0x3c))))
# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \
*((CfbBits *) (((char *) cfb8StippleAnd) + (c & 0x3c))), \
*((CfbBits *) (((char *) cfb8StippleXor) + (c & 0x3c))))
# define FirstStep(c) c = BitLeft (c, 2);
#endif
#endif
StoreBits0(tmp); FirstStep(tmp);
StoreBits(1,tmp); Step(tmp);
StoreBits(2,tmp); Step(tmp);
StoreBits(3,tmp); Step(tmp);
StoreBits(4,tmp); Step(tmp);
StoreBits(5,tmp); Step(tmp);
StoreBits(6,tmp); Step(tmp);
StoreBits(7,tmp); EndStep (pdst,8);
}
if (pixelsRemainingOnRightEdge)
{
tmp = BitLeft(bits, leftShift);
if (pixelsRemainingOnRightEdge > rightShift)
{
bits = *psrc++;
tmp |= BitRight (bits, rightShift);
}
EndStep (pdst, nl);
switch (nl)
{
case 7:
StoreBitsPlain(-7,tmp); Step(tmp);
case 6:
StoreBitsPlain(-6,tmp); Step(tmp);
case 5:
StoreBitsPlain(-5,tmp); Step(tmp);
case 4:
StoreBitsPlain(-4,tmp); Step(tmp);
case 3:
StoreBitsPlain(-3,tmp); Step(tmp);
case 2:
StoreBitsPlain(-2,tmp); Step(tmp);
case 1:
StoreBitsPlain(-1,tmp); Step(tmp);
}
if (endmask)
*pdst = (*pdst & ~endmask) | (GetPixelGroup(tmp) & endmask);
}
}
}
else
{
while (height--)
{
psrc = psrcLine;
pdst = pdstLine;
psrcLine += widthSrc;
pdstLine += widthDst;
bits = *psrc++;
if (startmask)
{
if (firstoff < 0)
tmp = BitRight (bits, -firstoff);
else
{
tmp = BitLeft (bits, firstoff);
if (firstoff >= (MFB_PPW-PPW))
{
bits = *psrc++;
if (firstoff != (MFB_PPW-PPW))
tmp |= BitRight (bits, secondoff);
}
}
src = GetBitGroup(tmp);
*pdst = MaskRRopPixels (*pdst, src, startmask);
pdst++;
}
nl = nlMiddle;
while (nl >= 8)
{
nl -= 8;
tmp = BitLeft(bits, leftShift);
bits = *psrc++;
if (rightShift != MFB_PPW)
tmp |= BitRight(bits, rightShift);
StoreRopBits0(tmp); FirstStep(tmp);
StoreRopBits(1,tmp); Step(tmp);
StoreRopBits(2,tmp); Step(tmp);
StoreRopBits(3,tmp); Step(tmp);
StoreRopBits(4,tmp); Step(tmp);
StoreRopBits(5,tmp); Step(tmp);
StoreRopBits(6,tmp); Step(tmp);
StoreRopBits(7,tmp); EndStep(pdst,8);
}
if (pixelsRemainingOnRightEdge)
{
tmp = BitLeft(bits, leftShift);
if (pixelsRemainingOnRightEdge > rightShift)
{
bits = *psrc++;
tmp |= BitRight (bits, rightShift);
}
while (nl--)
{
src = GetBitGroup (tmp);
*pdst = RRopPixels (*pdst, src);
pdst++;
NextBitGroup(tmp);
}
if (endmask)
{
src = GetBitGroup (tmp);
*pdst = MaskRRopPixels (*pdst, src, endmask);
}
}
}
}
}
}
#else
#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))
#define GetBits(psrc, nBits, curBit, bitPos, bits) {\
bits = 0; \
while (nBits--) \
{ \
bits |= ((*psrc++ >> bitPos) & 1) << curBit; \
StepBit (curBit, 1); \
} \
}
static void
#if PSZ == 16
cfbCopyPlane1to16
#endif
#if PSZ == 24
cfbCopyPlane1to24
#endif
#if PSZ == 32
cfbCopyPlane1to32
#endif
(
DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
int rop,
RegionPtr prgnDst,
DDXPointPtr pptSrc,
unsigned long planemask)
{
int srcx, srcy, dstx, dsty;
int width, height;
int xoffSrc;
CfbBits *psrcBase, *pdstBase;
int widthSrc, widthDst;
unsigned int *psrcLine;
register unsigned int *psrc;
#if PSZ == 16
unsigned short *pdstLine;
register unsigned short *pdst;
#endif
#if PSZ == 32
unsigned int *pdstLine;
register unsigned int *pdst;
#endif
#if PSZ == 24
unsigned char *pdstLine;
register unsigned char *pdst;
#endif
register unsigned int bits, tmp;
register unsigned int fgpixel, bgpixel;
register unsigned int src;
#if PSZ == 24
register unsigned int dst;
#endif
register int leftShift, rightShift;
register int i, nl;
int nbox;
BoxPtr pbox;
int result;
#if PSZ == 16
unsigned int doublet[4];
#endif
#if PSZ == 32
unsigned int doublet[8];
#endif
fgpixel = FgPixel & planemask;
bgpixel = BgPixel & planemask;
#if PSZ == 16
if (rop == GXcopy && (planemask & PMSK) == PMSK) {
doublet[0] = bgpixel | (bgpixel << 16);
doublet[1] = fgpixel | (bgpixel << 16);
doublet[2] = bgpixel | (fgpixel << 16);
doublet[3] = fgpixel | (fgpixel << 16);
}
#endif
#if PSZ == 32
if (rop == GXcopy && (planemask & PMSK) == PMSK) {
doublet[0] = bgpixel; doublet[1] = bgpixel;
doublet[2] = fgpixel; doublet[3] = bgpixel;
doublet[4] = bgpixel; doublet[5] = fgpixel;
doublet[6] = fgpixel; doublet[7] = fgpixel;
}
#endif
cfbGetTypedWidthAndPointer (pSrcDrawable, widthSrc, psrcBase, int, CfbBits)
cfbGetTypedWidthAndPointer (pDstDrawable, widthDst, pdstBase, int, CfbBits)
#if PSZ == 16
widthDst <<= 1;
#endif
#if PSZ == 24
widthDst <<= 2;
#endif
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 = (unsigned int *)psrcBase + srcy * widthSrc + (srcx >> 5);
#if PSZ == 16
pdstLine = (unsigned short *)pdstBase + dsty * widthDst + dstx;
#endif
#if PSZ == 24
pdstLine = (unsigned char *)pdstBase + dsty * widthDst + dstx * 3;
#endif
#if PSZ == 32
pdstLine = (unsigned int *)pdstBase + dsty * widthDst + dstx;
#endif
xoffSrc = srcx & 0x1f;
leftShift = xoffSrc;
rightShift = 32 - leftShift;
if (rop == GXcopy && (planemask & PMSK) == PMSK)
{
while (height--)
{
psrc = psrcLine;
pdst = pdstLine;
psrcLine += widthSrc;
pdstLine += widthDst;
bits = *psrc++;
nl = width;
while (nl >= 32)
{
tmp = BitLeft(bits, leftShift);
bits = *psrc++;
if (rightShift != 32)
tmp |= BitRight(bits, rightShift);
i = 0;
#if PSZ == 16
if ((unsigned long)psrc & 2) {
if (tmp & 0x01)
*pdst = fgpixel;
else
*pdst = bgpixel;
pdst++;
i++;
}
while (i <= 24)
{
unsigned tmpbits = tmp >> i;
*(unsigned int *)pdst = doublet[tmpbits & 0x03];
*(unsigned int *)(pdst + 2) =
doublet[(tmpbits >> 2) & 0x03];
*(unsigned int *)(pdst + 4) =
doublet[(tmpbits >> 4) & 0x03];
*(unsigned int *)(pdst + 6) =
doublet[(tmpbits >> 6) & 0x03];
pdst += 8;
i += 8;
}
while (i <= 30)
{
*(unsigned int *)pdst =
doublet[(tmp >> i) & 0x03];
pdst += 2;
i += 2;
}
if (i == 31) {
if ((tmp >> 31) & 0x01)
*pdst = fgpixel;
else
*pdst = bgpixel;
pdst++;
}
#endif
#if PSZ == 24
while (i < 32) {
if ((tmp >> i) & 0x01) {
*pdst = fgpixel;
*(pdst + 1) = fgpixel >> 8;
*(pdst + 2) = fgpixel >> 16;
}
else {
*pdst = bgpixel;
*(pdst + 1) = bgpixel >> 8;
*(pdst + 2) = bgpixel >> 16;
}
pdst += 3;
i++;
}
#endif
#if PSZ == 32
while (i <= 28) {
int pair;
pair = (tmp >> i) & 0x03;
*pdst = doublet[pair * 2];
*(pdst + 1) = doublet[pair * 2 + 1];
pair = (tmp >> (i + 2)) & 0x03;
*(pdst + 2) = doublet[pair * 2];
*(pdst + 3) = doublet[pair * 2 + 1];
pdst += 4;
i += 4;
}
while (i < 32) {
*pdst = ((tmp >> i) & 0x01) ? fgpixel : bgpixel;
pdst++;
i++;
}
#endif
nl -= 32;
}
if (nl)
{
tmp = BitLeft(bits, leftShift);
if (rightShift != 32)
{
bits = *psrc++;
tmp |= BitRight (bits, rightShift);
}
i = 32;
while (nl--)
{
--i;
#if PSZ == 24
if ((tmp >> (31 - i)) & 0x01) {
*pdst = fgpixel;
*(pdst + 1) = fgpixel >> 8;
*(pdst + 2) = fgpixel >> 16;
}
else {
*pdst = bgpixel;
*(pdst + 1) = bgpixel >> 8;
*(pdst + 2) = bgpixel >> 16;
}
pdst += 3;
#else
*pdst = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel;
pdst++;
#endif
}
}
}
}
else
{
while (height--)
{
psrc = psrcLine;
pdst = pdstLine;
psrcLine += widthSrc;
pdstLine += widthDst;
bits = *psrc++;
nl = width;
while (nl >= 32)
{
tmp = BitLeft(bits, leftShift);
bits = *psrc++;
if (rightShift != 32)
tmp |= BitRight(bits, rightShift);
i = 32;
while (i--)
{
src = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel;
#if PSZ == 24
dst = *pdst;
dst |= (*(pdst + 1)) << 8;
dst |= (*(pdst + 2)) << 16;
DoRop (result, rop, src, dst);
*pdst = (dst & ~planemask) |
(result & planemask);
*(pdst+1) = ((dst & ~planemask) >> 8) |
((result & planemask) >> 8);
*(pdst+2) = ((dst & ~planemask) >> 16) |
((result & planemask) >> 16);
pdst += 3;
#else
DoRop (result, rop, src, *pdst);
*pdst = (*pdst & ~planemask) |
(result & planemask);
pdst++;
#endif
}
nl -= 32;
}
if (nl)
{
tmp = BitLeft(bits, leftShift);
if (rightShift != 32)
{
bits = *psrc++;
tmp |= BitRight (bits, rightShift);
}
i = 32;
while (nl--)
{
--i;
src = ((tmp >> (31 - i)) & 0x01) ? fgpixel : bgpixel;
#if PSZ == 24
dst = *pdst;
dst |= (*(pdst + 1)) << 8;
dst |= (*(pdst + 2)) << 16;
DoRop (result, rop, src, dst);
*pdst = (dst & ~planemask) |
(result & planemask);
*(pdst+1) = ((dst & ~planemask) >> 8) |
((result & planemask) >> 8);
*(pdst+2) = ((dst & ~planemask) >> 16) |
((result & planemask) >> 16);
pdst += 3;
#else
DoRop (result, rop, src, *pdst);
*pdst = (*pdst & ~planemask) |
(result & planemask);
pdst++;
#endif
}
}
}
}
}
}
#endif
RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
DrawablePtr pSrcDrawable;
DrawablePtr pDstDrawable;
GCPtr pGC;
int srcx, srcy;
int width, height;
int dstx, dsty;
unsigned long bitPlane;
{
RegionPtr ret;
#if IMAGE_BYTE_ORDER == LSBFirst
void (*doCopyPlaneExpand)(
DrawablePtr ,
DrawablePtr ,
int ,
RegionPtr ,
DDXPointPtr ,
unsigned long );
if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == PSZ)
{
if (bitPlane == 1)
{
doCopyPlaneExpand = cfbCopyPlane1toN;
#if PSZ == 8
cfb8CheckOpaqueStipple (pGC->alu,
pGC->fgPixel, pGC->bgPixel,
pGC->planemask);
#else
FgPixel = pGC->fgPixel;
BgPixel = pGC->bgPixel;
#endif
ret = cfbCopyPlaneExpand (pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty, doCopyPlaneExpand, bitPlane);
}
else
ret = miHandleExposures (pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
}
else if (pSrcDrawable->bitsPerPixel == PSZ && pDstDrawable->bitsPerPixel == 1)
{
int oldalu;
oldalu = pGC->alu;
if ((pGC->fgPixel & 1) == 0 && (pGC->bgPixel&1) == 1)
pGC->alu = mfbGetInverseAlu(pGC->alu);
else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))
pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel);
ret = cfbCopyPlaneReduce(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty,
cfbCopyPlaneNto1, bitPlane);
pGC->alu = oldalu;
}
else if (pSrcDrawable->bitsPerPixel == PSZ && pDstDrawable->bitsPerPixel == PSZ)
{
PixmapPtr pBitmap;
ScreenPtr pScreen = pSrcDrawable->pScreen;
GCPtr pGC1;
pBitmap = (*pScreen->CreatePixmap) (pScreen, width, height, 1);
if (!pBitmap)
return NULL;
pGC1 = GetScratchGC (1, pScreen);
if (!pGC1)
{
(*pScreen->DestroyPixmap) (pBitmap);
return NULL;
}
ValidateGC ((DrawablePtr) pBitmap, pGC1);
cfbCopyPlaneReduce(pSrcDrawable, (DrawablePtr) pBitmap,
pGC1, srcx, srcy, width, height, 0, 0,
cfbCopyPlaneNto1, bitPlane);
#if PSZ == 8
cfb8CheckOpaqueStipple (pGC->alu,
pGC->fgPixel, pGC->bgPixel,
pGC->planemask);
#else
FgPixel = pGC->fgPixel;
BgPixel = pGC->bgPixel;
#endif
cfbCopyPlaneExpand((DrawablePtr) pBitmap, pDstDrawable, pGC,
0, 0, width, height, dstx, dsty, cfbCopyPlane1toN, 1);
FreeScratchGC (pGC1);
(*pScreen->DestroyPixmap) (pBitmap);
ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC,
srcx, srcy, width, height,
dstx, dsty, bitPlane);
}
else
#endif
ret = miCopyPlane (pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
return ret;
}