diff options
author | Ben Murdoch <benm@google.com> | 2009-08-11 17:01:47 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2009-08-11 18:21:02 +0100 |
commit | 0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch) | |
tree | 2943df35f62d885c89d01063cc528dd73b480fea /WebCore/platform/graphics/cg | |
parent | 7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff) | |
download | external_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.h | 2 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageBufferCG.cpp | 26 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageCG.cpp | 34 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageSourceCG.cpp | 26 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/PDFDocumentImage.cpp | 4 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/PathCG.cpp | 7 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/PatternCG.cpp | 8 |
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(); |