// Adds a bitmap, and optionally a mask bitmap. // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap' and 'mask'. int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask) { HBITMAP hbmp; #if wxUSE_WXDIB && wxUSE_IMAGE // wxBitmap normally stores alpha in pre-multiplied format but // ImageList_Draw() does pre-multiplication internally so we need to undo // the pre-multiplication here. Converting back and forth like this is, of // course, very inefficient but it's better than wrong appearance so we do // this for now until a better way can be found. AutoHBITMAP hbmpRelease; if ( bitmap.HasAlpha() ) { hbmp = wxDIB(bitmap.ConvertToImage(), wxDIB::PixelFormat_NotPreMultiplied).Detach(); hbmpRelease.Init(hbmp); } else #endif // wxUSE_WXDIB && wxUSE_IMAGE hbmp = GetHbitmapOf(bitmap); // Use mask only if we don't have alpha, the bitmap isn't drawn correctly // if we use both. AutoHBITMAP hbmpMask; if ( !bitmap.HasAlpha() ) hbmpMask.Init(GetMaskForImage(bitmap, mask)); int index = ImageList_Add(GetHImageList(), hbmp, hbmpMask); if ( index == -1 ) { wxLogError(_("Couldn't add an image to the image list.")); } return index; }
// Replaces a bitmap, optionally passing a mask bitmap. // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap' and 'mask'. bool wxImageList::Replace(int index, const wxBitmap& bitmap, const wxBitmap& mask) { HBITMAP hbmp; #if wxUSE_WXDIB && wxUSE_IMAGE // See the comment in Add() above. AutoHBITMAP hbmpRelease; if ( bitmap.HasAlpha() ) { hbmp = wxDIB(bitmap.ConvertToImage(), wxDIB::PixelFormat_NotPreMultiplied).Detach(); hbmpRelease.Init(hbmp); } else #endif // wxUSE_WXDIB && wxUSE_IMAGE hbmp = GetHbitmapOf(bitmap); AutoHBITMAP hbmpMask(GetMaskForImage(bitmap, mask)); if ( !ImageList_Replace(GetHImageList(), index, hbmp, hbmpMask) ) { wxLogLastError(wxT("ImageList_Replace()")); return false; } return true; }
// Adds a bitmap, using the specified colour to create the mask bitmap // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap'. int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour) { HBITMAP hbmp; #if wxUSE_WXDIB && wxUSE_IMAGE // See the comment in overloaded Add() above. AutoHBITMAP hbmpRelease; if ( bitmap.HasAlpha() ) { hbmp = wxDIB(bitmap.ConvertToImage(), wxDIB::PixelFormat_NotPreMultiplied).Detach(); hbmpRelease.Init(hbmp); } else #endif // wxUSE_WXDIB && wxUSE_IMAGE hbmp = GetHbitmapOf(bitmap); int index = ImageList_AddMasked(GetHImageList(), hbmp, wxColourToRGB(maskColour)); if ( index == -1 ) { wxLogError(_("Couldn't add an image to the image list.")); } return index; }
bool wxDIB::Create(const wxBitmap& bmp) { wxCHECK_MSG( bmp.Ok(), false, wxT("wxDIB::Create(): invalid bitmap") ); if ( !Create(GetHbitmapOf(bmp)) ) return false; m_hasAlpha = bmp.HasAlpha(); return true; }
// Adds a bitmap, and optionally a mask bitmap. // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap' and 'mask'. int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask) { HBITMAP hbmp; bool useMask; #if wxUSE_WXDIB && wxUSE_IMAGE // wxBitmap normally stores alpha in pre-multiplied format but // ImageList_Draw() does pre-multiplication internally so we need to undo // the pre-multiplication here. Converting back and forth like this is, of // course, very inefficient but it's better than wrong appearance so we do // this for now until a better way can be found. AutoHBITMAP hbmpRelease; if ( bitmap.HasAlpha() ) { wxImage img = bitmap.ConvertToImage(); // For comctl32.dll < 6 remove alpha channel from image // to prevent possible interferences with the mask. if ( wxApp::GetComCtl32Version() < 600 ) { img.ClearAlpha(); useMask = true; } else { useMask = false; } hbmp = wxDIB(img, wxDIB::PixelFormat_NotPreMultiplied).Detach(); hbmpRelease.Init(hbmp); } else #endif // wxUSE_WXDIB && wxUSE_IMAGE { hbmp = GetHbitmapOf(bitmap); useMask = true; } // Use mask only if we don't have alpha, the bitmap isn't drawn correctly // if we use both. AutoHBITMAP hbmpMask; if ( useMask ) hbmpMask.Init(GetMaskForImage(bitmap, mask)); int index = ImageList_Add(GetHImageList(), hbmp, hbmpMask); if ( index == -1 ) { wxLogError(_("Couldn't add an image to the image list.")); } return index; }
// Replaces a bitmap, optionally passing a mask bitmap. // Note that wxImageList creates new bitmaps, so you may delete // 'bitmap' and 'mask'. bool wxImageList::Replace(int index, const wxBitmap& bitmap, const wxBitmap& mask) { HBITMAP hbmp; bool useMask; #if wxUSE_WXDIB && wxUSE_IMAGE // See the comment in Add() above. AutoHBITMAP hbmpRelease; if ( bitmap.HasAlpha() ) { wxImage img = bitmap.ConvertToImage(); if ( wxApp::GetComCtl32Version() < 600 ) { img.ClearAlpha(); useMask = true; } else { useMask = false; } hbmp = wxDIB(img, wxDIB::PixelFormat_NotPreMultiplied).Detach(); hbmpRelease.Init(hbmp); } else #endif // wxUSE_WXDIB && wxUSE_IMAGE { hbmp = GetHbitmapOf(bitmap); useMask = true; } AutoHBITMAP hbmpMask; if ( useMask ) hbmpMask.Init(GetMaskForImage(bitmap, mask)); if ( !ImageList_Replace(GetHImageList(), index, hbmp, hbmpMask) ) { wxLogLastError(wxT("ImageList_Replace()")); return false; } return true; }
void wxGenericColourDialog::DoPreviewBitmap(wxBitmap& bmp, const wxColour& colour) { if ( bmp.HasAlpha() && colour.Alpha() != wxALPHA_OPAQUE ) { // For real ARGB draw a chessboard grid // with actual ARGB fields and reference RGB fields. const int w = bmp.GetWidth(); const int h = bmp.GetHeight(); // Calculate field size: 4 fields per row/column, // with size in range [2..10] int dx = wxMax(wxMin(w / 4, 10), 2); int dy = wxMax(wxMin(h / 4, 10), 2); // We want a square field dx = wxMax(dx, dy); dy = dx; // Prepare opaque colour wxColour colourRGB(colour.Red(), colour.Green(), colour.Blue(), wxALPHA_OPAQUE); { wxBrush brushARGB(colour); wxBrush brushRGB(colourRGB); wxMemoryDC mdc(bmp); { wxGCDC gdc(mdc); gdc.SetPen(*wxTRANSPARENT_PEN); for (int x = 0, ix = 0; x < w; x += dx, ix++) { for (int y = 0, iy = 0; y < h; y += dy, iy++) { if ( (ix+iy) % 2 == 0 ) { gdc.SetBrush(brushARGB); } else { gdc.SetBrush(brushRGB); } gdc.DrawRectangle(x, y, dx, dy); } } // Draw a frame gdc.SetPen(*wxBLACK_PEN); gdc.SetBrush(*wxTRANSPARENT_BRUSH); gdc.DrawRectangle(0, 0, w, h); } } } else { wxMemoryDC mdc(bmp); // Fill with custom colour wxBrush brush(colour); mdc.SetPen(*wxBLACK_PEN); mdc.SetBrush(brush); mdc.DrawRectangle(wxPoint(0, 0), bmp.GetSize()); } }