mirror of
https://github.com/reactos/reactos.git
synced 2025-05-18 16:51:18 +00:00
[WIN32K]
- Add a proper Alpha blending implementation for 16bpp surfaces CORE-8695 svn path=/trunk/; revision=64953
This commit is contained in:
parent
2b44442ffa
commit
7540c2ea36
3 changed files with 133 additions and 1 deletions
|
@ -47,7 +47,7 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] =
|
|||
{
|
||||
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 */
|
||||
{
|
||||
|
|
|
@ -101,6 +101,7 @@ BOOLEAN DIB_16BPP_BitBlt(PBLTINFO);
|
|||
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);
|
||||
|
|
|
@ -525,4 +525,135 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
|||
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 */
|
||||
|
|
Loading…
Reference in a new issue