mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Implement (Int)EngAlphaBlend and 8, 16, 24 and 32 bpp DIB AlphaBlend functions. AlphaBlend() should work now.
svn path=/trunk/; revision=19008
This commit is contained in:
parent
e21bca531d
commit
fc8ca65085
13 changed files with 837 additions and 65 deletions
|
@ -33,63 +33,68 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] =
|
|||
/* 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_ColorFill(SURFOBJ* Dest, RECTL* DestRect, ULONG Color)
|
|||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
Dummy_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||
RECTL* SourceRect, CLIPOBJ* ClipRegion,
|
||||
XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef BOOLEAN (*PFN_DIB_BitBlt)(PBLTINFO);
|
|||
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 @@ typedef struct
|
|||
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_BitBlt(PBLTINFO);
|
|||
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_BitBltSrcCopy(PBLTINFO);
|
|||
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_BitBltSrcCopy(PBLTINFO);
|
|||
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_BitBltSrcCopy(PBLTINFO);
|
|||
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_BitBltSrcCopy(PBLTINFO);
|
|||
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_BitBltSrcCopy(PBLTINFO);
|
|||
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_BitBltSrcCopy(PBLTINFO);
|
|||
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];
|
||||
|
|
|
@ -1358,4 +1358,123 @@ 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,
|
||||
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 */
|
||||
|
|
|
@ -1303,4 +1303,13 @@ DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DIB_1BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||
RECTL* SourceRect, CLIPOBJ* ClipRegion,
|
||||
XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1331,4 +1331,98 @@ DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
|||
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 */
|
||||
|
|
|
@ -1256,4 +1256,98 @@ DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
|||
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 */
|
||||
|
|
|
@ -1189,4 +1189,13 @@ DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DIB_4BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||
RECTL* SourceRect, CLIPOBJ* ClipRegion,
|
||||
XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1217,4 +1217,162 @@ DIB_8BPP_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,
|
||||
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 */
|
||||
|
|
|
@ -889,60 +889,320 @@ IntEngStretchBlt(SURFOBJ *DestSurf,
|
|||
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);
|
||||
|
||||
ASSERT(DestRect);
|
||||
ASSERT(SourceRect);
|
||||
ASSERT(DestRect);
|
||||
ASSERT(SourceRect);
|
||||
|
||||
BITMAPOBJ_LockBitmapBits(DestObj);
|
||||
MouseSafetyOnDrawStart(Dest, DestRect->left, DestRect->top,
|
||||
DestRect->right, DestRect->bottom);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (Source != Dest)
|
||||
BITMAPOBJ_LockBitmapBits(SourceObj);
|
||||
MouseSafetyOnDrawStart(Source, SourceRect->left, SourceRect->top,
|
||||
SourceRect->right, SourceRect->bottom);
|
||||
BITMAPOBJ_LockBitmapBits(DestObj);
|
||||
MouseSafetyOnDrawStart(Dest, DestRect->left, DestRect->top,
|
||||
DestRect->right, DestRect->bottom);
|
||||
|
||||
/* Call the driver's DrvAlphaBlend if available */
|
||||
if (DestObj->flHooks & HOOK_ALPHABLEND)
|
||||
{
|
||||
ret = GDIDEVFUNCS(Dest).AlphaBlend(
|
||||
Dest, Source, Clip, ColorTranslation,
|
||||
DestRect, SourceRect, BlendObj);
|
||||
}
|
||||
if (Source != Dest)
|
||||
BITMAPOBJ_LockBitmapBits(SourceObj);
|
||||
MouseSafetyOnDrawStart(Source, SourceRect->left, SourceRect->top,
|
||||
SourceRect->right, SourceRect->bottom);
|
||||
|
||||
if (! ret)
|
||||
{
|
||||
ret = EngAlphaBlend(Dest, Source, Clip, ColorTranslation,
|
||||
DestRect, SourceRect, BlendObj);
|
||||
}
|
||||
/* Call the driver's DrvAlphaBlend if available */
|
||||
if (DestObj->flHooks & HOOK_ALPHABLEND)
|
||||
{
|
||||
ret = GDIDEVFUNCS(Dest).AlphaBlend(
|
||||
Dest, Source, ClipRegion, ColorTranslation,
|
||||
DestRect, SourceRect, BlendObj);
|
||||
}
|
||||
|
||||
MouseSafetyOnDrawEnd(Source);
|
||||
if (Source != Dest)
|
||||
BITMAPOBJ_UnlockBitmapBits(SourceObj);
|
||||
MouseSafetyOnDrawEnd(Dest);
|
||||
BITMAPOBJ_UnlockBitmapBits(DestObj);
|
||||
if (! ret)
|
||||
{
|
||||
ret = EngAlphaBlend(Dest, Source, ClipRegion, ColorTranslation,
|
||||
DestRect, SourceRect, BlendObj);
|
||||
}
|
||||
|
||||
return ret;
|
||||
MouseSafetyOnDrawEnd(Source);
|
||||
if (Source != Dest)
|
||||
BITMAPOBJ_UnlockBitmapBits(SourceObj);
|
||||
MouseSafetyOnDrawEnd(Dest);
|
||||
BITMAPOBJ_UnlockBitmapBits(DestObj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**** REACTOS FONT RENDERING CODE *********************************************/
|
||||
|
|
|
@ -416,6 +416,24 @@ IntEngCreateSrcMonoXlate(HPALETTE PaletteDest,
|
|||
return XlateObj;
|
||||
}
|
||||
|
||||
HPALETTE FASTCALL
|
||||
IntEngGetXlatePalette(XLATEOBJ *XlateObj,
|
||||
ULONG Palette)
|
||||
{
|
||||
XLATEGDI *XlateGDI = ObjToGDI(XlateObj, XLATE);
|
||||
switch (Palette)
|
||||
{
|
||||
case XO_DESTPALETTE:
|
||||
return XlateGDI->DestPal;
|
||||
break;
|
||||
|
||||
case XO_SRCPALETTE:
|
||||
return XlateGDI->SourcePal;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -117,6 +117,10 @@ IntEngCreateSrcMonoXlate(HPALETTE PaletteDest,
|
|||
ULONG ForegroundColor,
|
||||
ULONG BackgroundColor);
|
||||
|
||||
HPALETTE FASTCALL
|
||||
IntEngGetXlatePalette(XLATEOBJ *XlateObj,
|
||||
ULONG Palette);
|
||||
|
||||
BOOL STDCALL
|
||||
IntEngPolyline(SURFOBJ *DestSurf,
|
||||
CLIPOBJ *Clip,
|
||||
|
@ -165,7 +169,7 @@ IntEngMovePointer(IN SURFOBJ *pso,
|
|||
BOOL STDCALL
|
||||
IntEngAlphaBlend(IN SURFOBJ *Dest,
|
||||
IN SURFOBJ *Source,
|
||||
IN CLIPOBJ *Clip,
|
||||
IN CLIPOBJ *ClipRegion,
|
||||
IN XLATEOBJ *ColorTranslation,
|
||||
IN PRECTL DestRect,
|
||||
IN PRECTL SourceRect,
|
||||
|
|
|
@ -1327,7 +1327,7 @@ NtGdiAlphaBlend(
|
|||
if (NULL == DCSrc)
|
||||
{
|
||||
DC_UnlockDc(DCDest);
|
||||
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
|
||||
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc);
|
||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -8,21 +8,6 @@
|
|||
#define STUB(x) void x(void) { DbgPrint("WIN32K: Stub for %s\n", #x); }
|
||||
#define UNIMPLEMENTED DbgPrint("(%s:%i) WIN32K: %s UNIMPLEMENTED\n", __FILE__, __LINE__, __FUNCTION__ )
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
EngAlphaBlend(
|
||||
IN SURFOBJ *psoDest,
|
||||
IN SURFOBJ *psoSrc,
|
||||
IN CLIPOBJ *pco,
|
||||
IN XLATEOBJ *pxlo,
|
||||
IN RECTL *prclDest,
|
||||
IN RECTL *prclSrc,
|
||||
IN BLENDOBJ *pBlendObj)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
EngControlSprites(
|
||||
|
|
Loading…
Reference in a new issue