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.
This commit is contained in:
Artur Wieczorek
2019-09-12 23:57:08 +02:00
parent 2d15218c9d
commit 64a08c0c9a

View File

@@ -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);