📄 gperotate.cpp
字号:
case 0x33: src.Value = ~src.Value; break; // NOTSRCCOPY
case 0x44: src.Value &= ~dst.Value; break; // SRCERASE
case 0x55: src.Value = ~dst.Value; break; // DSTINVERT
case 0x5A: src.Value = brush.Value ^ dst.Value; break; // PATINVERT
case 0x66: src.Value ^= dst.Value; break; // SRCINVERT
case 0x88: src.Value &= dst.Value; break; // SRCAND
case 0xBB: src.Value = ~src.Value | dst.Value; break; // MERGEPAINT
case 0xC0: src.Value &= brush.Value; break; // MERGECOPY
case 0xEE: src.Value |= dst.Value; break; // SRCPAINT
case 0xF0: src.Value = brush.Value; break; // PATCOPY
case 0xFB: src.Value = brush.Value | ~src.Value | dst.Value; break; // PATPAINT
case 0xFF: src.Value = 0xFFFFFFFF; break; // WHITENESS
case 0xE2: src.Value = ( dst.Value & ~src.Value ) | ( brush.Value & src.Value ); break;
case 0xAC: src.Value = ((src.Value^dst.Value)&brush.Value)^src.Value; break;
default: src.Value = ProcessROP3(dst.Value,src.Value,brush.Value,rop3,dst.Bpp);
}
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
// Perform the AlphaBlend
if (alphaBlend)
{
ULONG SrcRed;
ULONG SrcGreen;
ULONG SrcBlue;
ULONG SrcAlpha;
ULONG DstRed;
ULONG DstGreen;
ULONG DstBlue;
ULONG DstAlpha;
BYTE Alpha = pParms->blendFunction.SourceConstantAlpha;
ULONG PalEntries = 0;
ULONG * pPalette = NULL;
int AlphaType = 0;
// If the surface has a palette, get the BGR value of the
// color.
if (BlendPalette)
{
pPalette = pParms->pDst->FormatPtr()->m_pPalette;
PalEntries = pParms->pDst->FormatPtr()->m_PaletteEntries;
// The mask isn't always applied to the destination value.
dst.Value &= dst.Mask;
ASSERT(src.Value < PalEntries);
ASSERT(dst.Value < PalEntries);
src.Value = pPalette[src.Value];
dst.Value = pPalette[dst.Value];
}
SrcRed = (src.Value & RedMask) >> RedShift;
SrcGreen = (src.Value & GreenMask) >> GreenShift;
SrcBlue = (src.Value & BlueMask) >> BlueShift;
SrcAlpha = (src.Value & AlphaMask) >> AlphaShift;
DstRed = (dst.Value & RedMask) >> RedShift;
DstGreen = (dst.Value & GreenMask) >> GreenShift;
DstBlue = (dst.Value & BlueMask) >> BlueShift;
DstAlpha = (dst.Value & AlphaMask) >> AlphaShift;
// Figure out which of the three alpha blending functions
// needs to be used.
if (pParms->blendFunction.AlphaFormat)
{
SrcAlpha = originalSrc & SrcAlphaMask;
SrcAlpha >>= SrcAlphaShift;
if (SrcAlpha == 0)
{
// Just the dst.
src.Value = (DstRed << 16) |
(DstGreen << 8) |
(DstBlue ) |
(DstAlpha << 24);
}
else if (SrcAlpha == 255 && Alpha == 255)
{
// Just the src.
src.Value = (SrcRed << 16) |
(SrcGreen << 8) |
(SrcBlue ) |
(SrcAlpha << 24);
}
else if (SrcAlpha == 255)
{
// Source constant alpha only.
AlphaType = 1;
}
else
{
if (Alpha == 255)
{
AlphaType = 2; // Per-pixel only
}
else
{
AlphaType = 3; // Both;
}
}
}
else
{
AlphaType = 1;
}
// Perform the alpha blend.
if (AlphaType == 3)
{
// Both Per-Pixel and Constant Alpha
ULONG uB00aa00gg = (SrcAlpha << 16) | SrcGreen;
ULONG uB00rr00bb = (SrcRed << 16) | SrcBlue;
ULONG uTaaaagggg = uB00aa00gg * Alpha + 0x00800080;
ULONG uTrrrrbbbb = uB00rr00bb * Alpha + 0x00800080;
ULONG uT00aa00gg = (uTaaaagggg & 0xff00ff00) >> 8;
ULONG uT00rr00bb = (uTrrrrbbbb & 0xff00ff00) >> 8;
ULONG uCaa00gg00 = ((uTaaaagggg + uT00aa00gg) & 0xff00ff00);
ULONG uC00rr00bb = ((uTrrrrbbbb + uT00rr00bb) & 0xff00ff00) >> 8;
src.Value = uCaa00gg00 | uC00rr00bb;
BYTE beta = 255 - (BYTE)((src.Value & 0xff000000) >> 24);
ULONG _D1_00aa00gg = (DstAlpha << 16) | DstGreen;
ULONG _D1_00rr00bb = (DstRed << 16) | DstBlue;
ULONG _D2_aaaagggg = _D1_00aa00gg * beta + 0x00800080;
ULONG _D2_rrrrbbbb = _D1_00rr00bb * beta + 0x00800080;
ULONG _D3_00aa00gg = (_D2_aaaagggg & 0xff00ff00) >> 8;
ULONG _D3_00rr00bb = (_D2_rrrrbbbb & 0xff00ff00) >> 8;
ULONG _D4_00aa00gg = ((_D2_aaaagggg + _D3_00aa00gg) & 0xff00ff00) >> 8;
ULONG _D4_00rr00bb = ((_D2_rrrrbbbb + _D3_00rr00bb) & 0xff00ff00) >> 8;
ULONG _D5_00aa00gg = _D4_00aa00gg + ((src.Value & 0xff00ff00) >> 8);
ULONG _D5_00rr00bb = _D4_00rr00bb + (src.Value & 0x00ff00ff);
// Saturate the ARGB values.
ULONG TempMask = (AlphaMask >> AlphaShift) << 16;
if ((_D5_00aa00gg & 0xffff0000) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x0000ffff);
}
TempMask = GreenMask >> GreenShift;
if ((_D5_00aa00gg & 0x0000ffff) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x00ff0000);
}
TempMask = (RedMask >> RedShift) << 16;
if ((_D5_00rr00bb & 0xffff0000) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x0000ffff);
}
TempMask = BlueMask >> BlueShift;
if ((_D5_00rr00bb & 0x0000ffff) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x00ff0000);
}
src.Value = (_D5_00aa00gg << 8) | _D5_00rr00bb;
}
else if (AlphaType == 2)
{
// Per-Pixel Only
ULONG Multa = 255 - SrcAlpha;
ULONG _D1_00aa00gg = (DstAlpha << 16) | DstGreen;
ULONG _D1_00rr00bb = (DstRed << 16) | DstBlue;
ULONG _D2_aaaagggg = _D1_00aa00gg * Multa + 0x00800080;
ULONG _D2_rrrrbbbb = _D1_00rr00bb * Multa + 0x00800080;
ULONG _D3_00aa00gg = (_D2_aaaagggg & 0xff00ff00) >> 8;
ULONG _D3_00rr00bb = (_D2_rrrrbbbb & 0xff00ff00) >> 8;
ULONG _D4_00aa00gg = ((_D2_aaaagggg + _D3_00aa00gg) & 0xff00ff00) >> 8;
ULONG _D4_00rr00bb = ((_D2_rrrrbbbb + _D3_00rr00bb) & 0xff00ff00) >> 8;
ULONG _D5_00aa00gg = _D4_00aa00gg + ((SrcAlpha << 16) | SrcGreen);
ULONG _D5_00rr00bb = _D4_00rr00bb + ((SrcRed << 16) | SrcBlue);
// Saturate the ARGB values.
ULONG TempMask = (AlphaMask >> AlphaShift) << 16;
if ((_D5_00aa00gg & 0xffff0000) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x0000ffff);
}
TempMask = GreenMask >> GreenShift;
if ((_D5_00aa00gg & 0x0000ffff) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x00ff0000);
}
TempMask = (RedMask >> RedShift) << 16;
if ((_D5_00rr00bb & 0xffff0000) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x0000ffff);
}
TempMask = BlueMask >> BlueShift;
if ((_D5_00rr00bb & 0x0000ffff) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x00ff0000);
}
src.Value = (_D5_00aa00gg << 8) | _D5_00rr00bb;
}
else if (AlphaType == 1)
{
// Constant Alpha Only
// red and blue
ULONG uB00rr00bb = (DstRed << 16) | DstBlue;
ULONG uF00rr00bb = (SrcRed << 16) | SrcBlue;
ULONG uMrrrrbbbb = ((uB00rr00bb << 8) - uB00rr00bb)
+ (Alpha * (uF00rr00bb - uB00rr00bb)) + 0x00800080;
ULONG uM00rr00bb = (uMrrrrbbbb & 0xff00ff00) >> 8;
ULONG uD00rr00bb = ((uMrrrrbbbb + uM00rr00bb) & 0xff00ff00) >> 8;
// alpha and green
ULONG uB00aa00gg = (DstAlpha << 16) | DstGreen;
ULONG uF00aa00gg = (SrcAlpha << 16) | SrcGreen;
ULONG uMaaaagggg = ((uB00aa00gg << 8) - uB00aa00gg)
+ (Alpha * (uF00aa00gg - uB00aa00gg)) + 0x00800080;
ULONG uM00aa00gg = (uMaaaagggg & 0xff00ff00) >> 8;
ULONG uDaa00gg00 = (uMaaaagggg + uM00aa00gg) & 0xff00ff00;
src.Value = uD00rr00bb + uDaa00gg00;
}
// Convert src.Value back to the appropriate format;
SrcBlue = (src.Value & 0x000000ff) << BlueShift;
SrcGreen = ((src.Value & 0x0000ff00) >> 8) << GreenShift;
SrcRed = ((src.Value & 0x00ff0000) >> 16) << RedShift;
SrcAlpha = ((src.Value & 0xff000000) >> 24) << AlphaShift;
src.Value = ((SrcRed & RedMask)
| (SrcGreen & GreenMask)
| (SrcBlue & BlueMask)
| (SrcAlpha & AlphaMask));
// If the destination surface has a palette, src.Value must
// be converted to a palette index.
if (BlendPalette)
{
ULONG Error = RGBError(src.Value, pPalette[0]);
ULONG Index = 0;
for (ULONG i = 1; i < PalEntries; i++)
{
ULONG TempErr = RGBError(src.Value, pPalette[i]);
if (TempErr < Error)
{
Error = TempErr;
Index = i;
}
}
src.Value = Index;
}
}
#endif /* (_WINCEOSVER >= 500) */
src.Value &= dst.Mask;
if( rop3 == 0xAA || ( transparentBlt && ( originalSrc == transparentColor ) ) )
{
// we won't write this pixel
if (dst.IsRotate)
dst.CurrentCoord.x += dst.ColIncrement;
else
{
if( quickWrite )
dst.Ptr += dst.BytesPerAccess;
else
{
dst.CacheState += dst.CacheStateIncrement; // leave dirty flag as-is
if( !(dst.CacheState&0x00ff00) ) // Check bits remaining in dst cache
{
if( dst.CacheState & 0x0000ff )
*(unsigned long *)dst.Ptr = dst.Cache; // flush cache
dst.CacheState = dst.CacheStateNewDWord; // clears dirty flag
dst.Ptr += dst.BytesPerAccess; // +/- 4
dst.Cache = *(unsigned long *)dst.Ptr;
}
}
}
continue;
}
}
// Now, we are ready to write the value from src.Value into the dst pixel
if (dst.IsRotate)
{
switch(dst.Bpp)
{
case 8:
*(unsigned char *)dst.GetPtr() = (unsigned char)src.Value;
break;
case 16:
*(unsigned short *)dst.GetPtr() = (unsigned short)src.Value;
break;
case 32:
*(unsigned long *)dst.GetPtr() = (unsigned long)src.Value;
break;
case 24:
unsigned char *ptr = dst.GetPtr();
*ptr = (unsigned char)(src.Value);
*(ptr+1) = (unsigned char)(src.Value>>8);
*(ptr+2) = (unsigned char)(src.Value>>16);
}
dst.CurrentCoord.x += dst.ColIncrement;
}
else
{
if( quickWrite )
{
switch(dst.Bpp)
{
case 8:
*(unsigned char *)dst.Ptr = (unsigned char)src.Value;
break;
case 16:
*(unsigned short *)dst.Ptr = (unsigned short)src.Value;
break;
case 32:
*(unsigned long *)dst.Ptr = (unsigned long)src.Value;
break;
case 24:
*dst.Ptr = (unsigned char)(src.Value);
*(dst.Ptr+1) = (unsigned char)(src.Value>>8);
*(dst.Ptr+2) = (unsigned char)(src.Value>>16);
}
dst.Ptr += dst.BytesPerAccess;
}
else
{
unsigned char tmpShift = (unsigned char)(( dst.CacheState >> 16 ) ^ dst.MaskShiftXor);
dst.Cache &= ~( dst.Mask << tmpShift);
dst.Cache |= src.Value << tmpShift;
dst.CacheState += dst.CacheStateIncrementDirty; // sets dirty flag
if( !(dst.CacheState&0x00ff00) ) // Check bits remaining in dst cache
{
*(UNALIGNED unsigned long *)dst.Ptr = dst.Cache; // flush cache (we know it was dirty)
dst.CacheState = dst.CacheStateNewDWord; // clears dirty flag
dst.Ptr += dst.BytesPerAccess; // +/- 4
if (x != width - 1 )
dst.Cache = *(UNALIGNED unsigned long *)dst.Ptr;
}
}
}
} // next column
if( dst.CacheState & 0x0000ff )
*(UNALIGNED unsigned long *)dst.Ptr = dst.Cache; // flush cache
} // next row
return S_OK;
}
#if defined (OSV_PPC) || ( defined (_WINCEOSVER) && (_WINCEOSVER >= 500))
#define FIX16_ONE 0x00010000
#define FIX16_MASK 0x0000FFFF
#define FIX16_SHIFT 16
SCODE GPERotate::EmulatedBltRotate_Bilinear( GPEBltParms *pParms)
{
int width = pParms->prclDst->right - pParms->prclDst->left;
int height = pParms->prclDst->bottom - pParms->prclDst->top;
int dstMatters = ((( pParms->rop4 >> 1 ) ^ pParms->rop4 ) & 0x5555) != 0;
int srcWidth = pParms->prclSrc->right - pParms->prclSrc->left;
int srcHeight = pParms->prclSrc->bottom - pParms->prclSrc->top;
int dstXStartSkip = 0;
int dstYStartSkip = 0;
int srcXStartSkip = 0;
int srcYStartSkip = 0;
unsigned int xratio = srcWidth * FIX16_ONE / width;
unsigned int yratio = srcHeight * FIX16_ONE / height;
unsigned int xstep = (xratio - FIX16_ONE) >> 1;
unsigned int ystep = (yratio - FIX16_ONE) >> 1;
unsigned char rop3 = (unsigned char)pParms->rop4;
ystep &= FIX16_MASK;
xstep &= FIX16_MASK;
if (pParms->prclClip)
{
RECTL rclClipped = *pParms->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;
}
// The clipped rect is empty.
if (rclClipped.right <= rclClipped.left
|| rclClipped.bottom <= rclClipped.top)
{
return S_OK;
}
dstXStartSkip = pParms->xPositive ? (rclClipped.left - pParms->prclDst->left) : (pParms->prclDst->right - rclClipped.right);
dstYStartSkip = pParms->yPositive ? (rclClipped.top - pParms->prclDst->top) : (pParms->prclDst->bottom - rclClipped.bottom);
width = rclClipped.right - rclClipped.left;
height = rclClipped.bottom - rclClipped.top;
}
int skipCount;
for (skipCount = dstXStartSkip; skipCount; skipCount--)
{
xstep += xratio;
srcXStartSkip += (xstep >> FIX16_SHIFT);
xstep &= FIX16_MASK;
}
for (skipCount = dstYStartSkip; skipCount; skipCount--)
{
ystep += yratio;
srcYStartSkip += (ystep >> FIX16_SHIFT);
ystep &= FIX16_MASK;
}
// The destination must be at least 16 bpp.
PixelIteratorRotate dst;
dst.Bpp = EGPEFormatToBpp[pParms->pDst->Format()];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -