Fixed creating Cairo bitmap from wxBitmap (wxMSW).

Iterating over bit values with wxAlphaPixelData sets the internal wxBitmap's "has alpha" flag but we want to left it unchanged so we have to save its original value and restore it afterward.
This commit is contained in:
Artur Wieczorek
2016-04-11 18:06:42 +02:00
parent bac5975b02
commit 0ee25aaa76

View File

@@ -1414,43 +1414,57 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm
if ( isSrcBpp32 ) if ( isSrcBpp32 )
{ {
// use the bitmap's alpha // Using wxAlphaPixelData sets (on wxMSW and wxOSX) the internal
wxAlphaPixelData // "has alpha" flag but we want to leave it unchanged, so we need
pixData(bmpSource, wxPoint(0, 0), wxSize(m_width, m_height)); // to save its current value now and restore it afterwards.
wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data.")); #if defined(__WXMSW__) || defined(__WXOSX__)
const bool hasAlpha = bmpSource.HasAlpha();
#endif // __WXMSW__ || __WXOSX__
wxAlphaPixelData::Iterator p(pixData);
for (int y=0; y<m_height; y++)
{ {
wxAlphaPixelData::Iterator rowStart = p; // use the bitmap's alpha
wxUint32* const rowStartDst = data; wxAlphaPixelData pixData(bmpSource);
for (int x=0; x<m_width; x++) wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data."));
{
// Each pixel in CAIRO_FORMAT_ARGB32 is a 32-bit quantity,
// with alpha in the upper 8 bits, then red, then green, then
// blue. The 32-bit quantities are stored native-endian.
// Pre-multiplied alpha is used.
unsigned char alpha = (bufferFormat == CAIRO_FORMAT_ARGB32) ? p.Alpha() : 255;
#ifdef __WXMSW__
// MSW bitmap pixel bits are already premultiplied.
*data = (alpha << 24 | p.Red() << 16 | p.Green() << 8 | p.Blue());
#else // !__WXMSW__
if (alpha == 0)
*data = 0;
else
*data = (alpha << 24
| Premultiply(alpha, p.Red()) << 16
| Premultiply(alpha, p.Green()) << 8
| Premultiply(alpha, p.Blue()));
#endif // __WXMSW__ / !__WXMSW__
++data;
++p;
}
data = rowStartDst + stride / 4; wxAlphaPixelData::Iterator p(pixData);
p = rowStart; for (int y=0; y<m_height; y++)
p.OffsetY(pixData, 1); {
wxAlphaPixelData::Iterator rowStart = p;
wxUint32* const rowStartDst = data;
for (int x=0; x<m_width; x++)
{
// Each pixel in CAIRO_FORMAT_ARGB32 is a 32-bit quantity,
// with alpha in the upper 8 bits, then red, then green, then
// blue. The 32-bit quantities are stored native-endian.
// Pre-multiplied alpha is used.
unsigned char alpha = (bufferFormat == CAIRO_FORMAT_ARGB32) ? p.Alpha() : 255;
#ifdef __WXMSW__
// MSW bitmap pixel bits are already premultiplied.
*data = (alpha << 24 | p.Red() << 16 | p.Green() << 8 | p.Blue());
#else // !__WXMSW__
if (alpha == 0)
*data = 0;
else
*data = (alpha << 24
| Premultiply(alpha, p.Red()) << 16
| Premultiply(alpha, p.Green()) << 8
| Premultiply(alpha, p.Blue()));
#endif // __WXMSW__ / !__WXMSW__
++data;
++p;
}
data = rowStartDst + stride / 4;
p = rowStart;
p.OffsetY(pixData, 1);
}
} }
#if defined(__WXMSW__) || defined(__WXOSX__)
// Reset "has alpha" flag back.
// (wxBitmap::UseAlpha() is used only on wxMSW and wxOSX.)
bmpSource.UseAlpha(hasAlpha);
#endif // __WXMSW__ || __WXOSX__
} }
else // no alpha else // no alpha
{ {