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=…
==============================================================================
--- 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=…
==============================================================================
--- 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…
==============================================================================
--- 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 */