* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$ */
+
#include <w32k.h>
+#define NDEBUG
+#include <debug.h>
+
VOID
DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
{
- PBYTE addr = SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
+ PBYTE addr = (PBYTE)SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
*(PUSHORT)(addr) = c & 0xFFFF;
*(addr + 2) = (c >> 16) & 0xFF;
}
ULONG
DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
{
- PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
+ PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
return *(PUSHORT)(addr) + (*(addr + 2) << 16);
}
VOID
DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
{
- PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
- LONG cx = x1;
-
- c &= 0xFFFFFF;
- while(cx < x2) {
- *(PUSHORT)(addr) = c & 0xFFFF;
- addr += 2;
- *(addr) = c >> 16;
- addr += 1;
- ++cx;
- }
+ PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
+ ULONG Count = x2 - x1;
+#ifndef _M_IX86
+ ULONG MultiCount;
+ ULONG Fill[3];
+#endif
+
+ if (Count < 8)
+ {
+ /* For small fills, don't bother doing anything fancy */
+ while (Count--)
+ {
+ *(PUSHORT)(addr) = c;
+ addr += 2;
+ *(addr) = c >> 16;
+ addr += 1;
+ }
+ }
+ else
+ {
+ /* Align to 4-byte address */
+ while (0 != ((ULONG_PTR) addr & 0x3))
+ {
+ *(PUSHORT)(addr) = c;
+ addr += 2;
+ *(addr) = c >> 16;
+ addr += 1;
+ Count--;
+ }
+ /* If the color we need to fill with is 0ABC, then the final mem pattern
+ * (note little-endianness) would be:
+ *
+ * |C.B.A|C.B.A|C.B.A|C.B.A| <- pixel borders
+ * |C.B.A.C|B.A.C.B|A.C.B.A| <- ULONG borders
+ *
+ * So, taking endianness into account again, we need to fill with these
+ * ULONGs: CABC BCAB ABCA */
+#ifdef _M_IX86
+ /* This is about 30% faster than the generic C code below */
+ __asm__ __volatile__ (
+" movl %1, %%ecx\n"
+" andl $0xffffff, %%ecx\n" /* 0ABC */
+" movl %%ecx, %%ebx\n" /* Construct BCAB in ebx */
+" shrl $8, %%ebx\n"
+" movl %%ecx, %%eax\n"
+" shll $16, %%eax\n"
+" orl %%eax, %%ebx\n"
+" movl %%ecx, %%edx\n" /* Construct ABCA in edx */
+" shll $8, %%edx\n"
+" movl %%ecx, %%eax\n"
+" shrl $16, %%eax\n"
+" orl %%eax, %%edx\n"
+" movl %%ecx, %%eax\n" /* Construct CABC in eax */
+" shll $24, %%eax\n"
+" orl %%ecx, %%eax\n"
+" movl %2, %%ecx\n" /* Load count */
+" shr $2, %%ecx\n"
+" movl %3, %%edi\n" /* Load dest */
+"0:\n"
+" movl %%eax, (%%edi)\n" /* Store 4 pixels, 12 bytes */
+" movl %%ebx, 4(%%edi)\n"
+" movl %%edx, 8(%%edi)\n"
+" addl $12, %%edi\n"
+" dec %%ecx\n"
+" jnz 0b\n"
+" movl %%edi, %0\n"
+ : "=m"(addr)
+ : "m"(c), "m"(Count), "m"(addr)
+ : "%eax", "%ebx", "%ecx", "%edx", "%edi");
+#else
+ c = c & 0xffffff; /* 0ABC */
+ Fill[0] = c | (c << 24); /* CABC */
+ Fill[1] = (c >> 8) | (c << 16); /* BCAB */
+ Fill[2] = (c << 8) | (c >> 16); /* ABCA */
+ MultiCount = Count / 4;
+ do
+ {
+ *(PULONG)addr = Fill[0];
+ addr += 4;
+ *(PULONG)addr = Fill[1];
+ addr += 4;
+ *(PULONG)addr = Fill[2];
+ addr += 4;
+ }
+ while (0 != --MultiCount);
+#endif
+ Count = Count & 0x03;
+ while (0 != Count--)
+ {
+ *(PUSHORT)(addr) = c;
+ addr += 2;
+ *(addr) = c >> 16;
+ addr += 1;
+ }
+ }
}
VOID
DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
{
- PBYTE addr = SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
+ PBYTE addr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
LONG lDelta = SurfObj->lDelta;
c &= 0xFFFFFF;
PBYTE SourceBits_4BPP, SourceLine_4BPP;
PWORD SourceBits_16BPP, SourceLine_16BPP;
- DestBits = BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
+ DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
switch(BltInfo->SourceSurface->iBitmapFormat)
{
break;
case BMF_4BPP:
- SourceBits_4BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
+ SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
{
break;
case BMF_8BPP:
- SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
+ SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
DestLine = DestBits;
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
break;
case BMF_16BPP:
- SourceBits_16BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
+ SourceBits_16BPP = (PWORD)((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x);
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
{
{
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
{
- SourceBits = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
+ SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
{
RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
}
else
{
- SourceBits = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
- DestBits = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
+ SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
+ DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
{
RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
break;
case BMF_32BPP:
- SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
+ SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
DestLine = DestBits;
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
SourceY = BltInfo->SourcePoint.y;
DestBits = (PBYTE)(
- BltInfo->DestSurface->pvScan0 +
+ (PBYTE)BltInfo->DestSurface->pvScan0 +
(BltInfo->DestRect.left << 1) + BltInfo->DestRect.left +
BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
return TRUE;
}
+/* BitBlt Optimize */
+BOOLEAN
+DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
+{
+ ULONG DestY;
+
+#ifdef _M_IX86
+ PBYTE xaddr = (PBYTE)DestSurface->pvScan0 + DestRect->top * DestSurface->lDelta + (DestRect->left << 1) + DestRect->left;
+ PBYTE addr;
+ ULONG Count;
+ ULONG xCount=DestRect->right - DestRect->left;
+
+ for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
+ {
+ Count = xCount;
+ addr = xaddr;
+ xaddr = (PBYTE)((ULONG_PTR)addr + DestSurface->lDelta);
+
+ if (Count < 8)
+ {
+ /* For small fills, don't bother doing anything fancy */
+ while (Count--)
+ {
+ *(PUSHORT)(addr) = color;
+ addr += 2;
+ *(addr) = color >> 16;
+ addr += 1;
+ }
+ }
+ else
+ {
+ /* Align to 4-byte address */
+ while (0 != ((ULONG_PTR) addr & 0x3))
+ {
+ *(PUSHORT)(addr) = color;
+ addr += 2;
+ *(addr) = color >> 16;
+ addr += 1;
+ Count--;
+ }
+ /* If the color we need to fill with is 0ABC, then the final mem pattern
+ * (note little-endianness) would be:
+ *
+ * |C.B.A|C.B.A|C.B.A|C.B.A| <- pixel borders
+ * |C.B.A.C|B.A.C.B|A.C.B.A| <- ULONG borders
+ *
+ * So, taking endianness into account again, we need to fill with these
+ * ULONGs: CABC BCAB ABCA */
+
+ /* This is about 30% faster than the generic C code below */
+ __asm__ __volatile__ (
+" movl %1, %%ecx\n"
+" andl $0xffffff, %%ecx\n" /* 0ABC */
+" movl %%ecx, %%ebx\n" /* Construct BCAB in ebx */
+" shrl $8, %%ebx\n"
+" movl %%ecx, %%eax\n"
+" shll $16, %%eax\n"
+" orl %%eax, %%ebx\n"
+" movl %%ecx, %%edx\n" /* Construct ABCA in edx */
+" shll $8, %%edx\n"
+" movl %%ecx, %%eax\n"
+" shrl $16, %%eax\n"
+" orl %%eax, %%edx\n"
+" movl %%ecx, %%eax\n" /* Construct CABC in eax */
+" shll $24, %%eax\n"
+" orl %%ecx, %%eax\n"
+" movl %2, %%ecx\n" /* Load count */
+" shr $2, %%ecx\n"
+" movl %3, %%edi\n" /* Load dest */
+".FL1:\n"
+" movl %%eax, (%%edi)\n" /* Store 4 pixels, 12 bytes */
+" movl %%ebx, 4(%%edi)\n"
+" movl %%edx, 8(%%edi)\n"
+" addl $12, %%edi\n"
+" dec %%ecx\n"
+" jnz .FL1\n"
+" movl %%edi, %0\n"
+ : "=m"(addr)
+ : "m"(color), "m"(Count), "m"(addr)
+ : "%eax", "%ebx", "%ecx", "%edx", "%edi");
+ Count = Count & 0x03;
+ while (0 != Count--)
+ {
+ *(PUSHORT)(addr) = color;
+ addr += 2;
+ *(addr) = color >> 16;
+ addr += 1;
+ }
+ }
+ }
+#else
+
+ for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
+ {
+ DIB_24BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
+ }
+#endif
+ return TRUE;
+}
+
+//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
- DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
- return FALSE;
+ LONG SrcSizeY;
+ LONG SrcSizeX;
+ LONG DesSizeY;
+ LONG DesSizeX;
+ LONG sx;
+ LONG sy;
+ LONG DesX;
+ LONG DesY;
+ LONG color;
+
+ SrcSizeY = SourceRect->bottom - SourceRect->top;
+ SrcSizeX = SourceRect->right - SourceRect->left;
+
+ DesSizeY = DestRect->bottom - DestRect->top;
+ DesSizeX = DestRect->right - DestRect->left;
+
+ switch(SourceSurf->iBitmapFormat)
+ {
+ case BMF_1BPP:
+ /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+ /* This is a reference implementation, it hasn't been optimized for speed */
+
+ for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+ {
+ sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+
+ for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+ {
+ sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
+
+ if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
+ {
+ DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 0));
+ }
+ else
+ {
+ DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 1));
+ }
+ }
+ }
+
+ break;
+
+ case BMF_4BPP:
+ /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+ /* This is a reference implementation, it hasn't been optimized for speed */
+
+ for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+ {
+ sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+
+ for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+ {
+ sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
+ color = DIB_4BPP_GetPixel(SourceSurf, sx, sy);
+ DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+ }
+ }
+ break;
+
+ case BMF_8BPP:
+ /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+ /* This is a reference implementation, it hasn't been optimized for speed */
+
+ for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+ {
+ sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+
+ for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+ {
+ sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
+ color = DIB_8BPP_GetPixel(SourceSurf, sx, sy);
+ DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+ }
+ }
+ break;
+
+ case BMF_16BPP:
+ /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+ /* This is a reference implementation, it hasn't been optimized for speed */
+
+ for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+ {
+ sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+
+ for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+ {
+ sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
+ color = DIB_16BPP_GetPixel(SourceSurf, sx, sy);
+ DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+ }
+ }
+ break;
+
+ case BMF_24BPP:
+ /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+ /* This is a reference implementation, it hasn't been optimized for speed */
+
+ for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+ {
+ sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+
+ for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+ {
+ sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
+ color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
+ DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+ }
+ }
+ break;
+
+ case BMF_32BPP:
+ /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
+ /* This is a reference implementation, it hasn't been optimized for speed */
+
+ for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
+ {
+ sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
+
+ for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
+ {
+ sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
+ color = DIB_32BPP_GetPixel(SourceSurf, sx, sy);
+ DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
+ }
+ }
+ break;
+
+ default:
+ //DPRINT1("DIB_24BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
+ return FALSE;
+ }
+
+ return TRUE;
}
BOOLEAN
BYTE *DestBits;
SourceY = SourcePoint->y;
- DestBits = (BYTE*)(DestSurf->pvScan0 +
+ DestBits = (BYTE*)((PBYTE)DestSurf->pvScan0 +
(DestRect->left << 2) +
DestRect->top * DestSurf->lDelta);
wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
return TRUE;
}
+typedef union {
+ ULONG ul;
+ struct {
+ UCHAR red;
+ UCHAR green;
+ UCHAR blue;
+ UCHAR alpha;
+ } col;
+} NICEPIXEL32;
+
+STATIC inline UCHAR
+Clamp8(ULONG val)
+{
+ return (val > 255) ? 255 : val;
+}
+
+BOOLEAN
+DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+ RECTL* SourceRect, CLIPOBJ* ClipRegion,
+ XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+ INT Rows, Cols, SrcX, SrcY;
+ register PUCHAR Dst;
+ ULONG DstDelta;
+ BLENDFUNCTION BlendFunc;
+ register NICEPIXEL32 DstPixel, SrcPixel;
+ UCHAR Alpha, SrcBpp;
+
+ DPRINT("DIB_24BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
+ SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
+ DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
+
+ ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
+ DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
+
+ BlendFunc = BlendObj->BlendFunction;
+ if (BlendFunc.BlendOp != AC_SRC_OVER)
+ {
+ DPRINT1("BlendOp != AC_SRC_OVER\n");
+ return FALSE;
+ }
+ if (BlendFunc.BlendFlags != 0)
+ {
+ DPRINT1("BlendFlags != 0\n");
+ return FALSE;
+ }
+ if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
+ {
+ DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
+ return FALSE;
+ }
+ if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
+ BitsPerFormat(Source->iBitmapFormat) != 32)
+ {
+ DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
+ return FALSE;
+ }
+
+ Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
+ (DestRect->left * 3));
+ DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) * 3);
+ SrcBpp = BitsPerFormat(Source->iBitmapFormat);
+
+ Rows = DestRect->bottom - DestRect->top;
+ SrcY = SourceRect->top;
+ while (--Rows >= 0)
+ {
+ Cols = DestRect->right - DestRect->left;
+ SrcX = SourceRect->left;
+ while (--Cols >= 0)
+ {
+ SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
+ SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
+ SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
+ SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
+ SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
+
+ Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
+ SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
+
+ DstPixel.ul = *Dst;
+ DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
+ DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
+ DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
+ *Dst = DstPixel.ul;
+ Dst = (PUCHAR)((ULONG_PTR)Dst + 3);
+ }
+ Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
+ SrcY++;
+ }
+
+ return TRUE;
+}
+
/* EOF */