summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/cairo/ImageBufferCairo.cpp')
-rw-r--r--WebCore/platform/graphics/cairo/ImageBufferCairo.cpp54
1 files changed, 52 insertions, 2 deletions
diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index d2652d6..c905ee8 100644
--- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -39,9 +39,29 @@
#include <cairo.h>
#include <wtf/Vector.h>
+#include <math.h>
using namespace std;
+// Cairo doesn't provide a way to copy a cairo_surface_t.
+// See http://lists.cairographics.org/archives/cairo/2007-June/010877.html
+// Once cairo provides the way, use the function instead of this.
+static inline cairo_surface_t* copySurface(cairo_surface_t* surface)
+{
+ cairo_format_t format = cairo_image_surface_get_format(surface);
+ int width = cairo_image_surface_get_width(surface);
+ int height = cairo_image_surface_get_height(surface);
+ cairo_surface_t* newsurface = cairo_image_surface_create(format, width, height);
+
+ cairo_t* cr = cairo_create(newsurface);
+ cairo_set_source_surface(cr, surface, 0, 0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+
+ return newsurface;
+}
+
namespace WebCore {
ImageBufferData::ImageBufferData(const IntSize& size)
@@ -49,7 +69,7 @@ ImageBufferData::ImageBufferData(const IntSize& size)
{
}
-ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, bool& success)
: m_data(size)
, m_size(size)
{
@@ -82,12 +102,42 @@ Image* ImageBuffer::image() const
// It's assumed that if image() is called, the actual rendering to the
// GraphicsContext must be done.
ASSERT(context());
+
+ // This creates a COPY of the image and will cache that copy. This means
+ // that if subsequent operations take place on the context, neither the
+ // currently-returned image, nor the results of future image() calls,
+ // will contain that operation.
+ //
+ // This seems silly, but is the way the CG port works: image() is
+ // intended to be used only when rendering is "complete."
+ cairo_surface_t* newsurface = copySurface(m_data.m_surface);
+
// BitmapImage will release the passed in surface on destruction
- m_image = BitmapImage::create(cairo_surface_reference(m_data.m_surface));
+ m_image = BitmapImage::create(newsurface);
}
return m_image.get();
}
+void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
+{
+ ASSERT(cairo_surface_get_type(m_data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE);
+
+ unsigned char* dataSrc = cairo_image_surface_get_data(m_data.m_surface);
+ int stride = cairo_image_surface_get_stride(m_data.m_surface);
+ for (int y = 0; y < m_size.height(); ++y) {
+ unsigned* row = reinterpret_cast<unsigned*>(dataSrc + stride * y);
+ for (int x = 0; x < m_size.width(); x++) {
+ unsigned* pixel = row + x;
+ Color pixelColor = colorFromPremultipliedARGB(*pixel);
+ pixelColor = Color(lookUpTable[pixelColor.red()],
+ lookUpTable[pixelColor.green()],
+ lookUpTable[pixelColor.blue()],
+ lookUpTable[pixelColor.alpha()]);
+ *pixel = premultipliedARGBFromColor(pixelColor);
+ }
+ }
+}
+
PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
{
ASSERT(cairo_surface_get_type(m_data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE);