From d4c83e1cbcfe97064d7a9e95f3cdbcf412ca70a9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 2 Feb 2022 22:36:00 +0000 Subject: [PATCH] Ensure that a copy of a DIB wxBitmap remains a DIB in wxMSW Creating a DDB from DIB with alpha doesn't work correctly due to using premultiplied alpha for the latter, but not for the former, and while we could convert it, it seems to be even better to just preserve the type of the original bitmap, as this would seem to be expected when making a copy, after all. This commit is best viewed ignoring whitespace-only changes. --- src/msw/bitmap.cpp | 48 ++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index d490d88922..ae48064330 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -232,24 +232,40 @@ wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData& data) if ( data.m_hBitmap ) { wxDIB dib((HBITMAP)(data.m_hBitmap)); - // DDB obtained from CopyFromDIB() can have different - // colour depth than source DIB so we need to check it. - CopyFromDIB(dib); - if ( m_depth != dib.GetDepth() ) + + // Cloning a DIB should create a DIB, while cloning a DDB should create + // a DDB, so check what do we have. + if ( data.m_isDIB ) { - // We got DDB with a different colour depth than we wanted, so we - // can't use it and need to continue using the DIB instead. - wxDIB dibDst(m_width, m_height, dib.GetDepth()); - if ( dibDst.IsOk() ) + const int w = dib.GetWidth(); + const int h = dib.GetHeight(); + const int d = dib.GetDepth(); + + wxDIB dibDst(w, h, d); + memcpy(dibDst.GetData(), dib.GetData(), wxDIB::GetLineSize(w, d)*h); + InitFromDIB(dibDst); + } + else + { + // DDB obtained from CopyFromDIB() can have different + // colour depth than source DIB so we need to check it. + CopyFromDIB(dib); + if ( m_depth != dib.GetDepth() ) { - m_depth = dib.GetDepth(); - memcpy(dibDst.GetData(), dib.GetData(), - wxDIB::GetLineSize(m_width, m_depth)*m_height); - AssignDIB(dibDst); - } - else - { - // Nothing else left to do... + // We got DDB with a different colour depth than we wanted, so we + // can't use it and need to continue using the DIB instead. + wxDIB dibDst(m_width, m_height, dib.GetDepth()); + if ( dibDst.IsOk() ) + { + m_depth = dib.GetDepth(); + memcpy(dibDst.GetData(), dib.GetData(), + wxDIB::GetLineSize(m_width, m_depth)*m_height); + AssignDIB(dibDst); + } + else + { + // Nothing else left to do... + } } } }