Author: jgardou
Date: Fri Oct 24 11:34:45 2014
New Revision: 64953

URL: http://svn.reactos.org/svn/reactos?rev=64953&view=rev
Log:
[WIN32K]
 - Add a proper Alpha blending implementation for 16bpp surfaces
CORE-8695

Modified:
    trunk/reactos/win32ss/gdi/dib/dib.c
    trunk/reactos/win32ss/gdi/dib/dib.h
    trunk/reactos/win32ss/gdi/dib/dib16bpp.c

Modified: trunk/reactos/win32ss/gdi/dib/dib.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/dib/dib.c?rev=64953&r1=64952&r2=64953&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/dib/dib.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/dib/dib.c [iso-8859-1] Fri Oct 24 11:34:45 2014
@@ -47,7 +47,7 @@
   {
     DIB_16BPP_PutPixel, DIB_16BPP_GetPixel, DIB_16BPP_HLine, DIB_16BPP_VLine,
     DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
-    DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_XXBPP_AlphaBlend
+    DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_16BPP_AlphaBlend
   },
   /* BMF_24BPP */
   {

Modified: trunk/reactos/win32ss/gdi/dib/dib.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/dib/dib.h?rev=64953&r1=64952&r2=64953&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/dib/dib.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/dib/dib.h [iso-8859-1] Fri Oct 24 11:34:45 2014
@@ -101,6 +101,7 @@
 BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO);
 BOOLEAN 
DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,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);

Modified: trunk/reactos/win32ss/gdi/dib/dib16bpp.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/dib/dib16bpp.c?rev=64953&r1=64952&r2=64953&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/dib/dib16bpp.c    [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/dib/dib16bpp.c    [iso-8859-1] Fri Oct 24 
11:34:45 2014
@@ -525,4 +525,135 @@
   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;
+    USHORT green :6;
+    USHORT blue  :5;
+  } col;
+} NICEPIXEL16;
+
+static __inline UCHAR
+Clamp6(ULONG val)
+{
+   return (val > 63) ? 63 : (UCHAR)val;
+}
+
+static __inline UCHAR
+Clamp5(ULONG val)
+{
+   return (val > 31) ? 31 : (UCHAR)val;
+}
+
+BOOLEAN
+DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+                     RECTL* SourceRect, CLIPOBJ* ClipRegion,
+                     XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+  INT DstX, DstY, SrcX, SrcY;
+  BLENDFUNCTION BlendFunc;
+  NICEPIXEL32 SrcPixel32;
+  NICEPIXEL16 DstPixel16;
+  UCHAR Alpha, Alpha6, Alpha5;
+  EXLATEOBJ* pexlo;
+  EXLATEOBJ exloSrcRGB;
+
+  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);
+
+  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;
+  }
+
+  if (!ColorTranslation)
+  {
+    DPRINT1("ColorTranslation must not be NULL!\n");
+    return FALSE;
+  }
+
+  pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
+  EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0);
+
+  SrcY = SourceRect->top;
+  DstY = DestRect->top;
+  while ( DstY < DestRect->bottom )
+  {
+    SrcX = SourceRect->left;
+    DstX = DestRect->left;
+    while(DstX < DestRect->right)
+    {
+      SrcPixel32.ul = DIB_GetSource(Source, SrcX, SrcY, &exloSrcRGB.xlo);
+      SrcPixel32.col.red = (SrcPixel32.col.red * 
BlendFunc.SourceConstantAlpha) / 255;
+      SrcPixel32.col.green = (SrcPixel32.col.green * 
BlendFunc.SourceConstantAlpha) / 255;
+      SrcPixel32.col.blue = (SrcPixel32.col.blue * 
BlendFunc.SourceConstantAlpha) / 255;
+
+      Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
+           (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha) / 255 :
+           BlendFunc.SourceConstantAlpha;
+
+      Alpha6 = Alpha >> 2;
+      Alpha5 = Alpha >> 3;
+
+      DstPixel16.us = DIB_16BPP_GetPixel(Dest, DstX, DstY) & 0xFFFF;
+      /* Perform bit loss */
+      SrcPixel32.col.red >>= 3;
+      SrcPixel32.col.green >>= 2;
+      SrcPixel32.col.blue >>= 3;
+
+      /* Do the blend in the right bit depth */
+      DstPixel16.col.red = Clamp5((DstPixel16.col.red * (31 - Alpha5)) / 31 + 
SrcPixel32.col.red);
+      DstPixel16.col.green = Clamp6((DstPixel16.col.green * (63 - Alpha6)) / 
63 + SrcPixel32.col.green);
+      DstPixel16.col.blue = Clamp5((DstPixel16.col.blue * (31 - Alpha5)) / 31 
+ SrcPixel32.col.blue);
+
+      DIB_16BPP_PutPixel(Dest, DstX, DstY, DstPixel16.us);
+
+      DstX++;
+      SrcX = SourceRect->left + ((DstX-DestRect->left)*(SourceRect->right - 
SourceRect->left))
+                                            /(DestRect->right-DestRect->left);
+    }
+    DstY++;
+    SrcY = SourceRect->top + ((DstY-DestRect->top)*(SourceRect->bottom - 
SourceRect->top))
+                                            /(DestRect->bottom-DestRect->top);
+  }
+
+  EXLATEOBJ_vCleanup(&exloSrcRGB);
+
+  return TRUE;
+}
+
 /* EOF */


Reply via email to