wxMemoryDC bitmap mask fails after drawing bitmap with alpha on in. (Issue #23532)

56 views
Skip to first unread message

BrutalSoloH

unread,
May 8, 2023, 7:57:10 AM5/8/23
to wx-...@googlegroups.com, Subscribed

Description

Using wxMemoryDC and a bitmap with a mask as a drawing buffer. When you draw a bitmap or image with alpha channel enabled, the mask will not work anymore. It works on Mac, but not on Windows.

You would expect to see a red rounded rectangle, but you see it completely filled with red. If you change the below code create_bug = true to false, it will show correctly, except the icon will not have alpha channel.

Add the following function to the minimal sample:

#include "../sample.xpm"

void MyFrame::OnPaint(wxPaintEvent& /* event */)
{
    wxPaintDC dc(this);

    const wxSize size = GetClientSize();
 
    if (size.x <= 0 || size.y <= 0)
        return;

    wxMemoryDC memdc;

    // create a rounded mask
    wxBitmap maskBitmap(size.x, size.y);
    memdc.SelectObject(maskBitmap);
    memdc.SetBackground(*wxWHITE_BRUSH);
    memdc.Clear();
    memdc.SetPen(*wxBLACK_PEN);
    memdc.SetBrush(*wxBLACK_BRUSH);
    const int arc = size.x / 4; // for drawing rounded boxes
    memdc.DrawRoundedRectangle(0, 0, size.x, size.y, arc);
    memdc.SelectObject(wxNullBitmap);

    // create the masked double buffer
    wxBitmap bufferBitmap(size.x, size.y);

    if (maskBitmap.IsOk()) {
        bufferBitmap.SetMask(new wxMask(maskBitmap, *wxWHITE)); // mask will be deleted by bitmap.
    }

    // now let's draw on the bitmap which has a rounded mask
    memdc.SelectObject(bufferBitmap);
    memdc.Clear();

    // fill it in with red
    memdc.SetPen(*wxBLACK_PEN);
    memdc.SetBrush(*wxRED_BRUSH);
    memdc.DrawRectangle(0, 0, size.x, size.y);

    // draw an img in the middle.
    wxImage img(sample_xpm);

    // as soon as you initialize the alpha and draw it into the masked buffer,
    // the mask of the buffer will get destroyed or something like that.
    bool create_bug = true;
    if (create_bug) {
        img.InitAlpha();
    }
 
    // center the image
    memdc.DrawBitmap(img, (size.x - img.GetSize().x) / 2, (size.y - img.GetSize().y) / 2);

    dc.Blit(wxPoint(0, 0), size, &memdc, wxPoint(0, 0), wxCOPY, true);

    memdc.SelectObject(wxNullBitmap);
}

Don't forget to include

   EVT_PAINT(MyFrame::OnPaint)

to the event table.

Platform and version information

  • wxWidgets version you use: 3.2.2
  • wxWidgets port you use: wxMSW
  • OS and its version: Windows 11 ARM


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23532@github.com>

PB

unread,
May 8, 2023, 8:23:43 AM5/8/23
to wx-...@googlegroups.com, Subscribed

Are you aware that wxDC on MSW does not support alpha (it uses GDI, which is utterly alpha unaware)?

From wxDC docs:

In general wxDC methods don't support alpha transparency and the alpha component of wxColour is simply ignored and you need to use wxGraphicsContext for full transparency support. There are, however, a few exceptions: first, under macOS and GTK+ 3 colours with alpha channel are supported in all the normal wxDC-derived classes as they use wxGraphicsContext internally.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23532/1538273359@github.com>

VZ

unread,
May 8, 2023, 9:36:32 AM5/8/23
to wx-...@googlegroups.com, Subscribed

I agree that using wxDC with alpha and mask is not really a supported scenario. It might be possible to make it work by converting mask to alpha and if anybody is willing to work on this, why not, but I'd recommend using wxGraphicsContext if you're doing anything involving alpha.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23532/1538374740@github.com>

BrutalSoloH

unread,
May 8, 2023, 10:48:37 AM5/8/23
to wx-...@googlegroups.com, Subscribed

The strange thing is that I use a buffer (bitmap) with mask to draw to the wxDC. That works fine. It just fails when you draw a bitmap with alpha to that buffer.
If I use a triple buffer system, like wxBitmap with alpha ----draw---> wxBitmap ---draw--> wxBitmap with mask --blit--> DC
it will work.

Thanks for the replies, will look to wxGraphicsContext.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/23532/1538485785@github.com>

Reply all
Reply to author
Forward
0 new messages