summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/cg
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-08-19 17:55:56 +0100
committerIain Merrick <husky@google.com>2010-08-23 11:05:40 +0100
commitf486d19d62f1bc33246748b14b14a9dfa617b57f (patch)
tree195485454c93125455a30e553a73981c3816144d /WebCore/platform/graphics/cg
parent6ba0b43722d16bc295606bec39f396f596e4fef1 (diff)
downloadexternal_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.zip
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.gz
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.bz2
Merge WebKit at r65615 : Initial merge by git.
Change-Id: Ifbf384f4531e3b58475a662e38195c2d9152ae79
Diffstat (limited to 'WebCore/platform/graphics/cg')
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextCG.cpp26
-rw-r--r--WebCore/platform/graphics/cg/ImageBufferCG.cpp89
-rw-r--r--WebCore/platform/graphics/cg/ImageBufferData.h14
-rw-r--r--WebCore/platform/graphics/cg/ImageSourceCGWin.cpp2
4 files changed, 97 insertions, 34 deletions
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 2de4d14..e5079dc 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -753,18 +753,6 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
CGContextEOClip(context);
}
-void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
-{
- if (paintingDisabled())
- return;
-
- CGContextTranslateCTM(platformContext(), rect.x(), rect.y() + rect.height());
- CGContextScaleCTM(platformContext(), 1, -1);
- CGContextClipToMask(platformContext(), FloatRect(FloatPoint(), rect.size()), imageBuffer->image()->getCGImageRef());
- CGContextScaleCTM(platformContext(), 1, -1);
- CGContextTranslateCTM(platformContext(), -rect.x(), -rect.y() - rect.height());
-}
-
void GraphicsContext::beginTransparencyLayer(float opacity)
{
if (paintingDisabled())
@@ -950,9 +938,17 @@ void GraphicsContext::clip(const Path& path)
if (paintingDisabled())
return;
CGContextRef context = platformContext();
- CGContextBeginPath(context);
- CGContextAddPath(context, path.platformPath());
- CGContextClip(context);
+
+ // CGContextClip does nothing if the path is empty, so in this case, we
+ // instead clip against a zero rect to reduce the clipping region to
+ // nothing - which is the intended behavior of clip() if the path is empty.
+ if (path.isEmpty())
+ CGContextClipToRect(context, CGRectZero);
+ else {
+ CGContextBeginPath(context);
+ CGContextAddPath(context, path.platformPath());
+ CGContextClip(context);
+ }
m_data->clip(path);
}
diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index feb8cec..ecbcf60 100644
--- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -46,6 +46,11 @@ using namespace std;
namespace WebCore {
+static void releaseImageData(void*, const void* data, size_t)
+{
+ fastFree(const_cast<void*>(data));
+}
+
ImageBufferData::ImageBufferData(const IntSize&)
: m_data(0)
{
@@ -56,42 +61,46 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
, m_size(size)
{
success = false; // Make early return mean failure.
- unsigned bytesPerRow;
if (size.width() < 0 || size.height() < 0)
return;
- bytesPerRow = size.width();
+
+ unsigned bytesPerRow = size.width();
if (imageColorSpace != GrayScale) {
// Protect against overflow
if (bytesPerRow > 0x3FFFFFFF)
return;
bytesPerRow *= 4;
}
+ m_data.m_bytesPerRow = bytesPerRow;
+ size_t dataSize = size.height() * bytesPerRow;
if (!tryFastCalloc(size.height(), bytesPerRow).getValue(m_data.m_data))
return;
ASSERT((reinterpret_cast<size_t>(m_data.m_data) & 2) == 0);
- RetainPtr<CGColorSpaceRef> colorSpace;
switch(imageColorSpace) {
case DeviceRGB:
- colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
break;
case GrayScale:
- colorSpace.adoptCF(CGColorSpaceCreateDeviceGray());
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceGray());
break;
#if ((PLATFORM(MAC) || PLATFORM(CHROMIUM)) && !defined(BUILDING_ON_TIGER))
case LinearRGB:
- colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
break;
+
#endif
default:
- colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
+ m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
break;
}
+ m_data.m_grayScale = imageColorSpace == GrayScale;
+ m_data.m_bitmapInfo = m_data.m_grayScale ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast;
RetainPtr<CGContextRef> cgContext(AdoptCF, CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow,
- colorSpace.get(), (imageColorSpace == GrayScale) ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast));
+ m_data.m_colorSpace.get(), m_data.m_bitmapInfo));
if (!cgContext)
return;
@@ -99,11 +108,13 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
m_context->scale(FloatSize(1, -1));
m_context->translate(0, -size.height());
success = true;
+
+ // Create a live image that wraps the data.
+ m_data.m_dataProvider.adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, dataSize, releaseImageData));
}
ImageBuffer::~ImageBuffer()
{
- fastFree(m_data.m_data);
}
GraphicsContext* ImageBuffer::context() const
@@ -111,17 +122,59 @@ GraphicsContext* ImageBuffer::context() const
return m_context.get();
}
-Image* ImageBuffer::image() const
+bool ImageBuffer::drawsUsingCopy() const
+{
+ return false;
+}
+
+PassRefPtr<Image> ImageBuffer::copyImage() const
+{
+ // BitmapImage will release the passed in CGImage on destruction
+ return BitmapImage::create(CGBitmapContextCreateImage(context()->platformContext()));
+}
+
+static CGImageRef cgImage(const IntSize& size, const ImageBufferData& data)
{
- if (!m_image) {
- // It's assumed that if image() is called, the actual rendering to the
- // GraphicsContext must be done.
- ASSERT(context());
- CGImageRef cgImage = CGBitmapContextCreateImage(context()->platformContext());
- // BitmapImage will release the passed in CGImage on destruction
- m_image = BitmapImage::create(cgImage);
+ return CGImageCreate(size.width(), size.height(), 8, data.m_grayScale ? 8 : 32, data.m_bytesPerRow,
+ data.m_colorSpace.get(), data.m_bitmapInfo, data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault);
+}
+
+void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator op, bool useLowQualityScale)
+{
+ if (destContext == context()) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ destContext->drawImage(copy.get(), DeviceColorSpace, destRect, srcRect, op, useLowQualityScale);
+ } else {
+ RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data));
+ destContext->drawImage(imageForRendering.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+ }
+}
+
+void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+ if (destContext == context()) {
+ // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first.
+ RefPtr<Image> copy = copyImage();
+ copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+ } else {
+ RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data));
+ imageForRendering->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
}
- return m_image.get();
+}
+
+void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
+{
+ RetainPtr<CGImageRef> image(AdoptCF, cgImage(m_size, m_data));
+
+ CGContextRef platformContext = context->platformContext();
+ CGContextTranslateCTM(platformContext, rect.x(), rect.y() + rect.height());
+ CGContextScaleCTM(platformContext, 1, -1);
+ CGContextClipToMask(platformContext, FloatRect(FloatPoint(), rect.size()), image.get());
+ CGContextScaleCTM(platformContext, 1, -1);
+ CGContextTranslateCTM(platformContext, -rect.x(), -rect.y() - rect.height());
}
template <Multiply multiplied>
diff --git a/WebCore/platform/graphics/cg/ImageBufferData.h b/WebCore/platform/graphics/cg/ImageBufferData.h
index 5e6fc4c..2f9d854 100644
--- a/WebCore/platform/graphics/cg/ImageBufferData.h
+++ b/WebCore/platform/graphics/cg/ImageBufferData.h
@@ -26,6 +26,14 @@
#ifndef ImageBufferData_h
#define ImageBufferData_h
+#include "Image.h"
+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
+
+typedef struct CGColorSpace *CGColorSpaceRef;
+typedef struct CGDataProvider *CGDataProviderRef;
+typedef uint32_t CGBitmapInfo;
+
namespace WebCore {
class IntSize;
@@ -35,6 +43,12 @@ public:
ImageBufferData(const IntSize&);
void* m_data;
+
+ RetainPtr<CGDataProviderRef> m_dataProvider;
+ CGBitmapInfo m_bitmapInfo;
+ bool m_grayScale;
+ unsigned m_bytesPerRow;
+ RetainPtr<CGColorSpaceRef> m_colorSpace;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp b/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp
index c7d9a0b..ef69e5e 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp
@@ -27,8 +27,8 @@
#include "ImageSourceCG.h"
#include "StdLibExtras.h"
-#include "StringHash.h"
#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
namespace WebCore {