diff options
author | Iain Merrick <husky@google.com> | 2010-08-19 17:55:56 +0100 |
---|---|---|
committer | Iain Merrick <husky@google.com> | 2010-08-23 11:05:40 +0100 |
commit | f486d19d62f1bc33246748b14b14a9dfa617b57f (patch) | |
tree | 195485454c93125455a30e553a73981c3816144d /WebCore/platform/graphics/cg | |
parent | 6ba0b43722d16bc295606bec39f396f596e4fef1 (diff) | |
download | external_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.cpp | 26 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageBufferCG.cpp | 89 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageBufferData.h | 14 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageSourceCGWin.cpp | 2 |
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 { |