#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
#include "maskbits.h"
#define PSZ 8
#include "mergerop.h"
#else
#include "cfbtab.h"
#endif
void
cfbCopyImagePlane(
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(
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
#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;
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