comctl32/imagelist: Add support for ILD_PRESERVEALPHA.

Signed-off-by: Ziqing Hui <zhui@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Ziqing Hui 2020-04-14 10:40:16 +08:00 committed by Alexandre Julliard
parent a6bb675eb7
commit 28c60b64c7
2 changed files with 25 additions and 15 deletions

View File

@ -23,7 +23,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* TODO:
* - Add support for ILD_PRESERVEALPHA, ILD_SCALE, ILD_DPISCALE
* - Add support for ILD_SCALE, ILD_DPISCALE
* - Add support for ILS_GLOW, ILS_SHADOW
* - Thread-safe locking
*/
@ -1234,17 +1234,23 @@ ImageList_DrawEx (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y,
static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y,
int src_x, int src_y, int cx, int cy, BLENDFUNCTION func,
UINT style, COLORREF blend_col, BOOL has_alpha, BOOL grayscale )
int src_x, int src_y, int cx, int cy, UINT style, UINT state,
DWORD frame, COLORREF blend_col, BOOL has_alpha )
{
BOOL ret = FALSE;
HDC hdc;
HBITMAP bmp = 0, mask = 0;
BITMAPINFO *info;
BLENDFUNCTION func;
void *bits, *mask_bits;
unsigned int *ptr;
int i, j;
func.BlendOp = AC_SRC_OVER;
func.BlendFlags = 0;
func.SourceConstantAlpha = 255;
func.AlphaFormat = AC_SRC_ALPHA;
if (!(hdc = CreateCompatibleDC( 0 ))) return FALSE;
if (!(info = heap_alloc( FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done;
info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@ -1286,7 +1292,12 @@ static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int des
}
}
if (grayscale)
if (state & ILS_ALPHA)
{
func.SourceConstantAlpha = (BYTE)frame;
}
else if (state & ILS_SATURATE)
{
for (i = 0, ptr = bits; i < cx * cy; i++, ptr++)
{
@ -1297,6 +1308,12 @@ static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int des
*ptr = (*ptr & 0xff000000)| (gray << 16) | (gray << 8) | gray;
}
}
else if (style & ILD_PRESERVEALPHA)
{
HBRUSH old_brush = SelectObject( dest_dc, GetStockObject(BLACK_BRUSH) );
PatBlt( dest_dc, dest_x, dest_y, cx, cy, PATCOPY );
SelectObject( dest_dc, old_brush );
}
if (has_alpha) /* we already have an alpha channel in this case */
{
@ -1430,7 +1447,6 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
if (!bMask && (has_alpha || (fState & ILS_ALPHA) || (fState & ILS_SATURATE)))
{
COLORREF colour, blend_col = CLR_NONE;
BLENDFUNCTION func;
if (bBlend)
{
@ -1439,15 +1455,10 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
else if (blend_col == CLR_NONE) blend_col = GetTextColor( pimldp->hdcDst );
}
func.BlendOp = AC_SRC_OVER;
func.BlendFlags = 0;
func.SourceConstantAlpha = (fState & ILS_ALPHA) ? pimldp->Frame : 255;
func.AlphaFormat = AC_SRC_ALPHA;
if (bIsTransparent)
{
bResult = alpha_blend_image( himl, pimldp->hdcDst, pimldp->x, pimldp->y, pt.x, pt.y, cx, cy,
func, fStyle, blend_col, has_alpha, fState & ILS_SATURATE );
fStyle, fState, pimldp->Frame, blend_col, has_alpha );
goto end;
}
colour = pimldp->rgbBk;
@ -1456,8 +1467,8 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
hOldBrush = SelectObject (hImageDC, CreateSolidBrush (colour));
PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
alpha_blend_image( himl, hImageDC, 0, 0, pt.x, pt.y, cx, cy, func,
fStyle, blend_col, has_alpha, fState & ILS_SATURATE );
alpha_blend_image( himl, hImageDC, 0, 0, pt.x, pt.y, cx, cy, fStyle, fState,
pimldp->Frame, blend_col, has_alpha );
DeleteObject (SelectObject (hImageDC, hOldBrush));
bResult = BitBlt( pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hImageDC, 0, 0, SRCCOPY );
goto end;
@ -1554,7 +1565,6 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
if (fState & ILS_GLOW) FIXME("ILS_GLOW: unimplemented!\n");
if (fState & ILS_SHADOW) FIXME("ILS_SHADOW: unimplemented!\n");
if (fStyle & ILD_PRESERVEALPHA) FIXME("ILD_PRESERVEALPHA: unimplemented!\n");
if (fStyle & ILD_SCALE) FIXME("ILD_SCALE: unimplemented!\n");
if (fStyle & ILD_DPISCALE) FIXME("ILD_DPISCALE: unimplemented!\n");

View File

@ -1600,7 +1600,7 @@ static void test_ImageList_DrawIndirect(void)
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0xFFD3E5F7, __LINE__);
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0xFFD3E5F7, __LINE__);
todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x895D6F81, __LINE__);
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x895D6F81, __LINE__);
check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, ILS_ALPHA, 127, 0xFFE9F2FB, 0xFFAEB7C0, __LINE__);
check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, ILS_SATURATE, 0, 0xFFAFAFAF, 0xFFF0F0F0, __LINE__);