- unsigned char* buffer = new unsigned char[bw*bh*4];
- wxUint32* data = (wxUint32*)buffer;
-
- wxMask *mask = NULL;
- if (useMask) mask = bmpSource.GetMask();
-
- // 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() || mask)
- {
- surface = gs_cairo->cairo_image_surface_create_for_data(
- buffer, CAIRO_FORMAT_ARGB32, bw, bh, bw*4);
- wxAlphaPixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
- wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data."));
-
- wxAlphaPixelData::Iterator p(pixData);
- int y, x;
- for (y=0; y<bh; y++)
- {
- wxAlphaPixelData::Iterator rowStart = p;
- for (x=0; x<bw; 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 = p.Alpha();
-
- if (!bmpSource.HasAlpha() && mask)
- alpha = 255;
-
- if (alpha == 0)
- *data = 0;
- else
- *data = ( alpha << 24
- | (p.Red() * alpha/255) << 16
- | (p.Green() * alpha/255) << 8
- | (p.Blue() * alpha/255) );
- ++data;
- ++p;
- }
- p = rowStart;
- p.OffsetY(pixData, 1);
- }
- }
- else // no alpha
- {
- surface = gs_cairo->cairo_image_surface_create_for_data(
- buffer, CAIRO_FORMAT_RGB24, bw, bh, bw*4);
- wxNativePixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh));
- wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data."));
-
- wxNativePixelData::Iterator p(pixData);
- int y, x;
- for (y=0; y<bh; y++)
- {
- wxNativePixelData::Iterator rowStart = p;
- for (x=0; x<bw; x++)
- {
- // Each pixel in CAIRO_FORMAT_RGB24 is a 32-bit quantity, with
- // the upper 8 bits unused. Red, Green, and Blue are stored in
- // the remaining 24 bits in that order. The 32-bit quantities
- // are stored native-endian.
- *data = ( p.Red() << 16 | p.Green() << 8 | p.Blue() );
- ++data;
- ++p;
- }
- p = rowStart;
- p.OffsetY(pixData, 1);
- }
- }