Use wxAlphaPixelData if the source bitmap depth is 32 or if on wxGTK and there is a mask. Add a separate pass on MSW if there is a mask to adjust the cairo surface's alpha to match the mask.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69253 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1089,20 +1089,18 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm
|
||||
wxBitmap bmpSource = bmp; // we need a non-const instance
|
||||
m_buffer = new unsigned char[bw*bh*4];
|
||||
wxUint32* data = (wxUint32*)m_buffer;
|
||||
cairo_format_t bufferFormat;
|
||||
|
||||
// Create a surface object and copy the bitmap pixel data to it. if the
|
||||
// image has alpha (or a mask represented as alpha) then we'll use a
|
||||
// different format and iterator than if it doesn't...
|
||||
if (bmpSource.HasAlpha() || (bmpSource.GetMask()
|
||||
#ifdef __WXMSW__
|
||||
// this check is needed under wxMSW, but adding this condition to wxGTK
|
||||
// causes an assert when getting alpha pixel data, not sure about Mac.
|
||||
&& bmpSource.GetDepth() == 32
|
||||
if (bmpSource.GetDepth() == 32
|
||||
#ifdef __WXGTK__
|
||||
|| bmpSource.GetMask()
|
||||
#endif
|
||||
))
|
||||
{
|
||||
m_surface = cairo_image_surface_create_for_data(
|
||||
m_buffer, CAIRO_FORMAT_ARGB32, bw, bh, bw*4);
|
||||
)
|
||||
{ // use the bitmap's alpha
|
||||
bufferFormat = CAIRO_FORMAT_ARGB32;
|
||||
wxAlphaPixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
|
||||
wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data."));
|
||||
|
||||
@@ -1133,8 +1131,7 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm
|
||||
}
|
||||
else // no alpha
|
||||
{
|
||||
m_surface = cairo_image_surface_create_for_data(
|
||||
m_buffer, CAIRO_FORMAT_RGB24, bw, bh, bw*4);
|
||||
bufferFormat = CAIRO_FORMAT_RGB24;
|
||||
wxNativePixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
|
||||
wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data."));
|
||||
|
||||
@@ -1156,6 +1153,38 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm
|
||||
p.OffsetY(pixData, 1);
|
||||
}
|
||||
}
|
||||
#ifdef __WXMSW__
|
||||
// if there is a mask, set the alpha bytes in the target buffer to
|
||||
// fully transparent or fully opaque
|
||||
if (bmpSource.GetMask())
|
||||
{
|
||||
wxBitmap bmpMask = bmpSource.GetMaskBitmap();
|
||||
bufferFormat = CAIRO_FORMAT_ARGB32;
|
||||
data = (wxUint32*)m_buffer;
|
||||
wxNativePixelData pixData(bmpMask, wxPoint(0,0), wxSize(bw, bh));
|
||||
wxCHECK_RET( pixData, wxT("Failed to gain raw access to mask bitmap data."));
|
||||
|
||||
wxNativePixelData::Iterator p(pixData);
|
||||
for (int y=0; y<bh; y++)
|
||||
{
|
||||
wxNativePixelData::Iterator rowStart = p;
|
||||
for (int x=0; x<bw; x++)
|
||||
{
|
||||
if (p.Red()+p.Green()+p.Blue() == 0)
|
||||
*data = 0;
|
||||
else
|
||||
*data = (wxALPHA_OPAQUE << 24) | (*data & 0x00FFFFFF);
|
||||
++data;
|
||||
++p;
|
||||
}
|
||||
p = rowStart;
|
||||
p.OffsetY(pixData, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_surface = cairo_image_surface_create_for_data(
|
||||
m_buffer, bufferFormat, bw, bh, bw*4);
|
||||
m_pattern = cairo_pattern_create_for_surface(m_surface);
|
||||
#endif // wxHAS_RAW_BITMAP
|
||||
}
|
||||
|
Reference in New Issue
Block a user