summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/cg
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-08-11 17:01:47 +0100
committerBen Murdoch <benm@google.com>2009-08-11 18:21:02 +0100
commit0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch)
tree2943df35f62d885c89d01063cc528dd73b480fea /WebCore/platform/graphics/cg
parent7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff)
downloadexternal_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2
Merge in WebKit r47029.
Diffstat (limited to 'WebCore/platform/graphics/cg')
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h2
-rw-r--r--WebCore/platform/graphics/cg/ImageBufferCG.cpp26
-rw-r--r--WebCore/platform/graphics/cg/ImageCG.cpp34
-rw-r--r--WebCore/platform/graphics/cg/ImageSourceCG.cpp26
-rw-r--r--WebCore/platform/graphics/cg/PDFDocumentImage.cpp4
-rw-r--r--WebCore/platform/graphics/cg/PathCG.cpp7
-rw-r--r--WebCore/platform/graphics/cg/PatternCG.cpp8
7 files changed, 78 insertions, 29 deletions
diff --git a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
index beee660..f63a8dd 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
+++ b/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
@@ -50,6 +50,7 @@ public:
// These methods do nothing on Mac.
void save() {}
void restore() {}
+ void flush() {}
void clip(const FloatRect&) {}
void clip(const Path&) {}
void scale(const FloatSize&) {}
@@ -64,6 +65,7 @@ public:
// On Windows, we need to update the HDC for form controls to draw in the right place.
void save();
void restore();
+ void flush();
void clip(const FloatRect&);
void clip(const Path&);
void scale(const FloatSize&);
diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index 96e5604..6db7e88 100644
--- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -38,6 +38,7 @@
#include <wtf/Assertions.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/RetainPtr.h>
+#include <math.h>
using namespace std;
@@ -48,7 +49,7 @@ ImageBufferData::ImageBufferData(const IntSize&)
{
}
-ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, bool& success)
: m_data(size)
, m_size(size)
{
@@ -57,7 +58,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
if (size.width() < 0 || size.height() < 0)
return;
bytesPerRow = size.width();
- if (!grayScale) {
+ if (imageColorSpace != GrayScale) {
// Protect against overflow
if (bytesPerRow > 0x3FFFFFFF)
return;
@@ -67,9 +68,26 @@ ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
m_data.m_data = tryFastCalloc(size.height(), bytesPerRow);
ASSERT((reinterpret_cast<size_t>(m_data.m_data) & 2) == 0);
- CGColorSpaceRef colorSpace = grayScale ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
+ CGColorSpaceRef colorSpace;
+ switch(imageColorSpace) {
+ case DeviceRGB:
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+ break;
+ case GrayScale:
+ colorSpace = CGColorSpaceCreateDeviceGray();
+ break;
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER)
+ case LinearRGB:
+ colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
+ break;
+#endif
+ default:
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+ break;
+ }
+
CGContextRef cgContext = CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow,
- colorSpace, grayScale ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast);
+ colorSpace, (imageColorSpace == GrayScale) ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
if (!cgContext)
return;
diff --git a/WebCore/platform/graphics/cg/ImageCG.cpp b/WebCore/platform/graphics/cg/ImageCG.cpp
index dbf1d85..a5620e8 100644
--- a/WebCore/platform/graphics/cg/ImageCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageCG.cpp
@@ -166,32 +166,44 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const F
// interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed
// into the destination rect. See <rdar://problem/6112909>.
shouldUseSubimage = (interpolationQuality == kCGInterpolationHigh || interpolationQuality == kCGInterpolationDefault) && srcRect.size() != destRect.size();
+ float xScale = srcRect.width() / destRect.width();
+ float yScale = srcRect.height() / destRect.height();
if (shouldUseSubimage) {
- image = CGImageCreateWithImageInRect(image, srcRect);
+ FloatRect subimageRect = srcRect;
+ float leftPadding = srcRect.x() - floorf(srcRect.x());
+ float topPadding = srcRect.y() - floorf(srcRect.y());
+
+ subimageRect.move(-leftPadding, -topPadding);
+ adjustedDestRect.move(-leftPadding / xScale, -topPadding / yScale);
+
+ subimageRect.setWidth(ceilf(subimageRect.width() + leftPadding));
+ adjustedDestRect.setWidth(subimageRect.width() / xScale);
+
+ subimageRect.setHeight(ceilf(subimageRect.height() + topPadding));
+ adjustedDestRect.setHeight(subimageRect.height() / yScale);
+
+ image = CGImageCreateWithImageInRect(image, subimageRect);
if (currHeight < srcRect.bottom()) {
ASSERT(CGImageGetHeight(image) == currHeight - CGRectIntegral(srcRect).origin.y);
- adjustedDestRect.setHeight(destRect.height() / srcRect.height() * CGImageGetHeight(image));
+ adjustedDestRect.setHeight(CGImageGetHeight(image) / yScale);
}
} else {
- float xScale = srcRect.width() / destRect.width();
- float yScale = srcRect.height() / destRect.height();
-
adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale));
adjustedDestRect.setSize(FloatSize(selfSize.width() / xScale, selfSize.height() / yScale));
-
- CGContextClipToRect(context, destRect);
}
+
+ CGContextClipToRect(context, destRect);
}
// If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly.
if (!shouldUseSubimage && currHeight < selfSize.height())
adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height());
- // Flip the coords.
ctxt->setCompositeOperation(compositeOp);
- CGContextTranslateCTM(context, adjustedDestRect.x(), adjustedDestRect.bottom());
+
+ // Flip the coords.
CGContextScaleCTM(context, 1, -1);
- adjustedDestRect.setLocation(FloatPoint());
+ adjustedDestRect.setY(-adjustedDestRect.bottom());
// Draw the image.
CGContextDrawImage(context, adjustedDestRect, image);
@@ -205,7 +217,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const F
imageObserver()->didDraw(this);
}
-void Image::drawPatternCallback(void* info, CGContextRef context)
+static void drawPatternCallback(void* info, CGContextRef context)
{
CGImageRef image = (CGImageRef)info;
CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect(0, 0, CGImageGetWidth(image), CGImageGetHeight(image))), image);
diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index 7cb8799..b716060 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -38,7 +38,14 @@
namespace WebCore {
static const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
-static const CFStringRef kCGImageSourceDoNotCacheImageBlocks = CFSTR("kCGImageSourceDoNotCacheImageBlocks");
+
+#if !PLATFORM(MAC)
+static void sharedBufferDerefCallback(void*, void* info)
+{
+ SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info);
+ sharedBuffer->deref();
+}
+#endif
ImageSource::ImageSource()
: m_decoder(0)
@@ -79,11 +86,12 @@ void ImageSource::clear(bool destroyAllFrames, size_t, SharedBuffer* data, bool
static CFDictionaryRef imageSourceOptions()
{
static CFDictionaryRef options;
-
+
if (!options) {
- const void* keys[3] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceDoNotCacheImageBlocks };
- const void* values[3] = { kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue };
- options = CFDictionaryCreate(NULL, keys, values, 3,
+ const unsigned numOptions = 2;
+ const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32 };
+ const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue };
+ options = CFDictionaryCreate(NULL, keys, values, numOptions,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
return options;
@@ -104,8 +112,12 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
CFDataRef cfData = data->createCFData();
#else
// If no NSData is available, then we know SharedBuffer will always just be a vector. That means no secret changes can occur to it behind the
- // scenes. We use CFDataCreateWithBytesNoCopy in that case.
- CFDataRef cfData = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data->data()), data->size(), kCFAllocatorNull);
+ // scenes. We use CFDataCreateWithBytesNoCopy in that case. Ensure that the SharedBuffer lives as long as the CFDataRef.
+ data->ref();
+ CFAllocatorContext context = {0, data, 0, 0, 0, 0, 0, &sharedBufferDerefCallback, 0};
+ CFAllocatorRef derefAllocator = CFAllocatorCreate(kCFAllocatorDefault, &context);
+ CFDataRef cfData = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data->data()), data->size(), derefAllocator);
+ CFRelease(derefAllocator);
#endif
CGImageSourceUpdateData(m_decoder, cfData, allDataReceived);
CFRelease(cfData);
diff --git a/WebCore/platform/graphics/cg/PDFDocumentImage.cpp b/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
index 2578f08..858b18e 100644
--- a/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
+++ b/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
@@ -68,11 +68,11 @@ bool PDFDocumentImage::dataChanged(bool allDataReceived)
#if PLATFORM(MAC)
// On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge. We use SharedBuffer's ability
// to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
- CFDataRef data = m_data->createCFData();
+ CFDataRef data = this->data()->createCFData();
#else
// If no NSData is available, then we know SharedBuffer will always just be a vector. That means no secret changes can occur to it behind the
// scenes. We use CFDataCreateWithBytesNoCopy in that case.
- CFDataRef data = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(m_data->data()), m_data->size(), kCFAllocatorNull);
+ CFDataRef data = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(this->data()->data()), this->data()->size(), kCFAllocatorNull);
#endif
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(data);
CFRelease(data);
diff --git a/WebCore/platform/graphics/cg/PathCG.cpp b/WebCore/platform/graphics/cg/PathCG.cpp
index ebd0359..5812cea 100644
--- a/WebCore/platform/graphics/cg/PathCG.cpp
+++ b/WebCore/platform/graphics/cg/PathCG.cpp
@@ -245,7 +245,12 @@ void Path::clear()
bool Path::isEmpty() const
{
return CGPathIsEmpty(m_path);
- }
+}
+
+bool Path::hasCurrentPoint() const
+{
+ return !isEmpty();
+}
static void CGPathToCFStringApplierFunction(void* info, const CGPathElement *element)
{
diff --git a/WebCore/platform/graphics/cg/PatternCG.cpp b/WebCore/platform/graphics/cg/PatternCG.cpp
index 697bc57..63628f4 100644
--- a/WebCore/platform/graphics/cg/PatternCG.cpp
+++ b/WebCore/platform/graphics/cg/PatternCG.cpp
@@ -62,10 +62,10 @@ CGPatternRef Pattern::createPlatformPattern(const TransformationMatrix& userSpac
// If FLT_MAX should also be used for xStep or yStep, nothing is rendered. Using fractions of FLT_MAX also
// result in nothing being rendered.
// INT_MAX is almost correct, but there seems to be some number wrapping occuring making the fill
- // pattern is not filled correctly.
- // So, just pick a really large number that works.
- float xStep = m_repeatX ? tileRect.width() : (100000000.0f);
- float yStep = m_repeatY ? tileRect.height() : (100000000.0f);
+ // pattern is not filled correctly.
+ // To make error of floating point less than 0.5, we use the half of the number of mantissa of float (1 << 22).
+ CGFloat xStep = m_repeatX ? tileRect.width() : (1 << 22);
+ CGFloat yStep = m_repeatY ? tileRect.height() : (1 << 22);
// The pattern will release the tile when it's done rendering in patternReleaseCallback
tileImage()->ref();