diff --git a/reactos/subsystems/win32/win32k/dib/dib16bpp.c b/reactos/subsystems/win32/win32k/dib/dib16bpp.c index 5d33ef84786..61f0506c5ce 100644 --- a/reactos/subsystems/win32/win32k/dib/dib16bpp.c +++ b/reactos/subsystems/win32/win32k/dib/dib16bpp.c @@ -540,6 +540,12 @@ Clamp5(ULONG val) return (val > 31) ? 31 : val; } +static __inline UCHAR +Clamp8(ULONG val) +{ + return (val > 255) ? 255 : val; +} + static __inline UCHAR Clamp6(ULONG val) { @@ -555,9 +561,13 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, register PUSHORT Dst; ULONG DstDelta; BLENDFUNCTION BlendFunc; - register NICEPIXEL16 DstPixel; - register NICEPIXEL32 SrcPixel; + register NICEPIXEL16 SrcPixel16; + register NICEPIXEL16 DstPixel16; + register NICEPIXEL32 SrcPixel32; + register NICEPIXEL32 DstPixel32; UCHAR Alpha, SrcBpp; + XLATEGDI* XlateGDI; + XLATEOBJ* SrcXlateObj; DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, @@ -589,6 +599,21 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, return FALSE; } + if (!ColorTranslation) + { + DPRINT1("ColorTranslation must not be NULL!\n"); + return FALSE; + } + + XlateGDI = ObjToGDI(ColorTranslation, XLATE); + SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal); + + if (!SrcXlateObj) + { + DPRINT1("IntEngCreateXlate failed\n"); + return FALSE; + } + Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + (DestRect->left << 1)); DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 1); @@ -604,52 +629,61 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, { if (SrcBpp <= 16) { - DstPixel.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); - SrcPixel.col.red = (DstPixel.col.red << 3) | (DstPixel.col.red >> 2); + SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); + SrcPixel32.col.red = (SrcPixel16.col.red << 3); + SrcPixel32.col.green = (SrcPixel16.col.green << 2); + SrcPixel32.col.blue = (SrcPixel16.col.blue << 3); - SrcPixel.col.green = (DstPixel.col.green << 2) | - (DstPixel.col.green >> 4); + 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; + SrcPixel32.col.alpha = (SrcBpp == 32) ? + (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : + BlendFunc.SourceConstantAlpha; - SrcPixel.col.blue = (DstPixel.col.blue << 3) | (DstPixel.col.blue >> 2); + Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? + SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; + + DstPixel16.us = *Dst; + DstPixel16.col.red = Clamp5(DstPixel16.col.red * (255 - Alpha) / 255 + + (SrcPixel32.col.red >> 3)); + + DstPixel16.col.green = Clamp6(DstPixel16.col.green * (255 - Alpha) / 255 + + (SrcPixel32.col.green >> 2)); + + DstPixel16.col.blue = Clamp5(DstPixel16.col.blue * (255 - Alpha) / 255 + + (SrcPixel32.col.blue >> 3)); + + *Dst++ = DstPixel16.us; } else { - SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); + SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); + + 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; + SrcPixel32.col.alpha = (SrcBpp == 32) ? + (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : + BlendFunc.SourceConstantAlpha; + + Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? + SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; + + DstPixel32.ul = XLATEOBJ_iXlate(SrcXlateObj, *Dst); + SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red); + SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green); + SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); + *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul); } - 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++; } + if (SrcXlateObj) EngDeleteXlate(SrcXlateObj); + return TRUE; }