[v4 PATCH] comctl32/toolbar: Correctly draw disabled button which contains 32 bpp bitmap with alpha channel.
Nikolay Sivov
nsivov at codeweavers.com
Tue Mar 31 09:45:42 CDT 2020
From: Ziqing Hui <zhui at codeweavers.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=24784
Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
v4: made draw parameters initialization more explicit, so it's easier to follow what initial configuration is.
v3:
* Move imagelist_has_alpha() declaration to dlls/comctl32/comctl32.h
* Use ImageList_DrawIndirect() to replace ImageList_DrawEx()
dlls/comctl32/comctl32.h | 1 +
dlls/comctl32/imagelist.c | 5 +++++
dlls/comctl32/toolbar.c | 36 ++++++++++++++++++++++++++++++++----
3 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h
index 78e9798338..66b341ae5a 100644
--- a/dlls/comctl32/comctl32.h
+++ b/dlls/comctl32/comctl32.h
@@ -191,6 +191,7 @@ INT Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen) DECLSPEC_HIDDEN;
INT Str_GetPtrAtoW (LPCSTR lpSrc, LPWSTR lpDest, INT nMaxLen) DECLSPEC_HIDDEN;
BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc) DECLSPEC_HIDDEN;
BOOL Str_SetPtrWtoA (LPSTR *lppDest, LPCWSTR lpSrc) DECLSPEC_HIDDEN;
+BOOL imagelist_has_alpha(HIMAGELIST, UINT) DECLSPEC_HIDDEN;
#define COMCTL32_VERSION_MINOR 81
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 925952351f..013ae42f88 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -143,6 +143,11 @@ static BOOL is_valid(HIMAGELIST himl);
#define TILE_COUNT 4
+BOOL imagelist_has_alpha( HIMAGELIST himl, UINT index )
+{
+ return himl->item_flags[index] & ILIF_ALPHA;
+}
+
static inline UINT imagelist_height( UINT count )
{
return ((count + TILE_COUNT - 1)/TILE_COUNT);
diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c
index c302e6c111..b869cc4d7b 100644
--- a/dlls/comctl32/toolbar.c
+++ b/dlls/comctl32/toolbar.c
@@ -675,18 +675,45 @@ TOOLBAR_DrawPattern (const RECT *lpRect, const NMTBCUSTOMDRAW *tbcd)
static void TOOLBAR_DrawMasked(HIMAGELIST himl, int index, HDC hdc, INT x, INT y, UINT draw_flags)
{
+ IMAGELISTDRAWPARAMS draw_params = { 0 };
INT cx, cy;
HBITMAP hbmMask, hbmImage;
HDC hdcMask, hdcImage;
ImageList_GetIconSize(himl, &cx, &cy);
+ draw_params.cbSize = sizeof(draw_params);
+ draw_params.himl = himl;
+ draw_params.i = index;
+ draw_params.hdcDst = hdc;
+ draw_params.x = x;
+ draw_params.y = y;
+ draw_params.cx = cx;
+ draw_params.cy = cy;
+ draw_params.rgbBk = CLR_NONE;
+ draw_params.rgbFg = CLR_NONE;
+ draw_params.fStyle = draw_flags;
+ draw_params.fState = ILS_NORMAL;
+
+ /* 32bpp image with alpha channel is converted to grayscale */
+ if (imagelist_has_alpha(himl, index))
+ {
+ draw_params.fState = ILS_SATURATE;
+ ImageList_DrawIndirect(&draw_params);
+ return;
+ }
+
/* Create src image */
hdcImage = CreateCompatibleDC(hdc);
hbmImage = CreateCompatibleBitmap(hdc, cx, cy);
SelectObject(hdcImage, hbmImage);
- ImageList_DrawEx(himl, index, hdcImage, 0, 0, cx, cy,
- RGB(0xff, 0xff, 0xff), RGB(0,0,0), draw_flags);
+
+ draw_params.x = 0;
+ draw_params.y = 0;
+ draw_params.rgbBk = RGB(0xff, 0xff, 0xff);
+ draw_params.rgbFg = RGB(0,0,0);
+ draw_params.hdcDst = hdcImage;
+ ImageList_DrawIndirect(&draw_params);
/* Create Mask */
hdcMask = CreateCompatibleDC(0);
@@ -694,8 +721,9 @@ static void TOOLBAR_DrawMasked(HIMAGELIST himl, int index, HDC hdc, INT x, INT y
SelectObject(hdcMask, hbmMask);
/* Remove the background and all white pixels */
- ImageList_DrawEx(himl, index, hdcMask, 0, 0, cx, cy,
- RGB(0xff, 0xff, 0xff), RGB(0,0,0), ILD_MASK);
+ draw_params.fStyle = ILD_MASK;
+ draw_params.hdcDst = hdcMask;
+ ImageList_DrawIndirect(&draw_params);
SetBkColor(hdcImage, RGB(0xff, 0xff, 0xff));
BitBlt(hdcMask, 0, 0, cx, cy, hdcImage, 0, 0, NOTSRCERASE);
--
2.25.1
More information about the wine-devel
mailing list