Fix value returned by wxBitmap::GetDepth() in wxMSW
Some operations on wxBitmap involve converting the internal representation from DIB to DDB, and when this is done it can happen that the resulting DDB will have different colour depth than source DIB because CreateDIBitmap() Windows API which is used for conversion purposes can create DDB with "whatever bit depth your reference DC is". Therefore after every operation which directly or indirectly employs CreateDIBitmap() it is necessary to update respective data member with the actual color depth of the obtained DDB. Closes #17479. Closes https://github.com/wxWidgets/wxWidgets/pull/265
This commit is contained in:
parent
8006c4fed1
commit
ae1a332d1f
@ -240,19 +240,17 @@ 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);
|
||||
BITMAP bm;
|
||||
if ( ::GetObject(m_hBitmap, sizeof(bm), &bm) != sizeof(bm) )
|
||||
if ( m_depth != dib.GetDepth() )
|
||||
{
|
||||
wxLogLastError(wxT("GetObject(hBitmap@wxBitmapRefData)"));
|
||||
}
|
||||
else if ( m_depth != bm.bmBitsPixel )
|
||||
{
|
||||
// We got DDB with a different colour depth then we wanted, so we
|
||||
// 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, m_depth);
|
||||
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);
|
||||
@ -260,7 +258,6 @@ wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData& data)
|
||||
else
|
||||
{
|
||||
// Nothing else left to do...
|
||||
m_depth = bm.bmBitsPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -337,6 +334,21 @@ void wxBitmapRefData::CopyFromDIB(const wxDIB& dib)
|
||||
#endif // SOMETIMES_USE_DIB/ALWAYS_USE_DIB
|
||||
|
||||
InitFromDIB(dib, hbitmap);
|
||||
if ( hbitmap )
|
||||
{
|
||||
// DDB obtained from CreatedDDB() can have different colour depth
|
||||
// than source DIB and we have to adjust respective data member
|
||||
// accordingly.
|
||||
BITMAP bm;
|
||||
if ( ::GetObject(hbitmap, sizeof(bm), &bm) != sizeof(bm) )
|
||||
{
|
||||
wxLogLastError(wxS("GetObject (@wxBitmapRefData::CopyFromDIB)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_depth = bm.bmBitsPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool wxBitmapRefData::AssignDIB(wxDIB& dib)
|
||||
@ -871,6 +883,18 @@ bool wxBitmap::CreateFromImage(const wxImage& image, int depth, WXHDC hdc)
|
||||
else // we need to convert DIB to DDB
|
||||
{
|
||||
hbitmap = dib.CreateDDB((HDC)hdc);
|
||||
// DDB obtained from CreatedDDB() can have different colour depth
|
||||
// than source DIB and we have to adjust respective data member
|
||||
// accordingly.
|
||||
BITMAP bm;
|
||||
if ( ::GetObject(hbitmap, sizeof(bm), &bm) != sizeof(bm) )
|
||||
{
|
||||
wxLogLastError(wxS("GetObject (@wxBitmap::CreateFromImage)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
refData->m_depth = bm.bmBitsPixel;
|
||||
}
|
||||
}
|
||||
#endif // !ALWAYS_USE_DIB
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user