Improve drawing of monochrome bitmaps with masks in wxMSW.
This is a compromise solution between r78040, which handled monochrome bitmaps correctly, but broke drawing bitmaps without using their mask, and r78054 which simply reverted it: this version preserves the old behaviour when not using the mask, but draws at least the shape (if not the colour) correctly for the monochrome bitmaps. Notice that this also reverts r78039 which is not needed any more without r78040. Closes #16512. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78123 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -55,6 +55,9 @@
|
||||
#define CLR_INVALID ((COLORREF)-1)
|
||||
#endif // no CLR_INVALID
|
||||
|
||||
// ROP which doesn't have standard name
|
||||
#define DSTERASE 0x00220326 // dest = (NOT src) AND dest
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxBitmapRefData
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -513,7 +516,6 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
||||
// AND mask: 0 <= y <= h-1
|
||||
// XOR mask: h <= y <= 2*h-1
|
||||
// First we need to extract and store XOR mask from this bitmap.
|
||||
// AND mask will be extracted later at creation of inverted mask.
|
||||
HBITMAP hbmp = ::CreateBitmap(w, h, 1, wxDisplayDepth(), NULL);
|
||||
if ( !hbmp )
|
||||
{
|
||||
@@ -531,6 +533,18 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
||||
{
|
||||
wxLogLastError(wxT("wxBitmap::CopyFromIconOrCursor - BitBlt"));
|
||||
}
|
||||
// Prepare the AND mask to be compatible with wxBitmap mask
|
||||
// by seting its bits to 0 wherever XOR mask (image) bits are set to 1.
|
||||
// This is done in-place by applying the following ROP:
|
||||
// dest = dest AND (NOT src) where dest=AND mask, src=XOR mask
|
||||
//
|
||||
// AND mask will be extracted later at creation of inverted mask.
|
||||
if ( !::BitBlt((HDC)dcSrc, 0, 0, w, h,
|
||||
(HDC)dcSrc, 0, h,
|
||||
DSTERASE) )
|
||||
{
|
||||
wxLogLastError(wxT("wxBitmap::CopyFromIconOrCursor - BitBlt"));
|
||||
}
|
||||
}
|
||||
refData->m_width = w;
|
||||
refData->m_height = h;
|
||||
@@ -1908,6 +1922,21 @@ HICON wxBitmapToIconOrCursor(const wxBitmap& bmp,
|
||||
iconInfo.hbmMask = hbmpMask;
|
||||
iconInfo.hbmColor = GetHbitmapOf(bmp);
|
||||
|
||||
// black out the transparent area to preserve background colour, because
|
||||
// Windows blits the original bitmap using SRCINVERT (XOR) after applying
|
||||
// the mask to the dest rect.
|
||||
{
|
||||
MemoryHDC dcSrc, dcDst;
|
||||
SelectInHDC selectMask(dcSrc, (HBITMAP)mask->GetMaskBitmap()),
|
||||
selectBitmap(dcDst, iconInfo.hbmColor);
|
||||
|
||||
if ( !::BitBlt(dcDst, 0, 0, bmp.GetWidth(), bmp.GetHeight(),
|
||||
dcSrc, 0, 0, SRCAND) )
|
||||
{
|
||||
wxLogLastError(wxT("BitBlt"));
|
||||
}
|
||||
}
|
||||
|
||||
HICON hicon = ::CreateIconIndirect(&iconInfo);
|
||||
|
||||
if ( !bmp.GetMask() && !bmp.HasAlpha() )
|
||||
|
Reference in New Issue
Block a user