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.
1425 lines
37 KiB
1425 lines
37 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: srcblt1.cxx
|
|
*
|
|
* This contains the bitmap simulation functions that blt to a 1 bit/pel
|
|
* DIB surface.
|
|
*
|
|
* Created: 07-Feb-1991 19:27:49
|
|
* Author: Patrick Haluptzok patrickh
|
|
*
|
|
* Copyright (c) 1990-1999 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
/*******************Public*Routine*****************\
|
|
* vSrcCopyS1D1LtoR
|
|
*
|
|
* There are three main loops in this function.
|
|
*
|
|
* The first loop deals with the full bytes part of
|
|
* the Dst while fetching/shifting the matching 8 bits
|
|
* from the Src.
|
|
*
|
|
* The second loop deals with the left most strip
|
|
* of the partial bytes.
|
|
*
|
|
* The third loop deals with the right most strip
|
|
* of the partial bytes.
|
|
*
|
|
* Special case:
|
|
* when the Src and Dst are aligned, we enter
|
|
* a different loop to use rltcopymem to avoid
|
|
* shifting
|
|
*
|
|
* History:
|
|
* 17-Oct-1994 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
*
|
|
\**************************************************/
|
|
|
|
|
|
VOID vSrcCopyS1D1LtoR(PBLTINFO psb)
|
|
{
|
|
BYTE jSrc; // holds a source byte
|
|
BYTE jDst; // holds a dest byte
|
|
INT iSrc; // bit position in the first Src byte
|
|
INT iDst; // bit position in the first Dst byte
|
|
INT ixlate; // set flag to indicate if it is
|
|
// source invert, source copy or
|
|
// all 0's or all 1's
|
|
PBYTE pjDst; // pointer to the Src bytes
|
|
PBYTE pjSrc; // pointer to the Dst bytes
|
|
PBYTE pjLDst; // pointer to the last Dst byte
|
|
LONG xSrcEnd = psb->xSrcEnd;
|
|
LONG cy; // number of pixels
|
|
LONG cx; // number of rows
|
|
BYTE jAlignL; // alignment bits to the left
|
|
BYTE jAlignR; // alignment bits to the right
|
|
BYTE jMask; // Masks used for shifting
|
|
BYTE jEndMask;
|
|
LONG cFullBytes; //number of full bytes to deal with
|
|
BOOL bNextByte;
|
|
LONG xDstEnd;
|
|
LONG lDeltaDst;
|
|
LONG lDeltaSrc;
|
|
BOOL bNextSrc = TRUE;
|
|
|
|
// We assume we are doing left to right top to bottom blting
|
|
ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D1LtoR - direction not left to right");
|
|
ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
|
|
|
|
//DbgPrint ("vsrccopys1d1ltor\n");
|
|
|
|
// if ixlate is 0x00, all 0's
|
|
// if ixlate is 0x01, src copy
|
|
// if ixlate is 0x10, src invert
|
|
// if ixlate is 0x11, all 1's
|
|
|
|
ixlate = (psb->pxlo->pulXlate[0]<<1) | psb->pxlo->pulXlate[1];
|
|
|
|
//Get Src and Dst start positions
|
|
iSrc = psb->xSrcStart & 0x0007;
|
|
iDst = psb->xDstStart & 0x0007;
|
|
|
|
// Checking alignment
|
|
|
|
// If Src starting point is ahead of Dst
|
|
if (iSrc < iDst)
|
|
jAlignL = 8 - (iDst - iSrc);
|
|
// If Dst starting point is ahead of Src
|
|
else
|
|
jAlignL = iSrc - iDst;
|
|
|
|
//jAlignR = (8 - jAlignL) & 0x07;
|
|
jAlignR = 8 - jAlignL;
|
|
|
|
cx=psb->cx;
|
|
|
|
xDstEnd = psb->xDstStart + cx;
|
|
|
|
lDeltaDst = psb->lDeltaDst;
|
|
lDeltaSrc = psb->lDeltaSrc;
|
|
|
|
//check if there is a next byte
|
|
bNextByte = !((xDstEnd>>3) ==
|
|
(psb->xDstStart>>3));
|
|
|
|
// The following loop is the inner loop part
|
|
// where we deals with a byte at a time
|
|
// when this main part is done, we deal
|
|
// with the begin and end partial bytes
|
|
//
|
|
// if Src and Dst are aligned, use a separete loop
|
|
// to obtain better performance;
|
|
// If not, we shift the Src bytes to match with
|
|
// the Dst byte one at a time
|
|
|
|
if (bNextByte)
|
|
{
|
|
long iStrideSrc;
|
|
long iStrideDst;
|
|
PBYTE pjSrcEnd;
|
|
|
|
//Get first Dst full byte
|
|
pjDst = psb->pjDst + ((psb->xDstStart+7)>>3);
|
|
|
|
//Get the Src byte that matches the first Dst
|
|
// full byte
|
|
pjSrc = psb->pjSrc + ((psb->xSrcStart+((8-iDst)&0x07)) >> 3);
|
|
|
|
//Get last full byte
|
|
pjLDst = psb->pjDst + (xDstEnd>>3);
|
|
|
|
//Get the number of full bytes
|
|
|
|
// Sundown: xSrcStart and xSrcEnd are both LONG, safe to truncate
|
|
|
|
cFullBytes = (ULONG)(pjLDst - pjDst);
|
|
|
|
//the increment to the full byte on the next scan line
|
|
|
|
iStrideDst = lDeltaDst - cFullBytes;
|
|
iStrideSrc = lDeltaSrc - cFullBytes;
|
|
|
|
// deal with our special case
|
|
cy = psb->cy;
|
|
|
|
if (!jAlignL || (ixlate == 0) || (ixlate == 3))
|
|
{
|
|
BYTE jConstant;
|
|
|
|
switch (ixlate)
|
|
{
|
|
case 0:
|
|
case 3:
|
|
jConstant = (!ixlate)?0:0xFF;
|
|
|
|
while (cy--)
|
|
{
|
|
int i;
|
|
|
|
i = cFullBytes;
|
|
|
|
while (i--)
|
|
*pjDst++ = jConstant;
|
|
|
|
//move to the beginning full byte
|
|
// on the next scan line
|
|
|
|
pjDst += iStrideDst;
|
|
pjSrc += iStrideSrc;
|
|
};
|
|
break;
|
|
case 1:
|
|
while (cy--)
|
|
{
|
|
RtlCopyMemory(pjDst,pjSrc,cFullBytes);
|
|
|
|
// move to the beginning full byte
|
|
// on the next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
};
|
|
break;
|
|
|
|
case 2:
|
|
while (cy--)
|
|
{
|
|
int i;
|
|
|
|
i = cFullBytes;
|
|
|
|
while (i--)
|
|
*pjDst++ = ~*pjSrc++;
|
|
|
|
//move to the beginning full byte
|
|
// on the next scan line
|
|
|
|
pjDst += iStrideDst;
|
|
pjSrc += iStrideSrc;
|
|
};
|
|
break;
|
|
|
|
|
|
default:;
|
|
} //switch
|
|
} //end of if (!jAlignL)
|
|
|
|
else
|
|
// if neither aligned nor all 0's or all 1's
|
|
{
|
|
BYTE jRem; //remainder
|
|
|
|
switch (ixlate)
|
|
{
|
|
case 1:
|
|
while (cy--)
|
|
{
|
|
jRem = *pjSrc << jAlignL;
|
|
|
|
pjSrcEnd = pjSrc+cFullBytes;
|
|
|
|
while (pjSrc != pjSrcEnd)
|
|
{
|
|
jSrc = *(++pjSrc);
|
|
jDst = (jSrc>>jAlignR) | jRem;
|
|
*pjDst++ = jDst;
|
|
|
|
//next remainder
|
|
jRem = jSrc << jAlignL;
|
|
}
|
|
|
|
// go to the beginging full byte of
|
|
// next scan line
|
|
pjDst += iStrideDst;
|
|
pjSrc += iStrideSrc;
|
|
|
|
};
|
|
break;
|
|
|
|
case 2:
|
|
while (cy--)
|
|
{
|
|
jRem = *pjSrc << jAlignL;
|
|
|
|
pjSrcEnd = pjSrc+cFullBytes;
|
|
|
|
while (pjSrc != pjSrcEnd)
|
|
{
|
|
jSrc = *(++pjSrc);
|
|
jDst = (jSrc>>jAlignR) | jRem;
|
|
*pjDst++ = ~jDst;
|
|
|
|
//next remainder
|
|
jRem = jSrc << jAlignL;
|
|
}
|
|
|
|
// go to the beginging full byte of
|
|
// next scan line
|
|
pjDst += iStrideDst;
|
|
pjSrc += iStrideSrc;
|
|
|
|
}; //while
|
|
break;
|
|
|
|
default: ;
|
|
} //switch
|
|
} //else
|
|
} //if
|
|
// End of our dealing with the full bytes
|
|
|
|
//build our masks
|
|
jMask = 0xFF >> iDst;
|
|
|
|
// if there are only one partial left byte,
|
|
// the mask is special
|
|
// for example, when we have 00111000 for
|
|
// Dst
|
|
if (!bNextByte)
|
|
{
|
|
jEndMask = 0XFF << (8-(xDstEnd & 0x0007));
|
|
|
|
jMask = jMask & jEndMask;
|
|
|
|
bNextSrc = ((iSrc + cx) > 8);
|
|
|
|
}
|
|
|
|
// Begin dealing with the left strip of the first
|
|
// partial byte
|
|
// First check if there are any partial
|
|
// left byte. Otherwise don't bother
|
|
if (iDst | !bNextByte)
|
|
{
|
|
pjDst = psb->pjDst + (psb->xDstStart>>3);
|
|
pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
|
|
|
|
cy = psb->cy;
|
|
|
|
switch (ixlate)
|
|
{
|
|
case 0:
|
|
while (cy--)
|
|
{
|
|
*pjDst = *pjDst & ~jMask;
|
|
|
|
pjDst += lDeltaDst;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if (iSrc > iDst)
|
|
{
|
|
if (bNextSrc)
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc << jAlignL;
|
|
jSrc |= *(pjSrc+1) >> jAlignR;
|
|
|
|
jSrc &= jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
else //if !bNextSrc
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc << jAlignL;
|
|
|
|
jSrc &= jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
|
|
}
|
|
else if (iSrc < iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc >> jAlignR;
|
|
|
|
jSrc &= jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
|
|
}
|
|
else // iSrc = iDst
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc;
|
|
|
|
jSrc &= jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
if (iSrc > iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc << jAlignL;
|
|
jSrc |= *(pjSrc+1) >> jAlignR;
|
|
|
|
jSrc = ~jSrc & jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
//go to next scan line
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
else if (iSrc < iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc >> jAlignR;
|
|
|
|
jSrc = ~jSrc & jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
//go to next scan line
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
}
|
|
else // iSrc = iDst
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc;
|
|
|
|
jSrc = ~jSrc & jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
//go to next scan line
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
while (cy--)
|
|
{
|
|
*pjDst = *pjDst | jMask;
|
|
|
|
pjDst += lDeltaDst;
|
|
}
|
|
break;
|
|
|
|
default: ;
|
|
} //switch
|
|
} //if
|
|
|
|
// Begin dealing with the right edge
|
|
// of partial bytes
|
|
|
|
jMask = 0xFF >> ((BYTE)(psb->xDstStart+cx) & 0x0007);
|
|
|
|
// first check if there is any partial
|
|
// byte left
|
|
// and has next byte
|
|
|
|
if ((xDstEnd & 0x0007)
|
|
&& bNextByte)
|
|
{
|
|
// Get the last partial bytes on the
|
|
// scan line
|
|
|
|
pjDst = pjLDst;
|
|
|
|
// Get the Src byte that matches the
|
|
// right partial Dst byte
|
|
// since xSrcEnd always point one
|
|
// pixel after the last pixel, minus 1
|
|
// from it
|
|
pjSrc = psb->pjSrc + ((psb->xSrcEnd-1) >>3);
|
|
|
|
// Get the ending position in the last
|
|
// Src and Dst bytes
|
|
iSrc = (psb->xSrcEnd-1) & 0x0007;
|
|
iDst = (xDstEnd-1) & 0x0007;
|
|
|
|
cy = psb->cy;
|
|
|
|
switch (ixlate)
|
|
{
|
|
case 0:
|
|
while (cy--)
|
|
{
|
|
*pjDst &= jMask;
|
|
|
|
pjDst += lDeltaDst;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if (iSrc > iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc << jAlignL;
|
|
|
|
jSrc &= ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
//go to next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
else if (iSrc < iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *(pjSrc-1) << jAlignL;
|
|
|
|
jSrc |= *pjSrc >> jAlignR;
|
|
|
|
jSrc &= ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
//go to next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
}
|
|
else // iSrc = iDst
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc;
|
|
|
|
jSrc &= ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
//go to next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
if (iSrc > iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc << jAlignL;
|
|
|
|
jSrc = ~jSrc & ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
//go to next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
else if (iSrc < iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *(pjSrc-1) << jAlignL;
|
|
jSrc |= *pjSrc >> jAlignR;
|
|
|
|
jSrc = ~jSrc & ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
//go to next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
else // iSrc = iDst
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc;
|
|
|
|
jSrc = ~jSrc & ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
//go to next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
while (cy--)
|
|
{
|
|
*pjDst = *pjDst | ~jMask;
|
|
|
|
pjDst += lDeltaDst;
|
|
}
|
|
break;
|
|
|
|
default: ;
|
|
} //switch
|
|
} //if
|
|
}
|
|
|
|
/*******************Public*Routine*****************\
|
|
* vSrcCopyS1D1RtoL
|
|
*
|
|
* this function is only called when copy to the
|
|
* same surface and has overlapping.
|
|
*
|
|
* There are three main loops in this function.
|
|
*
|
|
* The first loop deals with the starting pixels on the
|
|
* right most partial bytes. This must
|
|
* come first because it is Right to Left and overlapping.
|
|
*
|
|
* The second loop deals with the full bytes part of
|
|
* the Dst while fetching/shifting the matching 8 bits
|
|
* from the Src.
|
|
*
|
|
* The third loop deals with the ending pixles on the
|
|
* left most partial bytes.
|
|
*
|
|
* Special case:
|
|
* when the Src and Dst are aligned, we enter
|
|
* a different loop to use RltMoveMem to avoid
|
|
* shifting. RltMoveMemory gurantee the overlapping
|
|
* parts to be correct.
|
|
*
|
|
* History:
|
|
* 26-Oct-1994 -by- Lingyun Wang [lingyunw]
|
|
* Wrote it.
|
|
|
|
\**************************************************/
|
|
|
|
|
|
|
|
VOID vSrcCopyS1D1RtoL(PBLTINFO psb)
|
|
{
|
|
BYTE jSrc; // holds a source byte
|
|
BYTE jDst; // holds a dest byte
|
|
INT iSrc; // bit position in the first Src byte
|
|
INT iDst; // bit position in the first Dst byte
|
|
PBYTE pjDst; // pointer to the Src bytes
|
|
PBYTE pjSrc; // pointer to the Dst bytes
|
|
PBYTE pjLDst; // pointer to the last Dst byte
|
|
LONG xSrcEnd = psb->xSrcEnd;
|
|
LONG cy; // number of pixels
|
|
LONG cx; // number of rows
|
|
BYTE jAlignL; // alignment bits to the left
|
|
BYTE jAlignR; // alignment bits to the right
|
|
BYTE jMask; // Masks used for shifting
|
|
BYTE jEndMask;
|
|
LONG cFullBytes; //number of full bytes to deal with
|
|
BOOL bNextByte;
|
|
LONG xDstEnd;
|
|
LONG lDeltaDst;
|
|
LONG lDeltaSrc;
|
|
BOOL bNextSrc = TRUE;
|
|
|
|
// We assume we are doing right to left top to bottom blting
|
|
ASSERTGDI(psb->xDir == -1, "vSrcCopyS1D1RtoL - direction not right to left");
|
|
ASSERTGDI(psb->cy != 0, "ERROR: Src Move cy == 0");
|
|
ASSERTGDI (psb->pxlo->pulXlate[0] == 0, "vSrcCopyS1D1RtoL - should be straight copy");
|
|
ASSERTGDI (psb->pxlo->pulXlate[1] == 1, "vSrcCopyS1D1RtoL - should be straight copy");
|
|
|
|
//DbgPrint ("vsrccopys1d1rtol\n");
|
|
|
|
//Get Src and Dst start positions
|
|
iSrc = psb->xSrcStart & 0x0007;
|
|
iDst = psb->xDstStart & 0x0007;
|
|
|
|
// Checking alignment
|
|
|
|
// If Src starting point is ahead of Dst
|
|
if (iSrc < iDst)
|
|
jAlignL = 8-(iDst - iSrc);
|
|
// If Dst starting point is ahead of Src
|
|
else
|
|
jAlignL = iSrc - iDst;
|
|
|
|
jAlignR = 8 - jAlignL;
|
|
|
|
cx=psb->cx;
|
|
|
|
xDstEnd = psb->xDstStart - cx;
|
|
|
|
lDeltaDst = psb->lDeltaDst;
|
|
lDeltaSrc = psb->lDeltaSrc;
|
|
|
|
//check if there is a next byte
|
|
bNextByte = !((xDstEnd>>3) ==
|
|
(psb->xDstStart>>3));
|
|
|
|
// prepare our mask for the beggining
|
|
// partial bytes (this is on the right
|
|
// hand side)
|
|
jMask = 0xFF << (7-(psb->xDstStart&0x07));
|
|
|
|
// if there are only one partial byte, the
|
|
// mask is special, for example, when
|
|
// we have 00111000 for dst.
|
|
if (!bNextByte)
|
|
{
|
|
jEndMask = 0XFF >> ((1+xDstEnd) & 0x0007);
|
|
|
|
jMask = jMask & jEndMask;
|
|
|
|
// test if src needs to go to 1 byte left
|
|
// for example, iSrc == 0, cx==1, does
|
|
// not need to fetch the byte to the left
|
|
if (iSrc < iDst)
|
|
bNextSrc = ((iSrc-cx) < -1);
|
|
|
|
}
|
|
// Dealing with the starting pixels
|
|
// first, since we are doing right
|
|
// to left.
|
|
|
|
if (((iDst+1)&0x07) | !bNextByte)
|
|
{
|
|
|
|
pjDst = psb->pjDst + (psb->xDstStart>>3);
|
|
pjSrc = psb->pjSrc + (psb->xSrcStart>>3);
|
|
|
|
cy = psb->cy;
|
|
|
|
if (iSrc > iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc << jAlignL;
|
|
|
|
jSrc = jSrc & jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
//go to next scan line
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
else if (iSrc < iDst)
|
|
{
|
|
if (bNextSrc)
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc >> jAlignR;
|
|
jSrc |= *(pjSrc-1) << jAlignL;
|
|
|
|
jSrc = jSrc & jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
//go to next scan line
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
else
|
|
// if there is no next src byte,
|
|
// accessing pjSrc-1 will cause
|
|
// access violation.
|
|
// this only happens on the starting
|
|
// partial byte when bNextByte is False
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc >> jAlignR;
|
|
|
|
jSrc = jSrc & jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
//go to next scan line
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
|
|
}
|
|
else // iSrc = iDst
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc;
|
|
|
|
jSrc = jSrc & jMask;
|
|
|
|
*pjDst = (*pjDst & (~jMask)) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// The following loop is the inner loop part
|
|
// where we deals with a byte at a time
|
|
// when this main part is done, we deal
|
|
// with the begin and end partial bytes
|
|
//
|
|
if (bNextByte)
|
|
{
|
|
long iStrideSrc;
|
|
long iStrideDst;
|
|
PBYTE pjSrcEnd;
|
|
|
|
//Get first Dst full byte
|
|
pjDst = psb->pjDst + ((psb->xDstStart-7)>>3);
|
|
|
|
//Get the Src byte that matches the first Dst
|
|
// full byte
|
|
pjSrc = psb->pjSrc + ((psb->xSrcStart-((iDst+1)&0x07))>>3);
|
|
|
|
//Get last byte
|
|
pjLDst = psb->pjDst + (xDstEnd>>3);
|
|
|
|
//Get the number of full bytes
|
|
|
|
// Sundown safe truncation
|
|
cFullBytes = (ULONG)(pjDst - pjLDst);
|
|
|
|
//the increment to the full byte on the next scan line
|
|
iStrideDst = lDeltaDst + cFullBytes;
|
|
iStrideSrc = lDeltaSrc + cFullBytes;
|
|
|
|
// deal with our special case
|
|
cy = psb->cy;
|
|
|
|
if (!jAlignL)
|
|
{
|
|
while (cy--)
|
|
{
|
|
RtlMoveMemory(pjDst-(cFullBytes-1),pjSrc-(cFullBytes-1),cFullBytes);
|
|
|
|
// move to the beginning full byte
|
|
// on the next scan line
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
} //end of if (!jAlignL)
|
|
else
|
|
{
|
|
BYTE jRem;
|
|
|
|
while (cy--)
|
|
{
|
|
jRem = *pjSrc >> jAlignR;
|
|
|
|
pjSrcEnd = pjSrc-cFullBytes;
|
|
|
|
while (pjSrc != pjSrcEnd)
|
|
{
|
|
jSrc = *(--pjSrc);
|
|
|
|
jDst = (jSrc<<jAlignL) | jRem;
|
|
|
|
*pjDst-- = jDst;
|
|
|
|
//next remainder
|
|
jRem = jSrc >> jAlignR;
|
|
}
|
|
|
|
// go to the beginging full byte of
|
|
// next scan line
|
|
pjDst += iStrideDst;
|
|
pjSrc += iStrideSrc;
|
|
|
|
}
|
|
}
|
|
} //if
|
|
|
|
// Begin dealing with the ending pixels
|
|
|
|
jMask = 0xFF << (8-((1+xDstEnd) & 0x0007));
|
|
|
|
// first check if there is any partial
|
|
// byte left
|
|
// and has next byte
|
|
|
|
if (((1+xDstEnd) & 0x0007)
|
|
&& bNextByte)
|
|
{
|
|
// Get the last partial bytes on the
|
|
// scan line
|
|
pjDst = pjLDst;
|
|
|
|
// Get the Src byte that matches the
|
|
// right partial Dst byte
|
|
//
|
|
pjSrc = psb->pjSrc + ((psb->xSrcEnd+1) >>3);
|
|
|
|
// Get the ending position in the last
|
|
// Src and Dst bytes
|
|
iSrc = (psb->xSrcEnd+1) & 0x0007;
|
|
iDst = (xDstEnd + 1)& 0x0007;
|
|
|
|
cy = psb->cy;
|
|
|
|
if (iSrc > iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc << jAlignL;
|
|
jSrc |= *(pjSrc+1) >> jAlignR;
|
|
|
|
jSrc &= ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
else if (iSrc < iDst)
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc >> jAlignR;
|
|
|
|
jSrc &= ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
}
|
|
}
|
|
else // iSrc = iDst
|
|
{
|
|
while (cy--)
|
|
{
|
|
jSrc = *pjSrc;
|
|
|
|
jSrc &= ~jMask;
|
|
|
|
*pjDst = (*pjDst & jMask) | jSrc;
|
|
|
|
pjDst += lDeltaDst;
|
|
pjSrc += lDeltaSrc;
|
|
|
|
}
|
|
}
|
|
} //if
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSrcCopyS4D1
|
|
*
|
|
* Note we use pxlo to translate rather than looking at the foreground
|
|
* or background color. This is to keep the PM/Windows differences
|
|
* transparent to the blt code.
|
|
*
|
|
* History:
|
|
* 18-Feb-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSrcCopyS4D1(PBLTINFO psb)
|
|
{
|
|
// We assume we are doing left to right top to bottom blting
|
|
|
|
ASSERTGDI(psb->xDir == 1, "vSrcCopyS4D1 - direction not left to right");
|
|
ASSERTGDI(psb->yDir == 1, "vSrcCopyS4D1 - direction not up to down");
|
|
|
|
BYTE jSrc;
|
|
BYTE jDst;
|
|
LONG iSrc;
|
|
LONG iDst;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
|
|
PBYTE pjSrc = psb->pjSrc + (psb->xSrcStart >> 1);
|
|
ULONG cy = psb->cy;
|
|
PULONG pulXlate = psb->pxlo->pulXlate;
|
|
|
|
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
|
|
|
|
while(1)
|
|
{
|
|
// Initialize all the variables
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
|
|
iSrc = psb->xSrcStart;
|
|
iDst = psb->xDstStart;
|
|
|
|
// Set up the Src. Left to Right.
|
|
|
|
if (iSrc & 0x00000001)
|
|
jSrc = *(pjSrcTemp++);
|
|
|
|
// Set up the Dst. We just keep adding bits to the right and
|
|
// shifting left.
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We're gonna need some bits from the 1st byte of Dst.
|
|
|
|
jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
|
|
}
|
|
|
|
// Do the inner loop on a scanline
|
|
|
|
while(iSrc != psb->xSrcEnd)
|
|
{
|
|
jDst <<= 1;
|
|
|
|
if (iSrc & 0x00000001)
|
|
{
|
|
if (pulXlate[(jSrc & 0x0F)])
|
|
jDst |= 0x01;
|
|
}
|
|
else
|
|
{
|
|
jSrc = *(pjSrcTemp++);
|
|
|
|
if (pulXlate[((jSrc & 0xF0) >> 4)])
|
|
jDst |= 0x01;
|
|
}
|
|
|
|
iDst++;
|
|
iSrc++;
|
|
|
|
if (!(iDst & 0x07))
|
|
*(pjDstTemp++) = jDst;
|
|
}
|
|
|
|
// Clean up after the inner loop
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We need to build up the last pel correctly.
|
|
|
|
jSrc = (BYTE) (0x000000FF >> (iDst & 0x00000007));
|
|
|
|
jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
|
|
|
|
*pjDstTemp = (BYTE) ((*pjDstTemp & jSrc) | (jDst & ~jSrc));
|
|
}
|
|
|
|
// Check if we have anymore scanlines to do
|
|
|
|
if (--cy)
|
|
{
|
|
pjSrc += psb->lDeltaSrc;
|
|
pjDst += psb->lDeltaDst;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSrcCopyS8D1
|
|
*
|
|
* Note we use pxlo to translate rather than looking at the foreground
|
|
* or background color. This is to keep the PM/Windows differences
|
|
* transparent to the blt code.
|
|
*
|
|
* History:
|
|
* 18-Feb-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSrcCopyS8D1(PBLTINFO psb)
|
|
{
|
|
// We assume we are doing left to right top to bottom blting
|
|
|
|
ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D1 - direction not left to right");
|
|
ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D1 - direction not up to down");
|
|
|
|
BYTE jDst;
|
|
LONG iDst;
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
LONG xDstEnd = psb->xDstStart + psb->cx;
|
|
PULONG pulXlate = psb->pxlo->pulXlate;
|
|
PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
|
|
PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
|
|
ULONG cy = psb->cy;
|
|
BYTE jMask;
|
|
|
|
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
|
|
|
|
while(1)
|
|
{
|
|
// Initialize the variables
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
iDst = psb->xDstStart;
|
|
|
|
// Set up jDst. We just keep adding bits to the right and
|
|
// shifting left.
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We're gonna need some bits from the 1st byte of Dst.
|
|
|
|
jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
|
|
}
|
|
|
|
// Do the inner loop on a scanline
|
|
|
|
while(iDst != xDstEnd)
|
|
{
|
|
jDst <<= 1;
|
|
|
|
if (pulXlate[(*(pjSrcTemp++))])
|
|
jDst |= 0x01;
|
|
|
|
iDst++;
|
|
|
|
if (!(iDst & 0x07))
|
|
*(pjDstTemp++) = jDst;
|
|
}
|
|
|
|
// Clean up after the inner loop
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We need to build up the last pel correctly.
|
|
|
|
jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
|
|
|
|
jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
|
|
|
|
*pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
|
|
}
|
|
|
|
// Check if we have anymore scanlines to do
|
|
|
|
if (--cy)
|
|
{
|
|
pjSrc += psb->lDeltaSrc;
|
|
pjDst += psb->lDeltaDst;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSrcCopyS16D1
|
|
*
|
|
* Note we use pxlo to translate rather than looking at the foreground
|
|
* or background color. This is to keep the PM/Windows differences
|
|
* transparent to the blt code.
|
|
*
|
|
* History:
|
|
* 18-Feb-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSrcCopyS16D1(PBLTINFO psb)
|
|
{
|
|
// We assume we are doing left to right top to bottom blting
|
|
|
|
ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D1 - direction not left to right");
|
|
ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D1 - direction not up to down");
|
|
|
|
BYTE jDst;
|
|
LONG iDst;
|
|
PBYTE pjDstTemp;
|
|
PUSHORT pusSrcTemp;
|
|
LONG xDstEnd = psb->xDstStart + psb->cx;
|
|
XLATE *pxlo = (XLATE *) psb->pxlo;
|
|
PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
|
|
PUSHORT pusSrc = (PUSHORT) (psb->pjSrc + (psb->xSrcStart << 1));
|
|
ULONG cy = psb->cy;
|
|
BYTE jMask;
|
|
|
|
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
|
|
|
|
while(1)
|
|
{
|
|
// Initialize the variables
|
|
|
|
pjDstTemp = pjDst;
|
|
pusSrcTemp = pusSrc;
|
|
iDst = psb->xDstStart;
|
|
|
|
// Set up jDst. We just keep adding bits to the right and
|
|
// shifting left.
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We're gonna need some bits from the 1st byte of Dst.
|
|
|
|
jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
|
|
}
|
|
|
|
// Do the inner loop on a scanline
|
|
|
|
while(iDst != xDstEnd)
|
|
{
|
|
jDst <<= 1;
|
|
|
|
if (pxlo->ulTranslate(*(pusSrcTemp++)))
|
|
jDst |= 0x01;
|
|
|
|
iDst++;
|
|
|
|
if (!(iDst & 0x07))
|
|
*(pjDstTemp++) = jDst;
|
|
}
|
|
|
|
// Clean up after the inner loop
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We need to build up the last pel correctly.
|
|
|
|
jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
|
|
|
|
jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
|
|
|
|
*pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
|
|
}
|
|
|
|
// Check if we have anymore scanlines to do
|
|
|
|
if (--cy)
|
|
{
|
|
pusSrc = (PUSHORT) (((PBYTE) pusSrc) + psb->lDeltaSrc);
|
|
pjDst += psb->lDeltaDst;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSrcCopyS24D1
|
|
*
|
|
* Note we use pxlo to translate rather than looking at the foreground
|
|
* or background color. This is to keep the PM/Windows differences
|
|
* transparent to the blt code.
|
|
*
|
|
* History:
|
|
* 18-Feb-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSrcCopyS24D1(PBLTINFO psb)
|
|
{
|
|
// We assume we are doing left to right top to bottom blting
|
|
|
|
ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D1 - direction not left to right");
|
|
ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D1 - direction not up to down");
|
|
|
|
BYTE jDst;
|
|
LONG iDst;
|
|
ULONG ulDink; // variable to dink around with bytes
|
|
PBYTE pjDstTemp;
|
|
PBYTE pjSrcTemp;
|
|
LONG xDstEnd = psb->xDstStart + psb->cx;
|
|
XLATE *pxlo = (XLATE *) psb->pxlo;
|
|
PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
|
|
PBYTE pjSrc = psb->pjSrc + (psb->xSrcStart * 3);
|
|
ULONG cy = psb->cy;
|
|
BYTE jMask;
|
|
|
|
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
|
|
|
|
while(1)
|
|
{
|
|
// Initialize the variables
|
|
|
|
pjDstTemp = pjDst;
|
|
pjSrcTemp = pjSrc;
|
|
iDst = psb->xDstStart;
|
|
|
|
// Set up jDst. We just keep adding bits to the right and
|
|
// shifting left.
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We're gonna need some bits from the 1st byte of Dst.
|
|
|
|
jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
|
|
}
|
|
|
|
// Do the inner loop on a scanline
|
|
|
|
while(iDst != xDstEnd)
|
|
{
|
|
jDst <<= 1;
|
|
|
|
ulDink = *(pjSrcTemp + 2);
|
|
ulDink = ulDink << 8;
|
|
ulDink |= (ULONG) *(pjSrcTemp + 1);
|
|
ulDink = ulDink << 8;
|
|
ulDink |= (ULONG) *pjSrcTemp;
|
|
pjSrcTemp += 3;
|
|
|
|
if (pxlo->ulTranslate(ulDink))
|
|
jDst |= 0x01;
|
|
|
|
iDst++;
|
|
|
|
if (!(iDst & 0x07))
|
|
*(pjDstTemp++) = jDst;
|
|
}
|
|
|
|
// Clean up after the inner loop
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We need to build up the last pel correctly.
|
|
|
|
jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
|
|
|
|
jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
|
|
|
|
*pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
|
|
}
|
|
|
|
// Check if we have anymore scanlines to do
|
|
|
|
if (--cy)
|
|
{
|
|
pjSrc += psb->lDeltaSrc;
|
|
pjDst += psb->lDeltaDst;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSrcCopyS32D1
|
|
*
|
|
* Note we use pxlo to translate rather than looking at the foreground
|
|
* or background color. This is to keep the PM/Windows differences
|
|
* transparent to the blt code.
|
|
*
|
|
* History:
|
|
* 18-Feb-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSrcCopyS32D1(PBLTINFO psb)
|
|
{
|
|
// We assume we are doing left to right top to bottom blting
|
|
|
|
ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D1 - direction not left to right");
|
|
ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D1 - direction not up to down");
|
|
|
|
BYTE jDst;
|
|
LONG iDst;
|
|
PBYTE pjDstTemp;
|
|
PULONG pulSrcTemp;
|
|
LONG xDstEnd = psb->xDstStart + psb->cx;
|
|
XLATE *pxlo = (XLATE *) psb->pxlo;
|
|
PBYTE pjDst = psb->pjDst + (psb->xDstStart >> 3);
|
|
PULONG pulSrc = (PULONG) (psb->pjSrc + (psb->xSrcStart << 2));
|
|
ULONG cy = psb->cy;
|
|
BYTE jMask;
|
|
|
|
ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
|
|
|
|
while(1)
|
|
{
|
|
// Initialize the variables
|
|
|
|
pjDstTemp = pjDst;
|
|
pulSrcTemp = pulSrc;
|
|
iDst = psb->xDstStart;
|
|
|
|
// Set up jDst. We just keep adding bits to the right and
|
|
// shifting left.
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We're gonna need some bits from the 1st byte of Dst.
|
|
|
|
jDst = (BYTE) ( ((ULONG) (*pjDstTemp)) >> (8 - (iDst & 0x00000007)) );
|
|
}
|
|
|
|
// Do the inner loop on a scanline
|
|
|
|
while(iDst != xDstEnd)
|
|
{
|
|
jDst <<= 1;
|
|
|
|
if (pxlo->ulTranslate(*(pulSrcTemp++)))
|
|
jDst |= 0x01;
|
|
|
|
iDst++;
|
|
|
|
if (!(iDst & 0x07))
|
|
*(pjDstTemp++) = jDst;
|
|
}
|
|
|
|
// Clean up after the inner loop
|
|
|
|
if (iDst & 0x00000007)
|
|
{
|
|
// We need to build up the last pel correctly.
|
|
|
|
jMask = (BYTE) (0x000000FF >> (iDst & 0x00000007));
|
|
|
|
jDst = (BYTE) (jDst << (8 - (iDst & 0x00000007)));
|
|
|
|
*pjDstTemp = (BYTE) ((*pjDstTemp & jMask) | (jDst & ~jMask));
|
|
}
|
|
|
|
// Check if we have anymore scanlines to do
|
|
|
|
if (--cy)
|
|
{
|
|
pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
|
|
pjDst += psb->lDeltaDst;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|