📄 swblt.cpp
字号:
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
// Variables used for AlphaBlend.
ULONG RedMask;
ULONG GreenMask;
ULONG BlueMask;
ULONG AlphaMask;
ULONG RedShift;
ULONG GreenShift;
ULONG BlueShift;
ULONG AlphaShift;
ULONG SrcAlphaMask;
ULONG SrcAlphaShift;
BOOL BlendPalette = FALSE;
// If the BLENDFUNCTION isn't Null, the destination pixel value will need
// to be read.
int alphaBlend = 0;
if (*(DWORD *)&(pParms->blendFunction) != *(DWORD *)&g_NullBlendFunction)
{
// Get the format of the source and destination surfaces.
GPEFormat * pDstFormat = pParms->pDst->FormatPtr();
if (pDstFormat->m_PaletteEntries == 3)
{
RedMask = pDstFormat->m_pPalette[0];
GreenMask = pDstFormat->m_pPalette[1];
BlueMask = pDstFormat->m_pPalette[2];
AlphaMask = 0;
// If this is a 32 bpp surface, try to add an "implicit" Alpha mask.
if (EGPEFormatToBpp[pParms->pDst->Format()] == 32
&& !(0xFF000000 & (RedMask | GreenMask | BlueMask)))
{
AlphaMask = 0xFF000000;
}
}
else if (pDstFormat->m_PaletteEntries == 4 && EGPEFormatToBpp[pParms->pDst->Format()] > 8)
{
RedMask = pDstFormat->m_pPalette[0];
GreenMask = pDstFormat->m_pPalette[1];
BlueMask = pDstFormat->m_pPalette[2];
AlphaMask = pDstFormat->m_pPalette[3];
}
else
{
RedMask = 0x000000FF;
GreenMask = 0x0000FF00;
BlueMask = 0x00FF0000;
AlphaMask = 0xFF000000;
BlendPalette = TRUE;
}
// Compute the shifts for each mask.
ULONG bit;
ULONG Mask = RedMask;
for (bit = 0; Mask && !(Mask & 1); bit++)
{
Mask >>= 1;
}
RedShift = bit;
Mask = GreenMask;
for (bit = 0; Mask && !(Mask & 1); bit++)
{
Mask >>= 1;
}
GreenShift = bit;
Mask = BlueMask;
for (bit = 0; Mask && !(Mask & 1); bit++)
{
Mask >>= 1;
}
BlueShift = bit;
Mask = AlphaMask;
for (bit = 0; Mask && !(Mask & 1); bit++)
{
Mask >>= 1;
}
AlphaShift = bit;
// If this is a per-pixel blend, get the source alpha format.
if (pParms->blendFunction.AlphaFormat)
{
DWORD SavedSrcAlphaMask;
if (pParms->pSrc->FormatPtr()->m_PaletteEntries == 4)
{
SrcAlphaMask = pParms->pSrc->FormatPtr()->m_pPalette[3];
}
else if (pParms->pSrc->FormatPtr()->m_PaletteEntries == 3)
{
// If a fourth mask isn't provided, GDI guarantees that
// 0xFF000000 is a valid alpha mask.
SrcAlphaMask = 0xFF000000;
}
else
{
ASSERT(0);
}
SavedSrcAlphaMask = SrcAlphaMask;
SrcAlphaShift = 0;
while (!(SrcAlphaMask & 1))
{
SrcAlphaMask >>= 1;
SrcAlphaShift++;
}
SrcAlphaMask = SavedSrcAlphaMask;
}
dstMatters = 1;
alphaBlend = 1;
}
#endif /* Wince 500 */
// Handle improperly ordered prclDst resulting from stretch Blt
// Note that only prclDst is ever improperly ordered
if( width < 0 || height < 0 )
{
tmpRclDst = *prclDst;
prclDst = &tmpRclDst;
if( width < 0 )
{
SWAP( tmpRclDst.left, tmpRclDst.right, LONG )
width = -width;
dstXPositive = !dstXPositive;
}
if( height < 0 )
{
SWAP( tmpRclDst.top, tmpRclDst.bottom, LONG )
height = -height;
dstYPositive = !dstYPositive;
}
}
// prclDst is now properly ordered
if( pParms->bltFlags & BLT_STRETCH ) // Check for stretching or shrinking vertically &/or horizontally
{
srcWidth = pParms->prclSrc->right - pParms->prclSrc->left;
srcHeight = pParms->prclSrc->bottom - pParms->prclSrc->top;
if( width > srcWidth )
{
xStretch = 1;
xDMajor = width;
xDMinor = srcWidth;
}
else if( width < srcWidth )
{
xShrink = 1;
xDMajor = srcWidth;
xDMinor = width;
}
if( xStretch || xShrink)
{
xShrinkStretch = 1;
// Convert to Bresenham parameters
xDMinor *= 2;
xDMajor = xDMinor - 2 * xDMajor;
rowXAccum = xShrink?(2*width - srcWidth):(3*srcWidth - 2*width);
// loaded into xAccum at start of each row
}
if( height > srcHeight )
{
yStretch = 1;
yDMajor = height;
yDMinor = srcHeight;
}
else if( height < srcHeight )
{
yShrink = 1;
yDMajor = srcHeight;
yDMinor = height;
}
if( yStretch || yShrink)
{
yShrinkStretch = 1;
// Convert to Bresenham parameters
yDMinor *= 2;
yDMajor = yDMinor - 2 * yDMajor;
yAccum = yShrink?(2*height - srcHeight):(3*srcHeight - 2*height);
}
if( pParms->prclClip ) // ONLY happens if stretch blting
{
RECTL rclClipped = *prclDst;
if( rclClipped.left < pParms->prclClip->left )
{
rclClipped.left = pParms->prclClip->left;
}
if( rclClipped.top < pParms->prclClip->top )
{
rclClipped.top = pParms->prclClip->top;
}
if( rclClipped.bottom > pParms->prclClip->bottom )
{
rclClipped.bottom = pParms->prclClip->bottom;
}
if( rclClipped.right > pParms->prclClip->right )
{
rclClipped.right = pParms->prclClip->right;
}
if( rclClipped.right <= rclClipped.left || rclClipped.bottom <= rclClipped.top )
{
return S_OK; // the clipping left nothing to do
}
dstXStartSkip = dstXPositive?(rclClipped.left-prclDst->left):(prclDst->right-rclClipped.right);
dstYStartSkip = dstYPositive?(rclClipped.top-prclDst->top):(prclDst->bottom-rclClipped.bottom);
width = rclClipped.right - rclClipped.left; // Calculate fully clipped destination width
height = rclClipped.bottom - rclClipped.top; // Fully clipped height
}
if( xShrink )
{
while( rowXAccum < 0 )
{
rowXAccum += xDMinor;
srcXStartSkip++;
}
rowXAccum += xDMajor;
}
for( int skipCount = dstXStartSkip; skipCount; skipCount-- )
{
if( xShrink )
{
while( rowXAccum < 0 )
{
rowXAccum += xDMinor;
srcXStartSkip++;
}
srcXStartSkip++; // <--- this is the srcSkip inherent with a dstSkip
rowXAccum += xDMajor;
}
else if( xStretch )
{
if( rowXAccum < 0 )
{
rowXAccum += xDMinor;
}
else
{
rowXAccum += xDMajor;
srcXStartSkip++;
}
}
else
{
srcXStartSkip++;
}
}
if( yShrink )
{
yAccum += dstYStartSkip * yDMajor;
srcYStartSkip += dstYStartSkip; // <--- this is the srcSkip inherent with a dstSkip
}
else if( yStretch )
{
for( int skipCount = dstYStartSkip; skipCount; skipCount-- )
{
if( yAccum < 0 )
{
yAccum += yDMinor;
}
else
{
yAccum += yDMajor;
srcYStartSkip++;
}
}
}
else
{
srcYStartSkip += dstYStartSkip;
}
}
int transparentBlt = pParms->bltFlags & BLT_TRANSPARENT;
unsigned long transparentColor = pParms->solidColor;
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pSrc=0x%08x, pDst=0x%08x, pBrush=%08x, pMask=%08x\r\n"),
pParms->pSrc, pParms->pDst, pParms->pBrush, pParms->pMask ));
PixelIterator src, dst, mask;
BrushPixelIterator brush;
src.Ptr = src.RowPtr = mask.Ptr = mask.RowPtr = brush.Ptr = brush.RowPtr = (unsigned char *)0;
if( pParms->pSrc )
{
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pSrc depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pSrc->Format()] ) );
src.InitPixelIterator( pParms->pSrc, pParms->xPositive, pParms->yPositive, pParms->prclSrc,
srcXStartSkip, srcYStartSkip );
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
// If we're doing a transparent blt, we will need to know the real RGB
// masks.
if (transparentBlt)
{
GPEFormat * pFormat = pParms->pSrc->FormatPtr();
// Make sure we're dealing with a known format.
if (EGPEFormatToBpp[pParms->pSrc->Format()] > 8
&& (pFormat->m_PaletteEntries == 4
||pFormat->m_PaletteEntries == 3))
{
ULONG * pMasks = pFormat->m_pPalette;
SrcRGBMask = pMasks[0] | pMasks[1] | pMasks[2];
}
else
{
SrcRGBMask = src.Mask;
}
}
else
{
SrcRGBMask = src.Mask;
}
#endif
}
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pDst depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pDst->Format()] ) );
if( pParms->pBrush )
{
// Calculate an rclBrush so that the correct starting pixel is chosen for the brush iterator
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Pattern depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pBrush->Format()] ) );
int topIndent = (pParms->pptlBrush)?pParms->pBrush->Height()-pParms->pptlBrush->y:0;
int leftIndent = (pParms->pptlBrush)?pParms->pBrush->Width()-pParms->pptlBrush->x:0;
rclBrush.left = ( leftIndent + prclDst->left ) % pParms->pBrush->Width();
rclBrush.right = ( leftIndent + prclDst->right ) % pParms->pBrush->Width();
rclBrush.top = ( topIndent + prclDst->top ) % pParms->pBrush->Height();
rclBrush.bottom = ( topIndent + prclDst->bottom ) % pParms->pBrush->Height();
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pBrush depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pBrush->Format()] ) );
brush.InitBrushPixelIterator( pParms->pBrush, pParms->xPositive, pParms->yPositive, &rclBrush );
}
if( pParms->pMask )
{
mask.InitPixelIterator( pParms->pMask, pParms->xPositive, pParms->yPositive, pParms->prclMask,
srcXStartSkip, srcYStartSkip );
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -