You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
870 lines
20 KiB
870 lines
20 KiB
|
|
/******************************Module*Header*******************************\
|
|
* Module Name: solid.cxx
|
|
*
|
|
* This contains the special case blting code for P, Pn, DPx and Dn rops
|
|
* with solid colors.
|
|
*
|
|
* Created: 03-Mar-1991 22:01:14
|
|
* Author: Patrick Haluptzok patrickh
|
|
*
|
|
* Copyright (c) 1991-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
// Array of masks for blting
|
|
|
|
ULONG aulMsk[] =
|
|
{
|
|
0xFFFFFFFF,
|
|
0xFFFFFF7F,
|
|
0xFFFFFF3F,
|
|
0xFFFFFF1F,
|
|
0xFFFFFF0F,
|
|
0xFFFFFF07,
|
|
0xFFFFFF03,
|
|
0xFFFFFF01,
|
|
0xFFFFFF00,
|
|
0xFFFF7F00,
|
|
0xFFFF3F00,
|
|
0xFFFF1F00,
|
|
0xFFFF0F00,
|
|
0xFFFF0700,
|
|
0xFFFF0300,
|
|
0xFFFF0100,
|
|
0xFFFF0000,
|
|
0xFF7F0000,
|
|
0xFF3F0000,
|
|
0xFF1F0000,
|
|
0xFF0F0000,
|
|
0xFF070000,
|
|
0xFF030000,
|
|
0xFF010000,
|
|
0xFF000000,
|
|
0x7F000000,
|
|
0x3F000000,
|
|
0x1F000000,
|
|
0x0F000000,
|
|
0x07000000,
|
|
0x03000000,
|
|
0x01000000,
|
|
};
|
|
|
|
#define DBG_SOLID 0
|
|
|
|
#if DBG_SOLID
|
|
ULONG DbgSolid = 0;
|
|
#endif
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidFillRect1
|
|
*
|
|
* Does a solid blt to a DIB of 1, 4, 8, 16 or 32 bpp.
|
|
*
|
|
* History:
|
|
*
|
|
* 17-Nov-1992 -by- Jim Thomas [jimt]
|
|
* Change call to work on list of rectangles.
|
|
* Change center loop to call RtlFillMemory only for wide
|
|
* scan lines
|
|
*
|
|
* 03-Feb-1992 -by- Donald Sidoroff [donalds]
|
|
* Rewrote it.
|
|
*
|
|
* 01-Mar-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidFillRect1(
|
|
PRECTL prcl,
|
|
ULONG cRcl,
|
|
PBYTE pjDst,
|
|
LONG lDeltaDst,
|
|
ULONG iColor,
|
|
ULONG cShift)
|
|
{
|
|
ULONG ulMskLeft;
|
|
ULONG ulMskRight;
|
|
ULONG cLeft;
|
|
ULONG cRight;
|
|
ULONG cxDword;
|
|
ULONG yRow;
|
|
ULONG ulColor;
|
|
PULONG pulTmp;
|
|
PULONG pulDst;
|
|
ULONG cx;
|
|
ULONG cy;
|
|
ULONG xDstStart;
|
|
|
|
#if DBG_SOLID
|
|
if (DbgSolid >= 1) {
|
|
DbgPrint("SolidFillRect1:\n");
|
|
DbgPrint(" pjDst = 0x%08lx\n",pjDst);
|
|
|
|
if (DbgSolid >= 2) {
|
|
DbgPrint(" prcl = 0x%08lx\n",prcl);
|
|
DbgPrint(" cRcl = %li\n",cRcl);
|
|
DbgPrint(" lDeltaDst = %li\n",lDeltaDst);
|
|
DbgPrint(" iColor = 0x%08lx\n",iColor);
|
|
DbgPrint(" cShift = %li\n",cShift);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// loop through each rectangle
|
|
//
|
|
|
|
for ( ;cRcl > 0;cRcl--, prcl++ )
|
|
{
|
|
//
|
|
// make sure rectangle is well ordered
|
|
//
|
|
|
|
ASSERTGDI(prcl != NULL,"ERROR: prcl = NULL");
|
|
ASSERTGDI(prcl->right > prcl->left,"ERROR: left >= right");
|
|
ASSERTGDI(prcl->bottom > prcl->top, "ERROR: top >= bottom");
|
|
|
|
#if DBG_SOLID
|
|
|
|
if (DbgSolid >= 1) {
|
|
DbgPrint(" Rect: %li,%li to %li,%li\n",
|
|
prcl->left,prcl->top,
|
|
prcl->right,prcl->bottom);
|
|
}
|
|
|
|
#endif
|
|
|
|
pulDst = (PULONG)(pjDst + prcl->top * lDeltaDst);
|
|
|
|
cy = prcl->bottom - prcl->top;
|
|
|
|
//
|
|
// cx is the number of bits in the scan line to fill
|
|
//
|
|
|
|
cx = (prcl->right - prcl->left) << cShift;
|
|
|
|
//
|
|
// Starting bit
|
|
//
|
|
|
|
xDstStart = prcl->left << cShift;
|
|
|
|
//
|
|
// starting and ending DWORD offset
|
|
//
|
|
|
|
cLeft = xDstStart >> 5;
|
|
cRight = (xDstStart + cx) >> 5;
|
|
|
|
//
|
|
// generate left and right bit masks
|
|
//
|
|
|
|
ulMskLeft = aulMsk[xDstStart & 0x1f];
|
|
ulMskRight = aulMsk[(xDstStart+cx) & 0x1f];
|
|
|
|
//
|
|
// if cLeft equals cRight then onyl 1 DWORD needs to be modified,
|
|
// combine left and right masks. Do entire strip.
|
|
//
|
|
|
|
if (cLeft == cRight) {
|
|
ulMskLeft &= ~ulMskRight;
|
|
ulColor = iColor & ulMskLeft;
|
|
ulMskLeft = ~ulMskLeft;
|
|
pulTmp = pulDst + cLeft;
|
|
|
|
while (cy--) {
|
|
*pulTmp = (*pulTmp & ulMskLeft) | ulColor;
|
|
pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// do solid fill in three portions,
|
|
//
|
|
// left edge (partial DWORD)
|
|
// center (full DWORD)
|
|
// right edge (partial DWORD)
|
|
//
|
|
|
|
//
|
|
// left strip
|
|
//
|
|
|
|
if (ulMskLeft != ~0) {
|
|
pulTmp = pulDst + cLeft;
|
|
ulColor = iColor & ulMskLeft;
|
|
ulMskLeft = ~ulMskLeft;
|
|
yRow = cy;
|
|
|
|
while (yRow--) {
|
|
*pulTmp = (*pulTmp & ulMskLeft) | ulColor;
|
|
pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
|
|
}
|
|
|
|
cLeft++;
|
|
}
|
|
|
|
//
|
|
// center calc number of DWORDS
|
|
//
|
|
|
|
cxDword = cRight - cLeft;
|
|
pulTmp = pulDst + cLeft;
|
|
if (cxDword != 0) {
|
|
|
|
yRow = cy;
|
|
|
|
while (yRow--) {
|
|
|
|
switch (cxDword) {
|
|
case 7:
|
|
*(pulTmp+6) = iColor;
|
|
case 6:
|
|
*(pulTmp+5) = iColor;
|
|
case 5:
|
|
*(pulTmp+4) = iColor;
|
|
case 4:
|
|
*(pulTmp+3) = iColor;
|
|
case 3:
|
|
*(pulTmp+2) = iColor;
|
|
case 2:
|
|
*(pulTmp+1) = iColor;
|
|
case 1:
|
|
*(pulTmp) = iColor;
|
|
break;
|
|
default:
|
|
RtlFillMemoryUlong((PVOID)pulTmp,cxDword<<2,iColor);
|
|
}
|
|
|
|
pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// right edge
|
|
//
|
|
|
|
if (ulMskRight != ~0) {
|
|
pulTmp = pulDst + cRight;
|
|
ulColor = iColor & ~ulMskRight;
|
|
|
|
|
|
while (cy--) {
|
|
*pulTmp = (*pulTmp & ulMskRight) | ulColor;
|
|
pulTmp = (PULONG)((PBYTE)pulTmp + lDeltaDst);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidFillRect24
|
|
*
|
|
* Does a solid blt to a 24 bpp DIB.
|
|
*
|
|
* History:
|
|
*
|
|
* 17-Nov-1992 -by- Jim Thomas [jimt]
|
|
* Change call to list of rects
|
|
*
|
|
* 02-Mar-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidFillRect24(
|
|
PRECTL prcl,
|
|
ULONG cRcl,
|
|
PBYTE pjDst,
|
|
LONG lDeltaDst,
|
|
ULONG iColor,
|
|
ULONG cShift)
|
|
{
|
|
PBYTE pjDstRow;
|
|
BYTE jRed,jGreen,jBlue;
|
|
ULONG cxTemp;
|
|
ULONG cx;
|
|
ULONG cy;
|
|
LONG lDelta;
|
|
|
|
DONTUSE(cShift);
|
|
|
|
//
|
|
// place any asserts here
|
|
//
|
|
|
|
|
|
jRed = (BYTE)iColor;
|
|
jGreen = (BYTE)(iColor >> 8);
|
|
jBlue = (BYTE)(iColor >> 16);
|
|
|
|
|
|
//
|
|
// loop through each rectangle
|
|
//
|
|
|
|
for ( ;cRcl > 0;cRcl--, prcl++ )
|
|
{
|
|
pjDstRow = pjDst + (prcl->top * lDeltaDst) + 3 * prcl->left;
|
|
|
|
cy = prcl->bottom - prcl->top;
|
|
cx = prcl->right - prcl->left;
|
|
|
|
//
|
|
// lDelta is adjusted to go from the end of one scan
|
|
// line to the start of the next.
|
|
//
|
|
|
|
lDelta = lDeltaDst - 3*cx;
|
|
|
|
while (cy--) {
|
|
|
|
cxTemp = cx;
|
|
|
|
while (cxTemp--) {
|
|
|
|
*(pjDstRow) = jRed;
|
|
*(pjDstRow+1) = jGreen;
|
|
*(pjDstRow+2) = jBlue;
|
|
|
|
pjDstRow += 3;
|
|
}
|
|
|
|
pjDstRow += lDelta;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidXorRect1
|
|
*
|
|
* Does an xor blt to a DIB or 1, 4, 8, 16 or 32 bpp.
|
|
*
|
|
* History:
|
|
*
|
|
* 17-Nov-1992 -by- Jim Thomas [jimt]
|
|
* Change call to list of rects
|
|
*
|
|
*
|
|
* 03-Feb-1992 -by- Donald Sidoroff [donalds]
|
|
* Rewrote it.
|
|
*
|
|
* 01-Mar-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidXorRect1(
|
|
PRECTL prcl,
|
|
ULONG cRcl,
|
|
PBYTE pjDst,
|
|
LONG lDeltaDst,
|
|
ULONG iColor,
|
|
ULONG cShift)
|
|
{
|
|
ULONG ulMskLeft;
|
|
ULONG ulMskRight;
|
|
ULONG iLeft;
|
|
ULONG iRight;
|
|
ULONG cLeft;
|
|
ULONG cRight;
|
|
ULONG culFill;
|
|
ULONG yRow;
|
|
PULONG pulTmp;
|
|
PULONG pulDst;
|
|
ULONG cx;
|
|
ULONG cy;
|
|
ULONG xDstStart;
|
|
BOOL bSimple;
|
|
|
|
#if DBG_SOLID
|
|
|
|
if (DbgSolid >= 1) {
|
|
DbgPrint("SolidXorRect1:\n");
|
|
DbgPrint(" pjDst = 0x%08lx\n",pjDst);
|
|
|
|
if (DbgSolid >= 2) {
|
|
DbgPrint(" prcl = 0x%08lx\n",prcl);
|
|
DbgPrint(" cRcl = %li\n",cRcl);
|
|
DbgPrint(" lDeltaDst = %li\n",lDeltaDst);
|
|
DbgPrint(" iColor = 0x%08lx\n",iColor);
|
|
DbgPrint(" cShift = %li\n",cShift);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// loop through each rectangle
|
|
//
|
|
|
|
for ( ; cRcl > 0;cRcl--, prcl++ )
|
|
{
|
|
//
|
|
// init rect params
|
|
//
|
|
|
|
ASSERTGDI(prcl != NULL,"ERROR: prcl = NULL");
|
|
ASSERTGDI(prcl->right > prcl->left,"ERROR: left >= right");
|
|
ASSERTGDI(prcl->bottom > prcl->top, "ERROR: top >= bottom");
|
|
|
|
pulDst = (PULONG)(pjDst + prcl->top * lDeltaDst);
|
|
|
|
cx = (prcl->right - prcl->left) << cShift;
|
|
|
|
cy = prcl->bottom - prcl->top;
|
|
|
|
xDstStart = (prcl->left << cShift);
|
|
|
|
//
|
|
// calc index of leftmost and rightmost DWORDS
|
|
//
|
|
|
|
cLeft = xDstStart >> 5;
|
|
cRight = (xDstStart + cx) >> 5;
|
|
|
|
//
|
|
// calc number of bits used in leftmost and rightmost DWORDs
|
|
//
|
|
|
|
iLeft = xDstStart & 31;
|
|
iRight = (xDstStart + cx) & 31;
|
|
|
|
//
|
|
// generate DWORD store masks
|
|
//
|
|
|
|
ulMskLeft = aulMsk[iLeft];
|
|
ulMskRight = ~aulMsk[iRight];
|
|
|
|
//
|
|
// If the leftmost and rightmost DWORDs are the same, then only one
|
|
// strip is needed. Merge the two masks together and note this.
|
|
//
|
|
|
|
bSimple = FALSE;
|
|
|
|
if (cLeft == cRight)
|
|
{
|
|
ulMskLeft &= ulMskRight;
|
|
bSimple = TRUE;
|
|
}
|
|
|
|
|
|
#if DBG_SOLID
|
|
|
|
if (DbgSolid >= 1) {
|
|
DbgPrint(" Rect: %li,%li to %li,%li\n",
|
|
prcl->left,prcl->top,
|
|
prcl->right,prcl->bottom);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// Lay down the left edge, if needed.
|
|
//
|
|
|
|
if (bSimple || (iLeft != 0))
|
|
{
|
|
pulTmp = pulDst + cLeft;
|
|
ulMskLeft &= iColor;
|
|
|
|
for (yRow = 0; yRow != cy; yRow++)
|
|
{
|
|
*pulTmp ^= ulMskLeft;
|
|
pulTmp = (ULONG *) ((BYTE *) pulTmp + lDeltaDst);
|
|
}
|
|
|
|
cLeft++;
|
|
}
|
|
|
|
if (!bSimple) {
|
|
|
|
//
|
|
// Lay down the center strip, if needed.
|
|
//
|
|
|
|
culFill = cRight - cLeft;
|
|
|
|
if (culFill != 0)
|
|
{
|
|
pulTmp = pulDst + cLeft;
|
|
for (yRow = 0; yRow != cy; yRow++)
|
|
{
|
|
cx = culFill;
|
|
while (cx--)
|
|
*pulTmp++ ^= iColor;
|
|
|
|
pulTmp -= culFill;
|
|
pulTmp = (ULONG *) ((BYTE *) pulTmp + lDeltaDst);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Lay down the right edge, if needed.
|
|
//
|
|
|
|
if (iRight != 0)
|
|
{
|
|
pulTmp = pulDst + cRight;
|
|
ulMskRight &= iColor;
|
|
|
|
for (yRow = 0; yRow != cy; yRow++)
|
|
{
|
|
*pulTmp ^= ulMskRight;
|
|
pulTmp = (ULONG *) ((BYTE *) pulTmp + lDeltaDst);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidXorRect24
|
|
*
|
|
* Does a solid blt to a 24 bpp DIB.
|
|
*
|
|
* History:
|
|
*
|
|
* 17-Nov-1992 -by- Jim Thomes [jimt]
|
|
* change call to list of rects
|
|
*
|
|
* 03-Feb-1992 -by- Donald Sidoroff [donalds]
|
|
* Rewrote it.
|
|
*
|
|
* 02-Mar-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidXorRect24(
|
|
PRECTL prcl,
|
|
ULONG cRcl,
|
|
PBYTE pjDst,
|
|
LONG lDeltaDst,
|
|
ULONG iColor,
|
|
ULONG cShift)
|
|
{
|
|
PBYTE pjDstTmp;
|
|
BYTE jRed, jGreen, jBlue;
|
|
ULONG cxTemp;
|
|
ULONG cx;
|
|
ULONG cy;
|
|
LONG lDelta;
|
|
|
|
DONTUSE(cShift);
|
|
|
|
//
|
|
// lDelta is adjusted to go from the end of one scan
|
|
// line to the start of the next.
|
|
//
|
|
|
|
|
|
jRed = (BYTE) iColor;
|
|
jGreen = (BYTE) (iColor >> 8);
|
|
jBlue = (BYTE) (iColor >> 16);
|
|
|
|
|
|
for ( ;cRcl > 0;cRcl--, prcl++ )
|
|
{
|
|
//
|
|
// init rect params
|
|
//
|
|
|
|
pjDstTmp = pjDst + prcl->top * lDeltaDst + prcl->left * 3;
|
|
|
|
cx = prcl->right - prcl->left;
|
|
cy = prcl->bottom - prcl->top;
|
|
|
|
lDelta = lDeltaDst - (3 * cx);
|
|
|
|
ASSERTGDI(cx != 0, "ERROR vDibSolidBlt32");
|
|
ASSERTGDI(cy != 0, "ERROR vDibSolidBlt32");
|
|
|
|
while(cy--)
|
|
{
|
|
cxTemp = cx;
|
|
|
|
while(cxTemp--)
|
|
{
|
|
*(pjDstTmp) ^= jRed;
|
|
*(pjDstTmp+1) ^= jGreen;
|
|
*(pjDstTmp+2) ^= jBlue;
|
|
|
|
pjDstTmp += 3;
|
|
|
|
}
|
|
|
|
pjDstTmp = pjDstTmp + lDelta;
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidFillRow1
|
|
*
|
|
* Blt a list of adjacent rows to a DIB of of 1, 4, 8, 16 or 32 bpp.
|
|
*
|
|
* History:
|
|
* 11-Oct-1993 -by- Eric Kutter [erick]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidFillRow1(
|
|
PROW prow,
|
|
ULONG crow,
|
|
LONG yTop,
|
|
PBYTE pjBits,
|
|
ULONG iColor,
|
|
LONG lDelta,
|
|
ULONG cShift)
|
|
{
|
|
pjBits += yTop * lDelta;
|
|
|
|
for (UINT i = 0; i < crow; i++, prow++, pjBits += lDelta)
|
|
{
|
|
ULONG *pulDst = (PULONG)pjBits;
|
|
|
|
LONG cx = (prow->right - prow->left) << cShift;
|
|
ULONG xDstStart = prow->left << cShift;
|
|
|
|
BOOL bSimple = FALSE;
|
|
|
|
ULONG cLeft = xDstStart >> 5; // Index of leftmost DWORD
|
|
ULONG cRght = (xDstStart + cx) >> 5; // Index of rightmost DWORD
|
|
|
|
ULONG iLeft = xDstStart & 31; // Bits used in leftmost DWORD
|
|
ULONG iRght = (xDstStart + cx) & 31; // Bits used in rightmost DWORD
|
|
|
|
ULONG ulMskLeft = aulMsk[iLeft];
|
|
ULONG ulMskRght = ~aulMsk[iRght];
|
|
|
|
// If the leftmost and rightmost DWORDs are the same, then only one
|
|
// strip is needed. Merge the two masks together and note this.
|
|
|
|
if (cLeft == cRght)
|
|
{
|
|
ulMskLeft &= ulMskRght;
|
|
bSimple = TRUE;
|
|
}
|
|
|
|
// Lay down the left edge, if needed.
|
|
|
|
if (bSimple || (iLeft != 0))
|
|
{
|
|
pulDst[cLeft] = (pulDst[cLeft] & ~ulMskLeft) | (iColor & ulMskLeft);
|
|
|
|
if (bSimple)
|
|
continue;
|
|
|
|
cLeft++;
|
|
}
|
|
|
|
// Lay down the center strip, if needed.
|
|
|
|
ULONG cjFill = (cRght - cLeft) << 2;
|
|
|
|
if (cjFill != 0)
|
|
RtlFillMemoryUlong((PVOID) (pulDst+cLeft), cjFill, iColor);
|
|
|
|
// Lay down the right edge, if needed.
|
|
|
|
if (iRght != 0)
|
|
pulDst[cRght] = (pulDst[cRght] & ~ulMskRght) | (iColor & ulMskRght);
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidFillRow24
|
|
*
|
|
* Blt a list of adjacent rows to a 24 bpp DIB.
|
|
*
|
|
* History:
|
|
* 12-Oct-1993 -by- Eric Kutter [erick]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidFillRow24(
|
|
PROW prow,
|
|
ULONG crow,
|
|
LONG yTop,
|
|
PBYTE pjBits,
|
|
ULONG iColor,
|
|
LONG lDelta,
|
|
ULONG cShift)
|
|
{
|
|
BYTE jRed, jGreen, jBlue;
|
|
|
|
jRed = (BYTE) iColor;
|
|
jGreen = (BYTE) (iColor >> 8);
|
|
jBlue = (BYTE) (iColor >> 16);
|
|
|
|
pjBits += (yTop * lDelta);
|
|
|
|
for (UINT i = 0; i < crow; i++, prow++, pjBits += lDelta)
|
|
{
|
|
LONG cx = (prow->right - prow->left) << cShift;
|
|
ULONG xDstStart = prow->left << cShift;
|
|
BYTE* pjDst = pjBits + (3 * xDstStart);
|
|
|
|
ULONG cxTemp = cx;
|
|
|
|
while(cxTemp--)
|
|
{
|
|
*(pjDst++) = jRed;
|
|
*(pjDst++) = jGreen;
|
|
*(pjDst++) = jBlue;
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidXorRow1
|
|
*
|
|
* Does an xor blt of a list of adjacent rows to a DIB or 1, 4, 8, 16 or 32 bpp.
|
|
*
|
|
* History:
|
|
* 12-Oct-1993 -by- Eric Kutter [erick]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidXorRow1(
|
|
PROW prow,
|
|
ULONG crow,
|
|
LONG yTop,
|
|
PBYTE pjBits,
|
|
ULONG iColor,
|
|
LONG lDelta,
|
|
ULONG cShift)
|
|
{
|
|
pjBits += yTop * lDelta;
|
|
|
|
for (UINT i = 0; i < crow; i++, prow++,pjBits += lDelta)
|
|
{
|
|
ULONG* pulDst = (ULONG *) pjBits;
|
|
LONG cx = (prow->right - prow->left) << cShift;
|
|
ULONG xDstStart = prow->left << cShift;
|
|
|
|
ULONG ulMskLeft;
|
|
ULONG ulMskRght;
|
|
ULONG iLeft;
|
|
ULONG iRght;
|
|
ULONG cLeft;
|
|
ULONG cRght;
|
|
ULONG culFill;
|
|
BOOL bSimple = FALSE;
|
|
|
|
cLeft = xDstStart >> 5; // Index of leftmost DWORD
|
|
cRght = (xDstStart + cx) >> 5; // Index of rightmost DWORD
|
|
|
|
iLeft = xDstStart & 31; // Bits used in leftmost DWORD
|
|
iRght = (xDstStart + cx) & 31; // Bits used in rightmost DWORD
|
|
|
|
ulMskLeft = aulMsk[iLeft];
|
|
ulMskRght = ~aulMsk[iRght];
|
|
|
|
// If the leftmost and rightmost DWORDs are the same, then only one
|
|
// strip is needed. Merge the two masks together and note this.
|
|
|
|
if (cLeft == cRght)
|
|
{
|
|
ulMskLeft &= ulMskRght;
|
|
bSimple = TRUE;
|
|
}
|
|
|
|
// Lay down the left edge, if needed.
|
|
|
|
if (bSimple || (iLeft != 0))
|
|
{
|
|
ulMskLeft &= iColor;
|
|
|
|
pulDst[cLeft] ^= ulMskLeft;
|
|
|
|
if (bSimple)
|
|
continue;
|
|
|
|
cLeft++;
|
|
}
|
|
|
|
// Lay down the center strip, if needed.
|
|
|
|
culFill = cRght - cLeft;
|
|
|
|
if (culFill != 0)
|
|
{
|
|
PULONG pulTmp = pulDst + cLeft;
|
|
cx = culFill;
|
|
while (cx--)
|
|
*pulTmp++ ^= iColor;
|
|
}
|
|
|
|
// Lay down the right edge, if needed.
|
|
|
|
if (iRght != 0)
|
|
{
|
|
ulMskRght &= iColor;
|
|
|
|
pulDst[cRght] ^= ulMskRght;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSolidXorRow24
|
|
*
|
|
* Does a solid blt with a list of adjacent rows to a 24 bpp DIB.
|
|
*
|
|
* History:
|
|
* 12-Oct-1993 -by- Eric Kutter [erick]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSolidXorRow24(
|
|
PROW prow,
|
|
ULONG crow,
|
|
LONG yTop,
|
|
PBYTE pjBits,
|
|
ULONG iColor,
|
|
LONG lDelta,
|
|
ULONG cShift)
|
|
{
|
|
BYTE jRed, jGreen, jBlue;
|
|
|
|
jRed = (BYTE) iColor;
|
|
jGreen = (BYTE) (iColor >> 8);
|
|
jBlue = (BYTE) (iColor >> 16);
|
|
pjBits += yTop * lDelta;
|
|
|
|
for (UINT i = 0; i < crow; i++, prow++, pjBits += lDelta)
|
|
{
|
|
LONG cx = (prow->right - prow->left) << cShift;
|
|
ULONG xDstStart = prow->left << cShift;
|
|
BYTE* pjDst = pjBits + (3 * xDstStart);
|
|
|
|
ULONG cxTemp = cx;
|
|
|
|
while(cxTemp--)
|
|
{
|
|
*(pjDst++) ^= jRed;
|
|
*(pjDst++) ^= jGreen;
|
|
*(pjDst++) ^= jBlue;
|
|
}
|
|
}
|
|
}
|