#18498: wxBitmaps with alpha channel and mask are drawn differently under diffrent
platforms
---------------------+-------------------------
Reporter: awi | Owner:
Type: defect | Status: new
Priority: normal | Milestone:
Component: GUI-all | Version: dev-latest
Keywords: | Blocked By:
Blocking: | Patch: 0
---------------------+-------------------------
32 bpp `wxBitmaps` with both alpha channel and masks are not drawn the
same way under all platforms.
[[Image(bitmap_mask_MSW.png)]] [[Image(bitmap_mask_GTK.png)]]
[[Image(bitmap_mask_OSX.png)]]
It seems that drawing works as expected under `wxGTK3`: both alpha channel
and mask values are taken into account.
Under `wxOSX` it looks like if mask superseded (disabled) alpha channel.
Under `wxMSW` it is hard to tell what is going on.
Here is the patch to minimal sample to demonstrate the issue.
{{{
#!diff
diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index 0d91f7fc75..85fc0a01af 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
@@ -139,6 +139,7 @@ bool MyApp::OnInit()
//
----------------------------------------------------------------------------
// main frame
//
----------------------------------------------------------------------------
+#include "wx/rawbmp.h"
// frame constructor
MyFrame::MyFrame(const wxString& title)
@@ -178,6 +179,116 @@ MyFrame::MyFrame(const wxString& title)
CreateStatusBar(2);
SetStatusText("Welcome to wxWidgets!");
#endif // wxUSE_STATUSBAR
+ int w = 64;
+ int h = 64;
+
+#if defined(__WXOSX__)
+ wxBitmap bmask(w, h, 1);
+ {
+ wxNativePixelData data(bmask);
+ wxNativePixelData::Iterator p(data);
+ for ( int y = 0; y < h; y++ )
+ {
+ unsigned char c = y < h / 2 ? 255 : 0;
+ wxNativePixelData::Iterator rowStart = p;
+ for ( int x = 0; x < w; x++, ++p )
+ {
+ p.Red() = p.Green() = p.Blue() = c;
+ }
+ p = rowStart;
+ p.OffsetY(data, 1);
+ }
+ }
+#else
+ wxBitmap bmask(w, h, 1);
+ {
+ wxMemoryDC dc(bmask);
+ dc.SetBackground(*wxBLACK_BRUSH);
+ dc.Clear();
+ dc.SetPen(*wxWHITE_PEN);
+ dc.SetBrush(*wxWHITE_BRUSH);
+ dc.DrawRectangle(0, 0, w, h / 2);
+ }
+#endif
+
+ wxBitmap bmpAlpha(w, h, 32);
+#if defined(__WXMSW__) || defined(__WXOSX__)
+ bmpAlpha.UseAlpha();
+#endif
+ {
+ wxAlphaPixelData data(bmpAlpha);
+ wxAlphaPixelData::Iterator p(data);
+ for ( int y = 0; y < h; y++ )
+ {
+ wxAlphaPixelData::Iterator rowStart = p;
+ for ( int x = 0; x < w; x++, ++p )
+ {
+ p.Red() = p.Blue() = 0;
+#if defined(__WXMSW__) || defined(__WXOSX__)
+ p.Green() = p.Alpha() = x < w / 2 ? 255 : 92;
+#else
+ p.Green() = 255;
+ p.Alpha() = x < w / 2 ? 255 : 92;
+#endif
+ }
+ p = rowStart;
+ p.OffsetY(data, 1);
+ }
+ }
+ wxASSERT(bmpAlpha.HasAlpha());
+ wxASSERT(!bmpAlpha.GetMask());
+ wxBitmap bmpAlphaMasked(bmpAlpha);
+ bmpAlphaMasked.SetMask(new wxMask(bmask));
+ wxASSERT(bmpAlphaMasked.HasAlpha());
+ wxASSERT(bmpAlphaMasked.GetMask());
+
+ wxBitmap bmp(w, h, 24);
+ {
+ wxMemoryDC dc(bmp);
+ dc.SetPen(*wxBLUE_PEN);
+ dc.SetBrush(*wxBLUE_BRUSH);
+ dc.DrawRectangle(0, 0, w / 2, h);
+ dc.SetPen(*wxRED_PEN);
+ dc.SetBrush(*wxRED_BRUSH);
+ dc.DrawRectangle(w / 2, 0, w / 2, h);
+ }
+ wxASSERT(!bmp.HasAlpha());
+ wxASSERT(!bmp.GetMask());
+ wxBitmap bmpMasked(bmp);
+ bmpMasked.SetMask(new wxMask(bmask));
+ wxASSERT(!bmpMasked.HasAlpha());
+ wxASSERT(bmpMasked.GetMask());
+
+ wxBitmap bmpOut(300, 200, 24);
+ {
+ wxMemoryDC dc(bmpOut);
+ dc.SetBackground(*wxGREY_BRUSH);
+ dc.Clear();
+
+ dc.DrawBitmap(bmpAlpha, wxPoint(20, 20), true);
+ dc.DrawBitmap(bmask, wxPoint(110, 20), true);
+ dc.DrawBitmap(bmpAlphaMasked, wxPoint(200, 20), true);
+
+ dc.DrawBitmap(bmp, wxPoint(20, 110), true);
+ dc.DrawBitmap(bmask, wxPoint(110, 110), true);
+ dc.DrawBitmap(bmpMasked, wxPoint(200, 110), true);
+ }
+
+ wxPanel* p = new wxPanel(this);
+
+ new wxStaticText(p, wxID_ANY, "bitmap", wxPoint(20, 0));
+ new wxStaticText(p, wxID_ANY, "mask", wxPoint(110, 0));
+ new wxStaticText(p, wxID_ANY, "bitmap+mask", wxPoint(200, 0));
+
+ new wxStaticBitmap(p, wxID_ANY, bmpAlpha, wxPoint(20, 20));
+ new wxStaticBitmap(p, wxID_ANY, bmask, wxPoint(110, 20));
+ new wxStaticBitmap(p, wxID_ANY, bmpAlphaMasked, wxPoint(200, 20));
+
+ new wxStaticBitmap(p, wxID_ANY, bmp, wxPoint(20, 110));
+ new wxStaticBitmap(p, wxID_ANY, bmask, wxPoint(110, 110));
+ new wxStaticBitmap(p, wxID_ANY, bmpMasked, wxPoint(200, 110));
+
+ new wxStaticBitmap(p, wxID_ANY, bmpOut, wxPoint(0, 200));
}
}}}
--
Ticket URL: <
https://trac.wxwidgets.org/ticket/18498>