- 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 = 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 (alpha == 0)
- *data = 0;
- else
- *data = ( alpha/255 << 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 = 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);
- }
- }
-
-
- cairo_save(m_cairo);
- // In case we're scaling the image by using a width and height different
- // than the bitmap's size create a pattern transformation on the surface and
- // draw the transformed pattern.
- cairo_pattern_t* pattern = cairo_pattern_create_for_surface(surface);
-
- // Prepare to draw the image.
- cairo_translate(m_cairo, x, y);
- cairo_set_source(m_cairo, pattern);
- // Use the original size here since the context is scaled already.
- cairo_rectangle(m_cairo, 0, 0, bw, bh);
- // Fill the rectangle using the pattern.
- cairo_fill(m_cairo);
-
- // Clean up.
- cairo_pattern_destroy(pattern);
- cairo_surface_destroy(surface);
- delete [] buffer;
-
- CalcBoundingBox(0,0);
- CalcBoundingBox(bw,bh);
-
- cairo_restore(m_cairo);
-}
-
-// wxGtkPrintDC has a constant resolution of 72dpi. If we want an higher resolution for printing
-// an image, the scaling has to be done by cairo.
-void wxGtkPrintDC::DoDrawScaledBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, wxCoord w, wxCoord h, bool useMask, int quality )
-{
- wxCHECK_RET( bitmap.IsOk(), wxT("Invalid bitmap in wxGtkPrintDC::DoDrawBitmap"));
-
- cairo_surface_t* surface;
- int bw = bitmap.GetWidth();
- int bh = bitmap.GetHeight();
- x = LogicalToDeviceX(x);
- y = LogicalToDeviceY(y);
- w = LogicalToDeviceXRel(w);
- h = LogicalToDeviceYRel(h);
- wxBitmap bmpSource = bitmap; // we need a non-const instance.
- unsigned char* buffer = new unsigned char[bw*bh*4];
- wxUint32* data = (wxUint32*)buffer;
-
- // 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())
- {
- surface = 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 (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 = 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);
- }
- }
-