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
|
wxBitmap bmpSource = bmp; // we need a non-const instance
|
||||||
m_buffer = new unsigned char[bw*bh*4];
|
m_buffer = new unsigned char[bw*bh*4];
|
||||||
wxUint32* data = (wxUint32*)m_buffer;
|
wxUint32* data = (wxUint32*)m_buffer;
|
||||||
|
cairo_format_t bufferFormat;
|
||||||
|
|
||||||
// Create a surface object and copy the bitmap pixel data to it. if the
|
// 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
|
// image has alpha (or a mask represented as alpha) then we'll use a
|
||||||
// different format and iterator than if it doesn't...
|
// different format and iterator than if it doesn't...
|
||||||
if (bmpSource.HasAlpha() || (bmpSource.GetMask()
|
if (bmpSource.GetDepth() == 32
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXGTK__
|
||||||
// this check is needed under wxMSW, but adding this condition to wxGTK
|
|| bmpSource.GetMask()
|
||||||
// causes an assert when getting alpha pixel data, not sure about Mac.
|
|
||||||
&& bmpSource.GetDepth() == 32
|
|
||||||
#endif
|
#endif
|
||||||
))
|
)
|
||||||
{
|
{ // use the bitmap's alpha
|
||||||
m_surface = cairo_image_surface_create_for_data(
|
bufferFormat = CAIRO_FORMAT_ARGB32;
|
||||||
m_buffer, CAIRO_FORMAT_ARGB32, bw, bh, bw*4);
|
|
||||||
wxAlphaPixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
|
wxAlphaPixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
|
||||||
wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data."));
|
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
|
else // no alpha
|
||||||
{
|
{
|
||||||
m_surface = cairo_image_surface_create_for_data(
|
bufferFormat = CAIRO_FORMAT_RGB24;
|
||||||
m_buffer, CAIRO_FORMAT_RGB24, bw, bh, bw*4);
|
|
||||||
wxNativePixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
|
wxNativePixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
|
||||||
wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data."));
|
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);
|
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);
|
m_pattern = cairo_pattern_create_for_surface(m_surface);
|
||||||
#endif // wxHAS_RAW_BITMAP
|
#endif // wxHAS_RAW_BITMAP
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user