public static void Blit(BitmapContext destContext, int dpw, int dph, Rect destRect, BitmapContext srcContext, Rect sourceRect, int sourceWidth)
{
const BlendMode blendMode = BlendMode.Alpha;
int dw = (int)destRect.Width;
int dh = (int)destRect.Height;
Rect intersect = new Rect(0, 0, dpw, dph);
intersect.Intersect(destRect);
if (intersect.IsEmpty)
{
return;
}
#if WPF
var isPrgba = srcContext.Format == PixelFormats.Pbgra32 || srcContext.Format == PixelFormats.Prgba64 || srcContext.Format == PixelFormats.Prgba128Float;
#endif
var sourcePixels = srcContext.Pixels;
var destPixels = destContext.Pixels;
int sourceLength = srcContext.Length;
int sourceIdx = -1;
int px = (int)destRect.X;
int py = (int)destRect.Y;
int x;
int y;
int idx;
double ii;
double jj;
int sr = 0;
int sg = 0;
int sb = 0;
int dr, dg, db;
int sourcePixel;
int sa = 0;
int da;
var sw = (int)sourceRect.Width;
var sdx = sourceRect.Width / destRect.Width;
var sdy = sourceRect.Height / destRect.Height;
int sourceStartX = (int)sourceRect.X;
int sourceStartY = (int)sourceRect.Y;
int lastii, lastjj;
lastii = -1;
lastjj = -1;
jj = sourceStartY;
y = py;
for (var j = 0; j < dh; j++)
{
if (y >= 0 && y < dph)
{
ii = sourceStartX;
idx = px + y * dpw;
x = px;
sourcePixel = sourcePixels[0];
// Pixel by pixel copying
for (var i = 0; i < dw; i++)
{
if (x >= 0 && x < dpw)
{
if ((int)ii != lastii || (int)jj != lastjj)
{
sourceIdx = (int)ii + (int)jj * sourceWidth;
if (sourceIdx >= 0 && sourceIdx < sourceLength)
{
sourcePixel = sourcePixels[sourceIdx];
sa = ((sourcePixel >> 24) & 0xff);
sr = ((sourcePixel >> 16) & 0xff);
sg = ((sourcePixel >> 8) & 0xff);
sb = ((sourcePixel) & 0xff);
}
else
{
sa = 0;
}
}
if (sa > 0)
{
int destPixel = destPixels[idx];
da = ((destPixel >> 24) & 0xff);
if ((sa == 255 || da == 0))
{
destPixels[idx] = sourcePixel;
}
else
{
dr = ((destPixel >> 16) & 0xff);
dg = ((destPixel >> 8) & 0xff);
db = ((destPixel) & 0xff);
var isa = 255 - sa;
#if NETFX_CORE
// Special case for WinRT since it does not use pARGB (pre-multiplied alpha)
destPixel = ((da & 0xff) << 24) |
((((sr * sa + isa * dr) >> 8) & 0xff) << 16) |
((((sg * sa + isa * dg) >> 8) & 0xff) << 8) |
(((sb * sa + isa * db) >> 8) & 0xff);
#elif WPF
if (isPrgba)
{
destPixel = ((da & 0xff) << 24) |
(((((sr << 8) + isa * dr) >> 8) & 0xff) << 16) |
(((((sg << 8) + isa * dg) >> 8) & 0xff) << 8) |
((((sb << 8) + isa * db) >> 8) & 0xff);
}
else
{
destPixel = ((da & 0xff) << 24) |
(((((sr * sa) + isa * dr) >> 8) & 0xff) << 16) |
(((((sg * sa) + isa * dg) >> 8) & 0xff) << 8) |
((((sb * sa) + isa * db) >> 8) & 0xff);
}
#else
destPixel = ((da & 0xff) << 24) |
(((((sr << 8) + isa * dr) >> 8) & 0xff) << 16) |
(((((sg << 8) + isa * dg) >> 8) & 0xff) << 8) |
((((sb << 8) + isa * db) >> 8) & 0xff);
#endif
destPixels[idx] = destPixel;
}
}
}
x++;
idx++;
ii += sdx;
}
}
jj += sdy;
y++;
}
}