Implement (Int)EngAlphaBlend and 8, 16, 24 and 32 bpp DIB AlphaBlend functions. AlphaBlend() should work now.
Modified: trunk/reactos/subsys/win32k/dib/dib.c
Modified: trunk/reactos/subsys/win32k/dib/dib.h
Modified: trunk/reactos/subsys/win32k/dib/dib16bpp.c
Modified: trunk/reactos/subsys/win32k/dib/dib1bpp.c
Modified: trunk/reactos/subsys/win32k/dib/dib24bpp.c
Modified: trunk/reactos/subsys/win32k/dib/dib32bpp.c
Modified: trunk/reactos/subsys/win32k/dib/dib4bpp.c
Modified: trunk/reactos/subsys/win32k/dib/dib8bpp.c
Modified: trunk/reactos/subsys/win32k/eng/bitblt.c
Modified: trunk/reactos/subsys/win32k/eng/xlate.c
Modified: trunk/reactos/subsys/win32k/include/inteng.h
Modified: trunk/reactos/subsys/win32k/objects/bitmaps.c
Modified: trunk/reactos/subsys/win32k/stubs/xpstubs.c

Modified: trunk/reactos/subsys/win32k/dib/dib.c
--- trunk/reactos/subsys/win32k/dib/dib.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -33,63 +33,68 @@
    /* 0 */
    {
       Dummy_PutPixel, Dummy_GetPixel, Dummy_HLine, Dummy_VLine,
-      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt
+      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt,
+      Dummy_ColorFill, Dummy_AlphaBlend
    },
    /* BMF_1BPP */
    {
       DIB_1BPP_PutPixel, DIB_1BPP_GetPixel, DIB_1BPP_HLine, DIB_1BPP_VLine,
       DIB_1BPP_BitBlt, DIB_1BPP_BitBltSrcCopy, DIB_1BPP_StretchBlt,
-      DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill
+      DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_1BPP_AlphaBlend
    },
    /* BMF_4BPP */
    {
       DIB_4BPP_PutPixel, DIB_4BPP_GetPixel, DIB_4BPP_HLine, DIB_4BPP_VLine,
       DIB_4BPP_BitBlt, DIB_4BPP_BitBltSrcCopy, DIB_4BPP_StretchBlt,
-      DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill
+      DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_4BPP_AlphaBlend
    },
    /* BMF_8BPP */
    {
       DIB_8BPP_PutPixel, DIB_8BPP_GetPixel, DIB_8BPP_HLine, DIB_8BPP_VLine,
       DIB_8BPP_BitBlt, DIB_8BPP_BitBltSrcCopy, DIB_8BPP_StretchBlt,
-      DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill
+      DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_8BPP_AlphaBlend
    },
    /* BMF_16BPP */
    {
       DIB_16BPP_PutPixel, DIB_16BPP_GetPixel, DIB_16BPP_HLine, DIB_16BPP_VLine,
       DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_16BPP_StretchBlt,
-      DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill
+      DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_16BPP_AlphaBlend
    },
    /* BMF_24BPP */
    {
       DIB_24BPP_PutPixel, DIB_24BPP_GetPixel, DIB_24BPP_HLine, DIB_24BPP_VLine,
       DIB_24BPP_BitBlt, DIB_24BPP_BitBltSrcCopy, DIB_24BPP_StretchBlt,
-      DIB_24BPP_TransparentBlt, DIB_24BPP_ColorFill
+      DIB_24BPP_TransparentBlt, DIB_24BPP_ColorFill, DIB_24BPP_AlphaBlend
    },
    /* BMF_32BPP */
    {
       DIB_32BPP_PutPixel, DIB_32BPP_GetPixel, DIB_32BPP_HLine, DIB_32BPP_VLine,
       DIB_32BPP_BitBlt, DIB_32BPP_BitBltSrcCopy, DIB_32BPP_StretchBlt,
-      DIB_32BPP_TransparentBlt, DIB_32BPP_ColorFill
+      DIB_32BPP_TransparentBlt, DIB_32BPP_ColorFill, DIB_32BPP_AlphaBlend
    },
    /* BMF_4RLE */
    {
       Dummy_PutPixel, Dummy_GetPixel, Dummy_HLine, Dummy_VLine,
-      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt, Dummy_ColorFill
+      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt,
+      Dummy_ColorFill, Dummy_AlphaBlend
    },
    /* BMF_8RLE */
    {
       Dummy_PutPixel, Dummy_GetPixel, Dummy_HLine, Dummy_VLine,
-      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt, Dummy_ColorFill
+      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt,
+      Dummy_ColorFill, Dummy_AlphaBlend
    },
    /* BMF_JPEG */
    {
       Dummy_PutPixel, Dummy_GetPixel, Dummy_HLine, Dummy_VLine,
-      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt, Dummy_ColorFill
+      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt,
+      Dummy_ColorFill, Dummy_AlphaBlend
    },
    /* BMF_PNG */
    {
       Dummy_PutPixel, Dummy_GetPixel, Dummy_HLine, Dummy_VLine,
-      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt, Dummy_ColorFill
+      Dummy_BitBlt, Dummy_BitBlt, Dummy_StretchBlt, Dummy_TransparentBlt,
+      Dummy_ColorFill, Dummy_AlphaBlend
    }
 };
 
@@ -240,4 +245,12 @@
 }
 
 
+BOOLEAN
+Dummy_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+                 RECTL* SourceRect, CLIPOBJ* ClipRegion,
+                 XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+  return FALSE;
+}
+
 /* EOF */

Modified: trunk/reactos/subsys/win32k/dib/dib.h
--- trunk/reactos/subsys/win32k/dib/dib.h	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib.h	2005-11-04 23:37:06 UTC (rev 19008)
@@ -44,6 +44,7 @@
 typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 typedef BOOLEAN (*PFN_DIB_TransparentBlt)(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 typedef BOOLEAN (*PFN_DIB_ColorFill)(SURFOBJ*, RECTL*, ULONG);
+typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 typedef struct
 {
@@ -56,6 +57,7 @@
   PFN_DIB_StretchBlt     DIB_StretchBlt;
   PFN_DIB_TransparentBlt DIB_TransparentBlt;
   PFN_DIB_ColorFill      DIB_ColorFill;
+  PFN_DIB_AlphaBlend     DIB_AlphaBlend;
 } DIB_FUNCTIONS;
 
 extern DIB_FUNCTIONS DibFunctionsForBitmapFormat[];
@@ -68,6 +70,7 @@
 BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG);
+BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 VOID DIB_1BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
 ULONG DIB_1BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -78,6 +81,7 @@
 BOOLEAN DIB_1BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_1BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
+BOOLEAN DIB_1BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 VOID DIB_4BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
 ULONG DIB_4BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -88,6 +92,7 @@
 BOOLEAN DIB_4BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_4BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
+BOOLEAN DIB_4BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 VOID DIB_8BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
 ULONG DIB_8BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -98,6 +103,7 @@
 BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_8BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
+BOOLEAN DIB_8BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 VOID DIB_16BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
 ULONG DIB_16BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -108,6 +114,7 @@
 BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
+BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 VOID DIB_24BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
 ULONG DIB_24BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -118,6 +125,7 @@
 BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_24BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
+BOOLEAN DIB_24BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 VOID DIB_32BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
 ULONG DIB_32BPP_GetPixel(SURFOBJ*,LONG,LONG);
@@ -128,6 +136,7 @@
 BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
 BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
+BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
 
 extern unsigned char notmask[2];
 extern unsigned char altnotmask[2];

Modified: trunk/reactos/subsys/win32k/dib/dib16bpp.c
--- trunk/reactos/subsys/win32k/dib/dib16bpp.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib16bpp.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -1358,4 +1358,123 @@
   return TRUE;
 }
 
+typedef union {
+   ULONG ul;
+   struct {
+      UCHAR red;
+      UCHAR green;
+      UCHAR blue;
+      UCHAR alpha;
+   } col;
+} NICEPIXEL32;
+
+typedef union {
+   USHORT us;
+   struct {
+      USHORT red:5,
+             green:6,
+             blue:5;
+   } col;
+} NICEPIXEL16;
+
+STATIC inline UCHAR
+Clamp5(ULONG val)
+{
+   return (val > 31) ? 31 : val;
+}
+
+STATIC inline UCHAR
+Clamp6(ULONG val)
+{
+   return (val > 63) ? 63 : val;
+}
+
+BOOLEAN
+DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+                     RECTL* SourceRect, CLIPOBJ* ClipRegion,
+                     XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+   INT Rows, Cols, SrcX, SrcY;
+   register PUSHORT Dst;
+   ULONG DstDelta;
+   BLENDFUNCTION BlendFunc;
+   register NICEPIXEL16 DstPixel;
+   register NICEPIXEL32 SrcPixel;
+   UCHAR Alpha, SrcBpp;
+
+   DPRINT("DIB_16BPP_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 = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
+                              (DestRect->left << 1));
+   DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 1);
+   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)
+      {
+         if (SrcBpp <= 16)
+         {
+            DstPixel.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
+            SrcPixel.col.red = (DstPixel.col.red << 3) | (DstPixel.col.red >> 2);
+            SrcPixel.col.green = (DstPixel.col.green << 2) | (DstPixel.col.green >> 4);
+            SrcPixel.col.blue = (DstPixel.col.blue << 3) | (DstPixel.col.blue >> 2);
+         }
+         else
+         {
+            SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
+         }
+         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.us = *Dst;
+         DstPixel.col.red = Clamp5(DstPixel.col.red * (255 - Alpha) / 255 + (SrcPixel.col.red >> 3));
+         DstPixel.col.green = Clamp6(DstPixel.col.green * (255 - Alpha) / 255 + (SrcPixel.col.green >> 2));
+         DstPixel.col.blue = Clamp5(DstPixel.col.blue * (255 - Alpha) / 255 + (SrcPixel.col.blue >> 3));
+         *Dst++ = DstPixel.us;
+      }
+      Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta);
+      SrcY++;
+   }
+
+   return TRUE;
+}
+
 /* EOF */

Modified: trunk/reactos/subsys/win32k/dib/dib1bpp.c
--- trunk/reactos/subsys/win32k/dib/dib1bpp.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib1bpp.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -1303,4 +1303,13 @@
   return FALSE;
 }
 
+BOOLEAN
+DIB_1BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+                    RECTL* SourceRect, CLIPOBJ* ClipRegion,
+                    XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+  UNIMPLEMENTED;
+  return FALSE;
+}
+
 /* EOF */

Modified: trunk/reactos/subsys/win32k/dib/dib24bpp.c
--- trunk/reactos/subsys/win32k/dib/dib24bpp.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib24bpp.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -1331,4 +1331,98 @@
   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 */

Modified: trunk/reactos/subsys/win32k/dib/dib32bpp.c
--- trunk/reactos/subsys/win32k/dib/dib32bpp.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib32bpp.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -1256,4 +1256,98 @@
   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_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+                     RECTL* SourceRect, CLIPOBJ* ClipRegion,
+                     XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+   INT Rows, Cols, SrcX, SrcY;
+   register PULONG Dst;
+   ULONG DstDelta;
+   BLENDFUNCTION BlendFunc;
+   register NICEPIXEL32 DstPixel, SrcPixel;
+   UCHAR Alpha, SrcBpp;
+
+   DPRINT("DIB_32BPP_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 = (PULONG)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
+                             (DestRect->left << 2));
+   DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 2);
+   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);
+         DstPixel.col.alpha = Clamp8(DstPixel.col.alpha * (255 - Alpha) / 255 + SrcPixel.col.alpha);
+         *Dst++ = DstPixel.ul;
+      }
+      Dst = (PULONG)((ULONG_PTR)Dst + DstDelta);
+      SrcY++;
+   }
+
+   return TRUE;
+}
+
 /* EOF */

Modified: trunk/reactos/subsys/win32k/dib/dib4bpp.c
--- trunk/reactos/subsys/win32k/dib/dib4bpp.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib4bpp.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -1189,4 +1189,13 @@
   return FALSE;
 }
 
+BOOLEAN
+DIB_4BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+                    RECTL* SourceRect, CLIPOBJ* ClipRegion,
+                    XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+  UNIMPLEMENTED;
+  return FALSE;
+}
+
 /* EOF */

Modified: trunk/reactos/subsys/win32k/dib/dib8bpp.c
--- trunk/reactos/subsys/win32k/dib/dib8bpp.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/dib/dib8bpp.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -1217,4 +1217,162 @@
   return TRUE;
 }
 
+typedef union {
+   ULONG ul;
+   struct {
+      UCHAR red;
+      UCHAR green;
+      UCHAR blue;
+      UCHAR alpha;
+   } col;
+} NICEPIXEL32;
+
+typedef union {
+   USHORT us;
+   struct {
+      USHORT red:5,
+             green:6,
+             blue:5;
+   } col;
+} NICEPIXEL16;
+
+STATIC inline UCHAR
+Clamp8(ULONG val)
+{
+   return (val > 255) ? 255 : val;
+}
+
+BOOLEAN
+DIB_8BPP_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;
+   register NICEPIXEL32 SrcPixel;
+   register NICEPIXEL16 SrcPixel16;
+   UCHAR Alpha, SrcBpp;
+   HPALETTE SrcPalette, DstPalette;
+   XLATEOBJ *SrcTo32Xlate, *DstTo32Xlate, *DstFrom32Xlate;
+
+   DPRINT("DIB_8BPP_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;
+   }
+
+   SrcBpp = BitsPerFormat(Source->iBitmapFormat);
+   SrcPalette = IntEngGetXlatePalette(ColorTranslation, XO_SRCPALETTE);
+   if (SrcPalette != 0)
+   {
+      SrcTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, SrcPalette);
+      if (SrcTo32Xlate == NULL)
+      {
+         DPRINT1("IntEngCreateXlate failed\n");
+         return FALSE;
+      }
+   }
+   else
+   {
+      SrcTo32Xlate = NULL;
+      ASSERT(SrcBpp >= 16);
+   }
+
+   DstPalette = IntEngGetXlatePalette(ColorTranslation, XO_DESTPALETTE);
+   DstTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, DstPalette);
+   DstFrom32Xlate = IntEngCreateXlate(0, PAL_RGB, DstPalette, NULL);
+   if (DstTo32Xlate == NULL || DstFrom32Xlate == NULL)
+   {
+      if (SrcTo32Xlate != NULL)
+         EngDeleteXlate(SrcTo32Xlate);
+      if (DstTo32Xlate != NULL)
+         EngDeleteXlate(DstTo32Xlate);
+      if (DstFrom32Xlate != NULL)
+         EngDeleteXlate(DstFrom32Xlate);
+      DPRINT1("IntEngCreateXlate failed\n");
+      return FALSE;
+   }
+
+   Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
+                             DestRect->left);
+   DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);
+
+   Rows = DestRect->bottom - DestRect->top;
+   SrcY = SourceRect->top;
+   while (--Rows >= 0)
+   {
+      Cols = DestRect->right - DestRect->left;
+      SrcX = SourceRect->left;
+      while (--Cols >= 0)
+      {
+         if (SrcTo32Xlate != NULL)
+         {
+            SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, SrcTo32Xlate);
+         }
+         else if (SrcBpp <= 16)
+         {
+            SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
+            SrcPixel.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
+            SrcPixel.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
+            SrcPixel.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
+         }
+         else
+         {
+            SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
+         }
+         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 = XLATEOBJ_iXlate(DstTo32Xlate, *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++ = XLATEOBJ_iXlate(DstFrom32Xlate, DstPixel.ul);
+      }
+      Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
+      SrcY++;
+   }
+
+   if (SrcTo32Xlate != NULL)
+      EngDeleteXlate(SrcTo32Xlate);
+   if (DstTo32Xlate != NULL)
+      EngDeleteXlate(DstTo32Xlate);
+   if (DstFrom32Xlate != NULL)
+      EngDeleteXlate(DstFrom32Xlate);
+
+   return TRUE;
+}
+
 /* EOF */

Modified: trunk/reactos/subsys/win32k/eng/bitblt.c
--- trunk/reactos/subsys/win32k/eng/bitblt.c	2005-11-04 23:25:03 UTC (rev 19007)
+++ trunk/reactos/subsys/win32k/eng/bitblt.c	2005-11-04 23:37:06 UTC (rev 19008)
@@ -889,60 +889,320 @@
   return ret;
 }
 
+BOOL
+STDCALL
+EngAlphaBlend(IN SURFOBJ *Dest,
+              IN SURFOBJ *Source,
+              IN CLIPOBJ *ClipRegion,
+              IN XLATEOBJ *ColorTranslation,
+              IN PRECTL DestRect,
+              IN PRECTL SourceRect,
+              IN BLENDOBJ *BlendObj)
+{
+  RECTL              SourceStretchedRect;
+  SIZEL              SourceStretchedSize;
+  HBITMAP            SourceStretchedBitmap = 0;
+  SURFOBJ*           SourceStretchedObj = NULL;
+  RECTL              InputRect;
+  RECTL              OutputRect;
+  RECTL              ClipRect;
+  RECTL              CombinedRect;
+  RECTL              Rect;
+  POINTL             Translate;
+  INTENG_ENTER_LEAVE EnterLeaveSource;
+  INTENG_ENTER_LEAVE EnterLeaveDest;
+  SURFOBJ*           InputObj;
+  SURFOBJ*           OutputObj;
+  LONG               Width;
+  LONG               ClippingType;
+  RECT_ENUM          RectEnum;
+  BOOL               EnumMore;
+  INT                i;
+  BOOLEAN            Ret;
+
+  DPRINT("EngAlphaBlend(Dest:0x%p, Source:0x%p, ClipRegion:0x%p, ColorTranslation:0x%p,\n", Dest, Source, ClipRegion, ColorTranslation);
+  DPRINT("              DestRect:{0x%x, 0x%x, 0x%x, 0x%x}, SourceRect:{0x%x, 0x%x, 0x%x, 0x%x},\n",
+         DestRect->left, DestRect->top, DestRect->right, DestRect->bottom,
+         SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
+  DPRINT("              BlendObj:{0x%x, 0x%x, 0x%x, 0x%x}\n", BlendObj->BlendFunction.BlendOp,
+         BlendObj->BlendFunction.BlendFlags, BlendObj->BlendFunction.SourceConstantAlpha,
+         BlendObj->BlendFunction.AlphaFormat);
+
+  /* Validate input */
+  if (DestRect->left >= DestRect->right || DestRect->top >= DestRect->bottom)
+    {
+      DPRINT1("Empty destination rectangle!\n");
+      return FALSE;
+    }
+  if (SourceRect->left >= SourceRect->right || SourceRect->top >= SourceRect->bottom)
+    {
+      DPRINT1("Empty source rectangle!\n");
+      return FALSE;
+    }
+  if (Dest == Source &&
+      !(DestRect->left >= SourceRect->right || SourceRect->left >= DestRect->right ||
+        DestRect->top >= SourceRect->bottom || SourceRect->top >= DestRect->bottom))
+    {
+      DPRINT1("Source and destination rectangles overlap!\n");
+      return FALSE;
+    }
+
+  if (BlendObj->BlendFunction.BlendOp != AC_SRC_OVER)
+    {
+      DPRINT1("BlendOp != AC_SRC_OVER (0x%x)\n", BlendObj->BlendFunction.BlendOp);
+      return FALSE;
+    }
+  if (BlendObj->BlendFunction.BlendFlags != 0)
+    {
+      DPRINT1("BlendFlags != 0 (0x%x)\n", BlendObj->BlendFunction.BlendFlags);
+      return FALSE;
+    }
+  if ((BlendObj->BlendFunction.AlphaFormat & ~AC_SRC_ALPHA) != 0)
+    {
+      DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendObj->BlendFunction.AlphaFormat);
+      return FALSE;
+    }
+
+  /* Check if there is anything to draw */
+  if (ClipRegion != NULL &&
+      (ClipRegion->rclBounds.left >= ClipRegion->rclBounds.right ||
+       ClipRegion->rclBounds.top >= ClipRegion->rclBounds.bottom))
+    {
+      /* Nothing to do */
+      return TRUE;
+    }
+
+  /* Stretch source if needed */
+  if (DestRect->right - DestRect->left != SourceRect->right - SourceRect->left ||
+      DestRect->bottom - DestRect->top != SourceRect->bottom - SourceRect->top)
+    {
+      SourceStretchedSize.cx = DestRect->right - DestRect->left;
+      SourceStretchedSize.cy = DestRect->bottom - DestRect->top;
+      Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx, BitsPerFormat(Source->iBitmapFormat));
+      /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and IntEngStretchBlt
+                if possible to get a HW accelerated stretch. */
+      SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width, Source->iBitmapFormat,
+                                              BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
+      if (SourceStretchedBitmap == 0)
+        {
+          DPRINT1("EngCreateBitmap failed!\n");
+          return FALSE;
+        }
+      SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap);
+      if (SourceStretchedObj == NULL)
+        {
+          DPRINT1("EngLockSurface failed!\n");
+          EngDeleteSurface((HSURF)SourceStretchedBitmap);
+          return FALSE;
+        }
+
+      SourceStretchedRect.left = 0;
+      SourceStretchedRect.right = SourceStretchedSize.cx;
+      SourceStretchedRect.top = 0;
+      SourceStretchedRect.bottom = SourceStretchedSize.cy;
+      /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
+                try to acquire an already acquired mutex (lock the already locked source surface) */
+      /*if (!IntEngStretchBlt(SourceStretchedObj, Source, NULL, NULL,
+                            NULL, &SourceStretchedRect, SourceRect, NULL,
+                            NULL, NULL, COLORONCOLOR))*/
+      if (!EngStretchBlt(SourceStretchedObj, Source, NULL, NULL, NULL,
+                         NULL, NULL, &SourceStretchedRect, SourceRect,
+                         NULL, COLORONCOLOR))
+        {
+          DPRINT1("EngStretchBlt failed!\n");
+          EngFreeMem(SourceStretchedObj->pvBits);
+          EngUnlockSurface(SourceStretchedObj);
+          EngDeleteSurface((HSURF)SourceStretchedBitmap);
+          return FALSE;
+        }
+      SourceRect = &SourceStretchedRect;
+      Source = SourceStretchedObj;
+    }
+
+  /* Now call the DIB function */
+  InputRect.left = SourceRect->left;
+  InputRect.right = SourceRect->right;
+  InputRect.top = SourceRect->top;
+  InputRect.bottom = SourceRect->bottom;
+  if (!IntEngEnter(&EnterLeaveSource, Source, &InputRect, TRUE, &Translate, &InputObj))
+    {
+      if (SourceStretchedObj != NULL)
+        {
+          EngFreeMem(SourceStretchedObj->pvBits);
+          EngUnlockSurface(SourceStretchedObj);
+        }
+      if (SourceStretchedBitmap != 0)
+        {
+          EngDeleteSurface((HSURF)SourceStretchedBitmap);
+        }
+      return FALSE;
+    }
+  InputRect.left = SourceRect->left + Translate.x;
+  InputRect.right = SourceRect->right + Translate.x;
+  InputRect.top = SourceRect->top + Translate.y;
+  InputRect.bottom = SourceRect->bottom + Translate.y;
+
+  OutputRect.left = DestRect->left;
+  OutputRect.right = DestRect->right;
+  OutputRect.top = DestRect->top;
+  OutputRect.bottom = DestRect->bottom;
+  if (!IntEngEnter(&EnterLeaveDest, Dest, &OutputRect, FALSE, &Translate, &OutputObj))
+    {
+      IntEngLeave(&EnterLeaveSource);
+      if (SourceStretchedObj != NULL)
+        {
+          EngFreeMem(SourceStretchedObj->pvBits);
+          EngUnlockSurface(SourceStretchedObj);
+        }
+      if (SourceStretchedBitmap != 0)
+        {
+          EngDeleteSurface((HSURF)SourceStretchedBitmap);
+        }
+      return FALSE;
+    }
+  OutputRect.left = DestRect->left + Translate.x;
+  OutputRect.right = DestRect->right + Translate.x;
+  OutputRect.top = DestRect->top + Translate.y;
+  OutputRect.bottom = DestRect->bottom + Translate.y;
+
+  Ret = FALSE;
+  ClippingType = (ClipRegion == NULL) ? DC_TRIVIAL : ClipRegion->iDComplexity;
+  switch(ClippingType)
+    {
+    case DC_TRIVIAL:
+      Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+                OutputObj, InputObj, &OutputRect, &InputRect, ClipRegion, ColorTranslation, BlendObj);
+      break;
+
+    case DC_RECT:
+      ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
+      ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
+      ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
+      ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
+      if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+        {
+          Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
+          Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
+          Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
+          Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
+          Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+                    OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj);
+        }
+      break;
+
+    case DC_COMPLEX:
+      Ret = TRUE;
+      CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
+      do
+        {
+          EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
+                                   (PVOID) &RectEnum);
+
+          for (i = 0; i < RectEnum.c; i++)
+            {
+              ClipRect.left = RectEnum.arcl[i].left + Translate.x;
+              ClipRect.right = RectEnum.arcl[i].right + Translate.x;
+              ClipRect.top = RectEnum.arcl[i].top + Translate.y;
+              ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
+              if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
+                {
+                  Rect.left = InputRect.left + CombinedRect.left - OutputRect.left;
+                  Rect.right = InputRect.right + CombinedRect.right - OutputRect.right;
+                  Rect.top = InputRect.top + CombinedRect.top - OutputRect.top;
+                  Rect.bottom = InputRect.bottom + CombinedRect.bottom - OutputRect.bottom;
+                  Ret = DibFunctionsForBitmapFormat[OutputObj->iBitmapFormat].DIB_AlphaBlend(
+                            OutputObj, InputObj, &CombinedRect, &Rect, ClipRegion, ColorTranslation, BlendObj) && Ret;
+                }
+            }
+        }
+      while(EnumMore);
+      break;
+
+    default:
+      UNIMPLEMENTED;
+      ASSERT(FALSE);
+      break;
+    }
+
+  IntEngLeave(&EnterLeaveDest);
+  IntEngLeave(&EnterLeaveSource);
+
+  if (SourceStretchedObj != NULL)
+    {
+      EngFreeMem(SourceStretchedObj->pvBits);
+      EngUnlockSurface(SourceStretchedObj);
+    }
+  if (SourceStretchedBitmap != 0)
+    {
+      EngDeleteSurface((HSURF)SourceStretchedBitmap);
+    }
+
+  return Ret;
+}
+
 BOOL STDCALL
 IntEngAlphaBlend(IN SURFOBJ *Dest,
                  IN SURFOBJ *Source,
-                 IN CLIPOBJ *Clip,
+                 IN CLIPOBJ *ClipRegion,
                  IN XLATEOBJ *ColorTranslation,
                  IN PRECTL DestRect,
                  IN PRECTL SourceRect,
                  IN BLENDOBJ *BlendObj)
 {
-	BOOL ret = FALSE;
-	BITMAPOBJ *DestObj;
-	BITMAPOBJ *SourceObj;
+  BOOL ret = FALSE;
+  BITMAPOBJ *DestObj;
+  BITMAPOBJ *SourceObj;
 
-	ASSERT(Dest);
-	DestObj = CONTAINING_RECORD(Dest, BITMAPOBJ, SurfObj);
-	ASSERT(DestObj);
+  ASSERT(Dest);
+  DestObj = CONTAINING_RECORD(Dest, BITMAPOBJ, SurfObj);
+  ASSERT(DestObj);
 
-	ASSERT(Source);
-	SourceObj = CONTAINING_RECORD(Source, BITMAPOBJ, SurfObj);
-	ASSERT(SourceObj);
+  ASSERT(Source);
+  SourceObj = CONTAINING_RECORD(Source, BITMAPOBJ, SurfObj);
+  ASSERT(SourceObj);
 
[truncated at 1000 lines; 164 more skipped]