From 64a08c0c9a463f39122e8762ef190e3a424d93d7 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 12 Sep 2019 23:57:08 +0200 Subject: [PATCH] Fix converting wxBitmap with alpha channel and mask to wxIcon For bitmap with both alpha channel and mask we have to apply mask on our own because 32 bpp icons don't work properly with mask bitmaps. To do so we will create a temporary bitmap with copy of RGB data and with alpha channel being a superposition of the original alpha values and the mask. See #18498. --- src/msw/bitmap.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 077ae40e83..4c34a6d109 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -1780,6 +1780,20 @@ HICON wxBitmapToIconOrCursor(const wxBitmap& bmp, if ( bmp.HasAlpha() ) { + // Make a copy in case we would neeed to remove its mask. + // If this will not be necessary, the copy is cheap as bitmaps are reference-counted. + wxBitmap curBmp(bmp); + + // For bitmap with both alpha channel and mask we have to apply mask on our own + // because 32 bpp icons don't work properly with mask bitmaps. + // To do so we will create a temporary bitmap with copy of RGB data and with alpha channel + // being a superposition of the original alpha values and the mask - for non-masked pixels + // alpha channel values will remain intact and for masked pixels they will be set to the transparent value. + if ( curBmp.GetMask() ) + { + curBmp.MSWBlendMaskWithAlpha(); + } + HBITMAP hbmp; #if wxUSE_WXDIB && wxUSE_IMAGE @@ -1788,17 +1802,17 @@ HICON wxBitmapToIconOrCursor(const wxBitmap& bmp, // a special DIB in such format to pass to it. This is inefficient but // better than creating an icon with wrong colours. AutoHBITMAP hbmpRelease; - hbmp = wxDIB(bmp.ConvertToImage(), + hbmp = wxDIB(curBmp.ConvertToImage(), wxDIB::PixelFormat_NotPreMultiplied).Detach(); hbmpRelease.Init(hbmp); #else // !(wxUSE_WXDIB && wxUSE_IMAGE) - hbmp = GetHbitmapOf(bmp); + hbmp = GetHbitmapOf(curBmp); #endif // wxUSE_WXDIB && wxUSE_IMAGE // Create an empty mask bitmap. // it doesn't seem to work if we mess with the mask at all. AutoHBITMAP - hMonoBitmap(CreateBitmap(bmp.GetWidth(),bmp.GetHeight(),1,1,NULL)); + hMonoBitmap(CreateBitmap(curBmp.GetWidth(),curBmp.GetHeight(),1,1,NULL)); ICONINFO iconInfo; wxZeroMemory(iconInfo);