Add real support for monochrome bitmaps to wxMSW
In order to be able to use monochrome bitmaps as wxMask, improve support for them in various ways: 1. Implement loading and saving of monochrome BMP files. 2. Add wxMonoPixelData for direct access to monochrome bitmap pixels. 3. Implement conversion from wxImage to monochrome wxBitmap. Closes https://github.com/wxWidgets/wxWidgets/pull/2032
This commit is contained in:
@@ -70,7 +70,7 @@ public:
|
||||
|
||||
#if wxUSE_WXDIB
|
||||
// Creates a new bitmap (DDB or DIB) from the contents of the given DIB.
|
||||
void CopyFromDIB(const wxDIB& dib);
|
||||
void CopyFromDIB(const wxDIB& dib, int depth = -1);
|
||||
|
||||
// Takes ownership of the given DIB.
|
||||
bool AssignDIB(wxDIB& dib);
|
||||
@@ -318,14 +318,15 @@ void wxBitmapRefData::InitFromDIB(const wxDIB& dib, HBITMAP hbitmap)
|
||||
m_hBitmap = (WXHBITMAP)hbitmap;
|
||||
}
|
||||
|
||||
void wxBitmapRefData::CopyFromDIB(const wxDIB& dib)
|
||||
void wxBitmapRefData::CopyFromDIB(const wxDIB& dib, int depth /* = -1 */)
|
||||
{
|
||||
wxCHECK_RET( !IsOk(), "bitmap already initialized" );
|
||||
wxCHECK_RET( dib.IsOk(), wxT("invalid DIB in CopyFromDIB") );
|
||||
|
||||
HBITMAP hbitmap;
|
||||
#ifdef SOMETIMES_USE_DIB
|
||||
hbitmap = dib.CreateDDB();
|
||||
// MemoryHDC defaults to monochrome
|
||||
hbitmap = dib.CreateDDB(depth == 1 ? HDC(MemoryHDC()) : NULL);
|
||||
#else // ALWAYS_USE_DIB
|
||||
hbitmap = NULL;
|
||||
#endif // SOMETIMES_USE_DIB/ALWAYS_USE_DIB
|
||||
@@ -845,7 +846,7 @@ bool wxBitmap::CreateFromImage(const wxImage& image, int depth, WXHDC hdc)
|
||||
const int h = image.GetHeight();
|
||||
const int w = image.GetWidth();
|
||||
|
||||
wxDIB dib(image);
|
||||
wxDIB dib(image, wxDIB::PixelFormat_PreMultiplied, depth);
|
||||
if ( !dib.IsOk() )
|
||||
return false;
|
||||
|
||||
@@ -1269,7 +1270,7 @@ void wxBitmap::MSWBlendMaskWithAlpha()
|
||||
|
||||
{
|
||||
wxBitmap bmpMask = GetMask()->GetBitmap();
|
||||
wxNativePixelData maskData(bmpMask);
|
||||
wxMonoPixelData maskData(bmpMask);
|
||||
wxCHECK_RET(maskData, "No access to bitmap mask data");
|
||||
|
||||
wxAlphaPixelData bmpData(*this);
|
||||
@@ -1278,17 +1279,17 @@ void wxBitmap::MSWBlendMaskWithAlpha()
|
||||
const int w = GetWidth();
|
||||
const int h = GetHeight();
|
||||
|
||||
wxNativePixelData::Iterator maskRowStart(maskData);
|
||||
wxMonoPixelData::Iterator maskRowStart(maskData);
|
||||
wxAlphaPixelData::Iterator bmpRowStart(bmpData);
|
||||
for ( int y = 0; y < h; y++ )
|
||||
{
|
||||
wxNativePixelData::Iterator pMask = maskRowStart;
|
||||
wxMonoPixelData::Iterator pMask = maskRowStart;
|
||||
wxAlphaPixelData::Iterator pBmp = bmpRowStart;
|
||||
for ( int x = 0; x < w; x++, ++pBmp, ++pMask )
|
||||
{
|
||||
// Masked pixel is not drawn i.e. is transparent,
|
||||
// non-masked pixel is untouched.
|
||||
if ( pMask.Red() == 0 )
|
||||
if ( pMask.Pixel() == 0 )
|
||||
{
|
||||
pBmp.Red() = pBmp.Green() = pBmp.Blue() = 0; // pre-multiplied
|
||||
pBmp.Alpha() = wxALPHA_TRANSPARENT;
|
||||
@@ -1378,6 +1379,12 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
|
||||
// no bitmap, no data (raw or otherwise)
|
||||
return NULL;
|
||||
}
|
||||
if ( bpp == 1 && GetDepth() != 1 )
|
||||
{
|
||||
wxFAIL_MSG( wxT("use wxQuantize if you want to convert color wxBitmap to mono") );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// if we're already a DIB we can access our data directly, but if not we
|
||||
// need to convert this DDB to a DIB section and use it for raw access and
|
||||
@@ -1388,7 +1395,7 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
|
||||
wxCHECK_MSG( !GetBitmapData()->m_dib, NULL,
|
||||
wxT("GetRawData() may be called only once") );
|
||||
|
||||
wxDIB *dib = new wxDIB(*this);
|
||||
wxDIB *dib = new wxDIB(*this, bpp);
|
||||
if ( !dib->IsOk() )
|
||||
{
|
||||
delete dib;
|
||||
@@ -1462,7 +1469,8 @@ void wxBitmap::UngetRawData(wxPixelDataBase& WXUNUSED(data))
|
||||
GetBitmapData()->m_dib = NULL;
|
||||
|
||||
GetBitmapData()->Free();
|
||||
GetBitmapData()->CopyFromDIB(*dib);
|
||||
int depth = GetDepth() == 1 && dib->GetDepth() != GetDepth() ? 1 : -1;
|
||||
GetBitmapData()->CopyFromDIB(*dib, depth);
|
||||
|
||||
delete dib;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user