home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xibm.zip
/
apa16
/
apa16FlSp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-20
|
22KB
|
728 lines
/***********************************************************
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/***********************************************************
Copyright IBM Corporation 1987,1988
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of IBM not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/***********************************************************
Copyright 1989 by the Massachusetts Institute of Technology
All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the Massachusetts
Institute of Technology (M.I.T.) not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/* $XConsortium: apa16FlSp.c,v 1.2 90/03/05 13:53:30 swick Exp $ */
#include "X.h"
#include "Xmd.h"
#include "gcstruct.h"
#include "window.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "mfb.h"
#include "maskbits.h"
#include "servermd.h"
#include "OScompiler.h"
#include "apa16Hdwr.h"
#include "ibmTrace.h"
/* scanline filling for monochrome frame buffer
written by drewry, oct 1986
modified for apa16 by erik, may 1987
optimized by jfc, june 1991
these routines all clip. they assume that anything that has called
them has already translated the points (i.e. pGC->miTranslate is
non-zero, which is howit gets set in mfbCreateGC().)
the number of new scnalines created by clipping ==
MaxRectsPerBand * nSpans.
FillSolid is overloaded to be used for OpaqueStipple as well,
if fgPixel == bgPixel.
FillTiled is overloaded to be used for OpaqueStipple, if
fgPixel != bgPixel. based on the fill style, it uses
{RotatedPixmap, gc.alu} or {RotatedPixmap, PrivGC.ropOpStip}
*/
void
apa16SolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GCPtr pGC;
int nInit; /* number of spans to fill */
DDXPointPtr pptInit; /* pointer to list of start points */
int *pwidthInit; /* pointer to list of n widths */
int fSorted;
{
/* next three parameters are post-clip */
int n; /* number of spans to fill */
register DDXPointPtr ppt; /* pointer to list of start points */
register int *pwidth; /* pointer to list of n widths */
int rop; /* reduced rasterop */
mfbPrivGC *gcpriv;
if (!(pGC->planemask & 1) || nInit == 0)
return;
TRACE(("apa16SolidFS(pDrawable=%#x, pGC=%#x, n=%d, ppt=%#x {%d,%d}, pwidth=%#x (%d))\n",
pDrawable, pGC, nInit, pptInit, pptInit->x,
pptInit->y, pwidthInit, *pwidthInit));
gcpriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
rop = gcpriv->rop;
if (rop==RROP_NOP) return;
if (pDrawable->type!=DRAWABLE_WINDOW) {
if (rop==RROP_WHITE)
mfbWhiteSolidFS(pDrawable,pGC,nInit,pptInit,pwidthInit,fSorted);
else if (rop==RROP_BLACK)
mfbBlackSolidFS(pDrawable,pGC,nInit,pptInit,pwidthInit,fSorted);
else if (rop==RROP_INVERT)
mfbInvertSolidFS(pDrawable,pGC,nInit,pptInit,pwidthInit,fSorted);
return;
}
n = nInit * miFindMaxBand(gcpriv->pCompositeClip);
pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
if (!pwidth)
return;
ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if(!ppt)
{
DEALLOCATE_LOCAL(ppt);
return;
}
n = miClipSpans(gcpriv->pCompositeClip, pptInit, pwidthInit,
nInit, ppt, pwidth, fSorted);
if (n == 0)
return;
if (rop == RROP_BLACK)
rop = STYPE_BLACK;
else if (rop == RROP_WHITE)
rop = STYPE_WHITE;
else /* rop == RROP_INVERT */
rop = STYPE_INVERT;
apa16FastFS(pwidth, ppt, n, rop);
DEALLOCATE_LOCAL(ppt);
DEALLOCATE_LOCAL(pwidth);
return ;
}
/* this works with tiles of width == 32 */
/* the "hard" way is used if writing neither 0 nor 1 to a bit can be
used as a noop. */
#define FILLSPAN32_HARD(ROP) \
while (--n >= 0) \
{ register unsigned int *addrl; \
if (*pwidth) \
{ \
addrl = ((unsigned int *)APA16_BASE) + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5); \
src = psrc[ppt->y % tileHeight]; \
if ( ((ppt->x & 0x1f) + *pwidth) < 32) \
{ \
maskpartialbits(ppt->x, *pwidth, startmask); \
*addrl = (*addrl & ~startmask) | (ROP(src, *addrl) & startmask); \
} \
else \
{ \
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
if (startmask) \
{ \
*addrl = (*addrl & ~startmask) | \
(ROP(src, *addrl) & startmask); \
addrl++; \
} \
while (nlmiddle--) \
{ \
*addrl = ROP(src, *addrl); \
addrl++; \
} \
if (endmask) \
*addrl = (*addrl & ~endmask) | \
(ROP(src, *addrl) & endmask); \
} \
} \
pwidth++; \
ppt++; \
}
/* This version is modified for the apa16: it assumes that
the mode register has been set and writing NOP has no
effect with the current setting. */
#define FILLSPAN32(NOP) \
while (--n >= 0) \
{ register unsigned int *addrl; \
if (*pwidth) \
{ \
addrl = ((unsigned int *)APA16_BASE) + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5); \
src = psrc[ppt->y % tileHeight]; \
if ( ((ppt->x & 0x1f) + *pwidth) < 32) \
{ \
maskpartialbits(ppt->x, *pwidth, startmask); \
*addrl = (NOP & ~startmask) | (src & startmask); \
} \
else \
{ \
maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
if (startmask) \
*addrl++ = (src & startmask) | (NOP & ~startmask); \
while (nlmiddle--) \
*addrl++ = src; \
if (endmask) \
*addrl = (NOP & ~endmask) | (src & endmask); \
} \
} \
pwidth++; \
ppt++; \
}
void
apa16TileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit; /* number of spans to fill */
DDXPointPtr pptInit; /* pointer to list of start points */
int *pwidthInit; /* pointer to list of n widths */
int fSorted;
{
/* next three parameters are post-clip */
int n; /* number of spans to fill */
register DDXPointPtr ppt; /* pointer to list of start points */
register int *pwidth; /* pointer to list of n widths */
register int startmask;
register int endmask;
register int nlmiddle;
PixmapPtr pTile;
int *psrc;
register int src;
int tileHeight;
int rop;
int *pwidthFree; /* copies of the pointers to free */
DDXPointPtr pptFree;
mfbPrivGC *gcpriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
if (!(pGC->planemask & 1))
return;
if (pDrawable->type != DRAWABLE_WINDOW)
{
mfbTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
return;
}
n = nInit * miFindMaxBand(gcpriv->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if(!pptFree || !pwidthFree)
{
if (pptFree) DEALLOCATE_LOCAL(pptFree);
if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(gcpriv->pCompositeClip, pptInit, pwidthInit,
nInit, ppt, pwidth, fSorted);
#if FAST_TILE
if (!pGC->tileIsPixel)
{
pTile = pGC->tile.pixmap;
if (pTile->drawable.width >= 16)
{
apa16FastTileFS(pwidth, ppt, n, apa16_rop2stype[pGC->alu],
pTile->devPrivate.ptr, pTile->drawable.width,
pTile->drawable.height, pTile->devKind,
pGC->patOrg.x + pDrawable->x,
pGC->patOrg.y + pDrawable->y);
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
return;
}
}
#endif
SET_MERGE_MODE(MERGE_COPY);
pTile = gcpriv->pRotatedPixmap;
tileHeight = pTile->drawable.height;
psrc = (int *)(pTile->devPrivate.ptr);
if (pGC->fillStyle == FillTiled)
rop = pGC->alu;
else
rop = gcpriv->ropOpStip;
switch(rop)
{
case GXclear:
FILLSPAN32_HARD(fnCLEAR)
break;
case GXand:
MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_AND;
FILLSPAN32(~0)
MR = MR_DEFAULT;
break;
case GXandReverse:
MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_BLACK;
goto fs32_0;
case GXcopy:
FILLSPAN32_HARD(fnCOPY)
break;
case GXandInverted:
FILLSPAN32_HARD(fnANDINVERTED)
break;
case GXnoop:
break;
case GXxor:
FILLSPAN32_HARD(fnXOR)
break;
case GXor:
MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_WHITE;
fs32_0:
FILLSPAN32(0)
MR = MR_DEFAULT;
break;
case GXnor:
FILLSPAN32_HARD(fnNOR)
break;
case GXequiv:
FILLSPAN32_HARD(fnEQUIV)
break;
case GXinvert:
MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_INVERT;
goto fs32_0;
case GXorReverse:
FILLSPAN32_HARD(fnORREVERSE)
break;
case GXcopyInverted:
FILLSPAN32_HARD(fnCOPYINVERTED)
break;
case GXorInverted:
FILLSPAN32_HARD(fnORINVERTED)
break;
case GXnand:
FILLSPAN32_HARD(fnNAND)
break;
case GXset:
FILLSPAN32_HARD(fnSET)
break;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
return ;
}
/* Fill spans with tiles that aren't 32 bits wide */
void
apa16UnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit; /* number of spans to fill */
DDXPointPtr pptInit; /* pointer to list of start points */
int *pwidthInit; /* pointer to list of n widths */
int fSorted;
{
int iline; /* first line of tile to use */
/* next three parameters are post-clip */
int n; /* number of spans to fill */
register DDXPointPtr ppt; /* pointer to list of start points */
register int *pwidth; /* pointer to list of n widths */
register unsigned int *pdst;/* pointer to current word in bitmap */
register unsigned int *psrc;/* pointer to current word in tile */
register unsigned int startmask;
register int nlMiddle;
PixmapPtr pTile; /* pointer to tile we want to fill with */
int w, width, x, xSrc, ySrc, srcStartOver, nstart, nend;
int tlwidth, rem, tileWidth, tileHeight, endinc, rop;
unsigned int endmask, *psrcT;
int *pwidthFree; /* copies of the pointers to free */
DDXPointPtr pptFree;
if (!(pGC->planemask & 1))
return;
if (pDrawable->type != DRAWABLE_WINDOW)
{
mfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
return;
}
n = nInit *
miFindMaxBand(((mfbPrivGC *)
(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if(!pptFree || !pwidthFree)
{
if (pptFree) DEALLOCATE_LOCAL(pptFree);
if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip,
pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
#ifdef FAST_TILE
if (!pGC->tileIsPixel)
{
pTile = pGC->tile.pixmap;
if (pTile->drawable.width >= 16)
{
apa16FastTileFS(pwidth, ppt, n, apa16_rop2stype[pGC->alu],
pTile->devPrivate.ptr, pTile->drawable.width,
pTile->drawable.height, pTile->devKind,
pGC->patOrg.x + pDrawable->x,
pGC->patOrg.y + pDrawable->y);
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
return;
}
}
#endif
if (pGC->fillStyle == FillTiled)
{
pTile = pGC->tile.pixmap;
tlwidth = pTile->devKind >> 2;
rop = pGC->alu;
}
else
{
pTile = pGC->stipple;
tlwidth = pTile->devKind >> 2;
rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->ropOpStip;
}
if (rop == GXnoop) {
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
return;
}
xSrc = pDrawable->x;
ySrc = pDrawable->y;
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
/* this replaces rotating the tile. Instead we just adjust the offset
* at which we start grabbing bits from the tile.
* Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
* so that iline and rem always stay within the tile bounds.
*/
xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
QUEUE_WAIT();
while (n--)
{
iline = (ppt->y - ySrc) % tileHeight;
pdst = (unsigned int *)APA16_BASE + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5);
psrcT = (unsigned int *) pTile->devPrivate.ptr + (iline * tlwidth);
x = ppt->x;
if (*pwidth)
{
width = *pwidth;
while(width > 0)
{
psrc = psrcT;
w = MIN(tileWidth, width);
if((rem = (x - xSrc) % tileWidth) != 0)
{
/* if we're in the middle of the tile, get
as many bits as will finish the span, or
as many as will get to the left edge of the tile,
or a longword worth, starting at the appropriate
offset in the tile.
*/
w = MIN(MIN(tileWidth - rem, width), BITMAP_SCANLINE_UNIT);
endinc = rem / BITMAP_SCANLINE_UNIT;
getandputrop((psrc+endinc), (rem&0x1f), (x & 0x1f), w, pdst, rop);
if((x & 0x1f) + w >= 0x20)
pdst++;
}
else if(((x & 0x1f) + w) < 32)
{
/* doing < 32 bits is easy, and worth special-casing */
putbitsrop(*psrc, x & 0x1f, w, pdst, rop);
}
else
{
/* start at the left edge of the tile,
and put down as much as we can
*/
maskbits(x, w, startmask, endmask, nlMiddle);
if (startmask)
nstart = 32 - (x & 0x1f);
else
nstart = 0;
if (endmask)
nend = (x + w) & 0x1f;
else
nend = 0;
srcStartOver = nstart > 31;
if(startmask)
{
putbitsrop(*psrc, (x & 0x1f), nstart, pdst, rop);
pdst++;
if(srcStartOver)
psrc++;
}
while(nlMiddle--)
{
getandputrop0(psrc, nstart, 32, pdst, rop);
pdst++;
psrc++;
}
if(endmask)
{
getandputrop0(psrc, nstart, nend, pdst, rop);
}
}
x += w;
width -= w;
}
}
ppt++;
pwidth++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}
/* Fill spans with stipples that aren't 32 bits wide */
void
apa16UnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
DrawablePtr pDrawable;
GC *pGC;
int nInit; /* number of spans to fill */
DDXPointPtr pptInit; /* pointer to list of start points */
int *pwidthInit; /* pointer to list of n widths */
int fSorted;
{
/* next three parameters are post-clip */
int n; /* number of spans to fill */
register DDXPointPtr ppt; /* pointer to list of start points */
register int *pwidth; /* pointer to list of n widths */
int iline; /* first line of tile to use */
register unsigned int *pdst;/* pointer to current word in bitmap */
register int *psrc; /* pointer to current word in tile */
register int startmask;
register int nlMiddle;
PixmapPtr pTile; /* pointer to tile we want to fill with */
int w, width, x, xSrc, ySrc, srcStartOver, nstart, nend;
int endmask, tlwidth, rem, tileWidth, *psrcT, endinc, rop;
int tileHeight;
int *pwidthFree; /* copies of the pointers to free */
DDXPointPtr pptFree;
if (!(pGC->planemask & 1))
return;
if (pDrawable->type != DRAWABLE_WINDOW)
{
mfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
return;
}
n = nInit * miFindMaxBand(((mfbPrivGC *)
(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip);
pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
if(!pptFree || !pwidthFree)
{
if (pptFree) DEALLOCATE_LOCAL(pptFree);
if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
return;
}
pwidth = pwidthFree;
ppt = pptFree;
n = miClipSpans(((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip,
pptInit, pwidthInit, nInit,
ppt, pwidth, fSorted);
pTile = pGC->stipple;
rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
if (rop == GXnoop)
{
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
return;
}
tlwidth = pTile->devKind >> 2;
xSrc = pDrawable->x;
ySrc = pDrawable->y;
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
/* this replaces rotating the stipple. Instead, we just adjust the offset
* at which we start grabbing bits from the stipple.
* Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
* so that iline and rem always stay within the tile bounds.
*/
xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
QUEUE_WAIT();
while (n--)
{
iline = (ppt->y - ySrc) % tileHeight;
pdst = (unsigned int *)APA16_BASE + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5);
psrcT = (int *) pTile->devPrivate.ptr + (iline * tlwidth);
x = ppt->x;
if (*pwidth)
{
width = *pwidth;
while(width > 0)
{
psrc = psrcT;
w = MIN(tileWidth, width);
if((rem = (x - xSrc) % tileWidth) != 0)
{
/* if we're in the middle of the tile, get
as many bits as will finish the span, or
as many as will get to the left edge of the tile,
or a longword worth, starting at the appropriate
offset in the tile.
*/
w = MIN(MIN(tileWidth - rem, width), BITMAP_SCANLINE_UNIT);
endinc = rem / BITMAP_SCANLINE_UNIT;
getandputrrop((psrc + endinc), (rem & 0x1f), (x & 0x1f),
w, pdst, rop)
if((x & 0x1f) + w >= 0x20)
pdst++;
}
else if(((x & 0x1f) + w) < 32)
{
/* doing < 32 bits is easy, and worth special-casing */
putbitsrrop(*psrc, x & 0x1f, w, pdst, rop);
}
else
{
/* start at the left edge of the tile,
and put down as much as we can
*/
maskbits(x, w, startmask, endmask, nlMiddle);
if (startmask)
nstart = 32 - (x & 0x1f);
else
nstart = 0;
if (endmask)
nend = (x + w) & 0x1f;
else
nend = 0;
srcStartOver = nstart > 31;
if(startmask)
{
putbitsrrop(*psrc, (x & 0x1f), nstart, pdst, rop);
pdst++;
if(srcStartOver)
psrc++;
}
while(nlMiddle--)
{
getandputrrop0(psrc, nstart, 32, pdst, rop);
pdst++;
psrc++;
}
if(endmask)
{
getandputrrop0(psrc, nstart, nend, pdst, rop);
}
}
x += w;
width -= w;
}
}
ppt++;
pwidth++;
}
DEALLOCATE_LOCAL(pptFree);
DEALLOCATE_LOCAL(pwidthFree);
}