From: Ziqing Hui Subject: [PATCH 3/3] comctl32/imagelist: Add support for ILD_PRESERVEALPHA. Message-Id: <210445cb-dc72-395f-2ffc-4cc37ec0efb1@codeweavers.com> Date: Wed, 1 Apr 2020 17:59:07 +0800 Signed-off-by: Ziqing Hui --- dlls/comctl32/imagelist.c | 38 +++++++++++++++++++++------------ dlls/comctl32/tests/imagelist.c | 2 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index 013ae42f88..a6d9c73c49 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -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"); diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index d3f12e1679..db18443f89 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -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__);