diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-05 14:34:32 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-05 14:34:32 -0800 |
commit | 635860845790a19bf50bbc51ba8fb66a96dde068 (patch) | |
tree | ef6ad9ff73a5b57f65249d4232a202fa77e6a140 /WebCore/platform/graphics/cg | |
parent | 8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (diff) | |
download | external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.zip external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.gz external_webkit-635860845790a19bf50bbc51ba8fb66a96dde068.tar.bz2 |
auto import from //depot/cupcake/@136594
Diffstat (limited to 'WebCore/platform/graphics/cg')
-rw-r--r-- | WebCore/platform/graphics/cg/GraphicsContextCG.cpp | 140 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h | 6 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageBufferCG.cpp | 4 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageCG.cpp | 19 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageSourceCG.cpp | 23 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageSourceCG.h | 41 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageSourceCGMac.mm | 48 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/ImageSourceCGWin.cpp | 84 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/PDFDocumentImage.h | 7 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/PathCG.cpp | 80 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/PatternCG.cpp | 6 | ||||
-rw-r--r-- | WebCore/platform/graphics/cg/TransformationMatrixCG.cpp (renamed from WebCore/platform/graphics/cg/AffineTransformCG.cpp) | 68 |
12 files changed, 422 insertions, 104 deletions
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index 3f0e6e7..1cc55a4 100644 --- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -28,7 +28,7 @@ #include "config.h" #include "GraphicsContext.h" -#include "AffineTransform.h" +#include "TransformationMatrix.h" #include "FloatConversion.h" #include "GraphicsContextPrivate.h" #include "GraphicsContextPlatformPrivateCG.h" @@ -191,11 +191,13 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) } CGContextRef context = platformContext(); - CGContextSaveGState(context); - - CGContextSetShouldAntialias(context, false); + + if (shouldAntialias()) + CGContextSetShouldAntialias(context, false); if (patWidth) { + CGContextSaveGState(context); + // Do a rect fill of our endpoints. This ensures we always have the // appearance of being a border. We then draw the actual dotted/dashed line. setCGFillColor(context, strokeColor()); // The save/restore make it safe to mutate the fill color here without setting it back to the old color. @@ -245,7 +247,11 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) CGContextStrokePath(context); - CGContextRestoreGState(context); + if (patWidth) + CGContextRestoreGState(context); + + if (shouldAntialias()) + CGContextSetShouldAntialias(context, true); } // This method is only used to draw the little circles used in lists. @@ -358,7 +364,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp CGContextRestoreGState(context); } -void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias) +void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled() || !fillColor().alpha() && (strokeThickness() <= 0 || strokeStyle() == NoStroke)) return; @@ -368,9 +374,8 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points CGContextRef context = platformContext(); - CGContextSaveGState(context); - - CGContextSetShouldAntialias(context, shouldAntialias); + if (antialiased != shouldAntialias()) + CGContextSetShouldAntialias(context, antialiased); CGContextBeginPath(context); CGContextMoveToPoint(context, points[0].x(), points[0].y()); @@ -379,15 +384,16 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points CGContextClosePath(context); drawPath(); - - CGContextRestoreGState(context); + + if (antialiased != shouldAntialias()) + CGContextSetShouldAntialias(context, shouldAntialias()); } -static void applyStrokePattern(GraphicsContext* context, Pattern* pattern) +void GraphicsContext::applyStrokePattern() { - CGContextRef cgContext = context->platformContext(); + CGContextRef cgContext = platformContext(); - CGPatternRef platformPattern = pattern->createPlatformPattern(context->getCTM()); + CGPatternRef platformPattern = m_common->state.strokePattern.get()->createPlatformPattern(getCTM()); if (!platformPattern) return; @@ -400,11 +406,11 @@ static void applyStrokePattern(GraphicsContext* context, Pattern* pattern) CGPatternRelease(platformPattern); } -static void applyFillPattern(GraphicsContext* context, Pattern* pattern) +void GraphicsContext::applyFillPattern() { - CGContextRef cgContext = context->platformContext(); + CGContextRef cgContext = platformContext(); - CGPatternRef platformPattern = pattern->createPlatformPattern(context->getCTM()); + CGPatternRef platformPattern = m_common->state.fillPattern.get()->createPlatformPattern(getCTM()); if (!platformPattern) return; @@ -460,9 +466,9 @@ void GraphicsContext::drawPath() } if (state.fillColorSpace == PatternColorSpace) - applyFillPattern(this, m_common->state.fillPattern.get()); + applyFillPattern(); if (state.strokeColorSpace == PatternColorSpace) - applyStrokePattern(this, m_common->state.strokePattern.get()); + applyStrokePattern(); CGPathDrawingMode drawingMode; if (calculateDrawingMode(state, drawingMode)) @@ -489,7 +495,7 @@ void GraphicsContext::fillPath() fillPathWithFillRule(context, fillRule()); break; case PatternColorSpace: - applyFillPattern(this, m_common->state.fillPattern.get()); + applyFillPattern(); fillPathWithFillRule(context, fillRule()); break; case GradientColorSpace: @@ -512,11 +518,11 @@ void GraphicsContext::strokePath() CGContextRef context = platformContext(); switch (m_common->state.strokeColorSpace) { case SolidColorSpace: - if (fillColor().alpha()) + if (strokeColor().alpha()) CGContextStrokePath(context); break; case PatternColorSpace: - applyStrokePattern(this, m_common->state.strokePattern.get()); + applyStrokePattern(); CGContextStrokePath(context); break; case GradientColorSpace: @@ -540,7 +546,7 @@ void GraphicsContext::fillRect(const FloatRect& rect) CGContextFillRect(context, rect); break; case PatternColorSpace: - applyFillPattern(this, m_common->state.fillPattern.get()); + applyFillPattern(); CGContextFillRect(context, rect); break; case GradientColorSpace: @@ -614,6 +620,21 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) CGContextEOClip(platformContext()); } +void GraphicsContext::clipPath(WindRule clipRule) +{ + if (paintingDisabled()) + return; + + CGContextRef context = platformContext(); + + if (!CGContextIsPathEmpty(context)) { + if (clipRule == RULE_EVENODD) + CGContextEOClip(context); + else + CGContextClip(context); + } +} + void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) { if (paintingDisabled()) @@ -670,23 +691,30 @@ void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Col { if (paintingDisabled()) return; + CGFloat width = size.width(); + CGFloat height = size.height(); + CGFloat blurRadius = blur; CGContextRef context = platformContext(); - CGAffineTransform transform = CGContextGetCTM(context); - CGFloat A = transform.a * transform.a + transform.b * transform.b; - CGFloat B = transform.a * transform.c + transform.b * transform.d; - CGFloat C = B; - CGFloat D = transform.c * transform.c + transform.d * transform.d; + if (!m_common->state.shadowsIgnoreTransforms) { + CGAffineTransform transform = CGContextGetCTM(context); - CGFloat smallEigenvalue = narrowPrecisionToCGFloat(sqrt(0.5 * ((A + D) - sqrt(4 * B * C + (A - D) * (A - D))))); + CGFloat A = transform.a * transform.a + transform.b * transform.b; + CGFloat B = transform.a * transform.c + transform.b * transform.d; + CGFloat C = B; + CGFloat D = transform.c * transform.c + transform.d * transform.d; - // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp - CGFloat blurRadius = min(blur * smallEigenvalue, narrowPrecisionToCGFloat(1000.0)); + CGFloat smallEigenvalue = narrowPrecisionToCGFloat(sqrt(0.5 * ((A + D) - sqrt(4 * B * C + (A - D) * (A - D))))); - CGSize sizeInDeviceSpace = CGSizeApplyAffineTransform(size, transform); + // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp + blurRadius = min(blur * smallEigenvalue, narrowPrecisionToCGFloat(1000.0)); - CGFloat width = sizeInDeviceSpace.width; - CGFloat height = sizeInDeviceSpace.height; + CGSize sizeInDeviceSpace = CGSizeApplyAffineTransform(size, transform); + + width = sizeInDeviceSpace.width; + height = sizeInDeviceSpace.height; + + } // Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated // to the desired integer. @@ -747,7 +775,27 @@ void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth) { if (paintingDisabled()) return; - CGContextStrokeRectWithWidth(platformContext(), r, lineWidth); + + CGContextRef context = platformContext(); + switch (m_common->state.strokeColorSpace) { + case SolidColorSpace: + if (strokeColor().alpha()) + CGContextStrokeRectWithWidth(context, r, lineWidth); + break; + case PatternColorSpace: + applyStrokePattern(); + CGContextStrokeRectWithWidth(context, r, lineWidth); + break; + case GradientColorSpace: + CGContextSaveGState(context); + setStrokeThickness(lineWidth); + CGContextAddRect(context, r); + CGContextReplacePathWithStrokedPath(context); + CGContextClip(context); + CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient()); + CGContextRestoreGState(context); + break; + } } void GraphicsContext::setLineCap(LineCap cap) @@ -848,7 +896,7 @@ void GraphicsContext::translate(float x, float y) m_data->m_userToDeviceTransformKnownToBeIdentity = false; } -void GraphicsContext::concatCTM(const AffineTransform& transform) +void GraphicsContext::concatCTM(const TransformationMatrix& transform) { if (paintingDisabled()) return; @@ -857,7 +905,7 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->m_userToDeviceTransformKnownToBeIdentity = false; } -AffineTransform GraphicsContext::getCTM() const +TransformationMatrix GraphicsContext::getCTM() const { return CGContextGetCTM(platformContext()); } @@ -909,8 +957,6 @@ void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool pri if (width <= 0) return; - CGContextSaveGState(platformContext()); - float x = point.x(); float y = point.y(); float lineLength = width; @@ -919,6 +965,8 @@ void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool pri // See http://bugs.webkit.org/show_bug.cgi?id=4255 for details of why 0.5 is the right minimum thickness to use. float thickness = max(strokeThickness(), 0.5f); + bool restoreAntialiasMode = false; + if (!printing) { // On screen, use a minimum thickness of 1.0 in user space (later rounded to an integral number in device space). float adjustedThickness = max(thickness, 1.0f); @@ -933,15 +981,21 @@ void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool pri y = lineRect.origin.y; lineLength = lineRect.size.width; thickness = lineRect.size.height; - CGContextSetShouldAntialias(platformContext(), false); + if (shouldAntialias()) { + CGContextSetShouldAntialias(platformContext(), false); + restoreAntialiasMode = true; + } } } if (fillColor() != strokeColor()) setCGFillColor(platformContext(), strokeColor()); CGContextFillRect(platformContext(), CGRectMake(x, y, lineLength, thickness)); - - CGContextRestoreGState(platformContext()); + if (fillColor() != strokeColor()) + setCGFillColor(platformContext(), fillColor()); + + if (restoreAntialiasMode) + CGContextSetShouldAntialias(platformContext(), true); } void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) @@ -1078,7 +1132,7 @@ void GraphicsContext::setPlatformFillColor(const Color& color) setCGFillColor(platformContext(), color); } -void GraphicsContext::setUseAntialiasing(bool enable) +void GraphicsContext::setPlatformShouldAntialias(bool enable) { if (paintingDisabled()) return; diff --git a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h index 8827ff7..beee660 100644 --- a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +++ b/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h @@ -34,6 +34,7 @@ public: #if PLATFORM(WIN) , m_hdc(0) , m_transparencyCount(0) + , m_shouldIncludeChildWindows(false) #endif , m_userToDeviceTransformKnownToBeIdentity(false) { @@ -54,7 +55,7 @@ public: void scale(const FloatSize&) {} void rotate(float) {} void translate(float, float) {} - void concatCTM(const AffineTransform&) {} + void concatCTM(const TransformationMatrix&) {} void beginTransparencyLayer() {} void endTransparencyLayer() {} #endif @@ -68,12 +69,13 @@ public: void scale(const FloatSize&); void rotate(float); void translate(float, float); - void concatCTM(const AffineTransform&); + void concatCTM(const TransformationMatrix&); void beginTransparencyLayer() { m_transparencyCount++; } void endTransparencyLayer() { m_transparencyCount--; } HDC m_hdc; unsigned m_transparencyCount; + bool m_shouldIncludeChildWindows; #endif CGContextRef m_cgContext; diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp index 502313b..96e5604 100644 --- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -107,7 +107,7 @@ Image* ImageBuffer::image() const PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const { PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); - unsigned char* data = result->data()->data().data(); + unsigned char* data = result->data()->data()->data(); if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) memset(data, 0, result->data()->length()); @@ -188,7 +188,7 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con unsigned srcBytesPerRow = 4 * source->width(); unsigned destBytesPerRow = 4 * m_size.width(); - unsigned char* srcRows = source->data()->data().data() + originy * srcBytesPerRow + originx * 4; + unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4; unsigned char* destRows = reinterpret_cast<unsigned char*>(m_data.m_data) + desty * destBytesPerRow + destx * 4; for (int y = 0; y < numRows; ++y) { for (int x = 0; x < numColumns; x++) { diff --git a/WebCore/platform/graphics/cg/ImageCG.cpp b/WebCore/platform/graphics/cg/ImageCG.cpp index 8609c46..13c8c07 100644 --- a/WebCore/platform/graphics/cg/ImageCG.cpp +++ b/WebCore/platform/graphics/cg/ImageCG.cpp @@ -28,7 +28,7 @@ #if PLATFORM(CG) -#include "AffineTransform.h" +#include "TransformationMatrix.h" #include "FloatConversion.h" #include "FloatRect.h" #include "GraphicsContext.h" @@ -47,15 +47,17 @@ namespace WebCore { -void FrameData::clear() +bool FrameData::clear(bool clearMetadata) { + if (clearMetadata) + m_haveMetadata = false; + if (m_frame) { CGImageRelease(m_frame); m_frame = 0; - // NOTE: We purposefully don't reset metadata here, so that even if we - // throw away previously-decoded data, animation loops can still access - // properties like frame durations without re-decoding. + return true; } + return false; } // ================================================ @@ -207,7 +209,7 @@ void Image::drawPatternCallback(void* info, CGContextRef context) CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect(0, 0, CGImageGetWidth(image), CGImageGetHeight(image))), image); } -void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, +void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const TransformationMatrix& patternTransform, const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) { if (!nativeImageForCurrentFrame()) @@ -251,9 +253,14 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const // its buffer is the same size as the overall image. Because a partially decoded CGImageRef with a smaller width or height than the // overall image buffer needs to tile with "gaps", we can't use the optimized tiling call in that case. // FIXME: Could create WebKitSystemInterface SPI for CGCreatePatternWithImage2 and probably make Tiger tile faster as well. + // FIXME: We cannot use CGContextDrawTiledImage with scaled tiles on Leopard, because it suffers from rounding errors. Snow Leopard is ok. float scaledTileWidth = tileRect.width() * narrowPrecisionToFloat(patternTransform.a()); float w = CGImageGetWidth(tileImage); +#ifdef BUILDING_ON_LEOPARD + if (w == size().width() && h == size().height() && scaledTileWidth == tileRect.width() && scaledTileHeight == tileRect.height()) +#else if (w == size().width() && h == size().height()) +#endif CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage); else { #endif diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp index 73907c9..0b276cc 100644 --- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp +++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp @@ -27,8 +27,10 @@ #include "ImageSource.h" #if PLATFORM(CG) +#include "ImageSourceCG.h" #include "IntSize.h" +#include "MIMETypeRegistry.h" #include "SharedBuffer.h" #include <ApplicationServices/ApplicationServices.h> @@ -43,18 +45,23 @@ ImageSource::ImageSource() ImageSource::~ImageSource() { - clear(); + clear(true); } -void ImageSource::clear() +void ImageSource::clear(bool, size_t, SharedBuffer* data, bool allDataReceived) { + // We always destroy the decoder, because there is no API to get it to + // selectively release some of the frames it's holding, and if we don't + // release any of them, we use too much memory on large images. if (m_decoder) { CFRelease(m_decoder); m_decoder = 0; } + if (data) + setData(data, allDataReceived); } -CFDictionaryRef imageSourceOptions() +static CFDictionaryRef imageSourceOptions() { static CFDictionaryRef options; @@ -89,6 +96,14 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived) CFRelease(cfData); } +String ImageSource::filenameExtension() const +{ + if (!m_decoder) + return String(); + CFStringRef imageSourceType = CGImageSourceGetType(m_decoder); + return WebCore::preferredExtensionForImageSourceType(imageSourceType); +} + bool ImageSource::isSizeAvailable() { bool result = false; @@ -210,7 +225,7 @@ float ImageSource::frameDurationAtIndex(size_t index) return duration; } -bool ImageSource::frameHasAlphaAtIndex(size_t index) +bool ImageSource::frameHasAlphaAtIndex(size_t) { // Might be interesting to do this optimization on Mac some day, but for now we're just using this // for the Cairo source, since it uses our decoders, and our decoders can answer this question. diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.h b/WebCore/platform/graphics/cg/ImageSourceCG.h new file mode 100644 index 0000000..d5b4b5a --- /dev/null +++ b/WebCore/platform/graphics/cg/ImageSourceCG.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ImageSourceCG_h +#define ImageSourceCG_h + +#include "ImageSource.h" + +namespace WebCore { + +class String; + +String preferredExtensionForImageSourceType(const String& type); + +String MIMETypeForImageSourceType(const String& type); + +} + +#endif // ImageSourceCG_h diff --git a/WebCore/platform/graphics/cg/ImageSourceCGMac.mm b/WebCore/platform/graphics/cg/ImageSourceCGMac.mm new file mode 100644 index 0000000..297e30a --- /dev/null +++ b/WebCore/platform/graphics/cg/ImageSourceCGMac.mm @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "ImageSourceCG.h" + +#import "PlatformString.h" +#import "wtf/RetainPtr.h" + +namespace WebCore { + +String MIMETypeForImageSourceType(const String& uti) +{ + RetainPtr<CFStringRef> utiref(AdoptCF, uti.createCFString()); + RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(utiref.get(), kUTTagClassMIMEType)); + return mime.get(); +} + +String preferredExtensionForImageSourceType(const String& uti) +{ + RetainPtr<CFStringRef> type(AdoptCF, uti.createCFString()); + RetainPtr<CFStringRef> extension(AdoptCF, UTTypeCopyPreferredTagWithClass(type.get(), kUTTagClassFilenameExtension)); + return extension.get(); +} + +} // namespace WebCore diff --git a/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp b/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp new file mode 100644 index 0000000..c7d9a0b --- /dev/null +++ b/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ImageSourceCG.h" + +#include "StdLibExtras.h" +#include "StringHash.h" +#include <wtf/HashMap.h> + +namespace WebCore { + +String MIMETypeForImageSourceType(const String& type) +{ + String mimeType; + // FIXME: This approach of taking a UTI like public.type and giving back + // a MIME type like image/type will work for common image UTIs like jpeg, + // png, tiff, gif but won't work for UTIs like: public.jpeg-2000, + // public.xbitmap-image, com.apple.quicktime-image, and others. + if (int dotLocation = type.reverseFind('.')) + mimeType = "image/" + type.substring(dotLocation + 1); + return mimeType; +} + +String preferredExtensionForImageSourceType(const String& type) +{ + if (type.isEmpty()) + return String(); + + typedef HashMap<String, String> StringMap; + DEFINE_STATIC_LOCAL(StringMap, UTIMap, ()); + if (UTIMap.isEmpty()) { + UTIMap.add("public.html", "html"); + UTIMap.add("public.jpeg", "jpeg"); + UTIMap.add("public.jpeg-2000", "jp2"); + UTIMap.add("public.plain-text", "txt"); + UTIMap.add("public.png", "png"); + UTIMap.add("public.tiff", "tiff"); + UTIMap.add("public.xbitmap-image", "xbm"); + UTIMap.add("public.xml", "xml"); + UTIMap.add("com.adobe.illustrator.ai-image", "ai"); + UTIMap.add("com.adobe.pdf", "pdf"); + UTIMap.add("com.adobe.photoshop-image", "psd"); + UTIMap.add("com.adobe.postscript", "ps"); + UTIMap.add("com.apple.icns", "icns"); + UTIMap.add("com.apple.macpaint-image", "pntg"); + UTIMap.add("com.apple.pict", "pict"); + UTIMap.add("com.apple.quicktime-image", "qtif"); + UTIMap.add("com.apple.webarchive", "webarchive"); + UTIMap.add("com.compuserve.gif", "gif"); + UTIMap.add("com.ilm.openexr-image", "exr"); + UTIMap.add("com.kodak.flashpix-image", "fpx"); + UTIMap.add("com.microsoft.bmp", "bmp"); + UTIMap.add("com.microsoft.ico", "ico"); + UTIMap.add("com.netscape.javascript-source", "js"); + UTIMap.add("com.sgi.sgi-image", "sgi"); + UTIMap.add("com.truevision.tga-image", "tga"); + } + return UTIMap.get(type); +} + +} // namespace WebCore diff --git a/WebCore/platform/graphics/cg/PDFDocumentImage.h b/WebCore/platform/graphics/cg/PDFDocumentImage.h index 5c9d4e1..130c12c 100644 --- a/WebCore/platform/graphics/cg/PDFDocumentImage.h +++ b/WebCore/platform/graphics/cg/PDFDocumentImage.h @@ -42,7 +42,9 @@ namespace WebCore { { return adoptRef(new PDFDocumentImage); } - ~PDFDocumentImage(); + + private: + virtual ~PDFDocumentImage(); virtual bool hasSingleSecurityOrigin() const { return true; } @@ -50,12 +52,11 @@ namespace WebCore { // FIXME: PDF Images are underreporting decoded sizes and will be unable // to prune because these functions are not implemented yet. - virtual void destroyDecodedData(bool incremental = false, bool preserveNearbyFrames = false) { } + virtual void destroyDecodedData(bool /*destroyAll*/ = true) { } virtual unsigned decodedSize() const { return 0; } virtual IntSize size() const; - private: PDFDocumentImage(); virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator); diff --git a/WebCore/platform/graphics/cg/PathCG.cpp b/WebCore/platform/graphics/cg/PathCG.cpp index 1382589..ebd0359 100644 --- a/WebCore/platform/graphics/cg/PathCG.cpp +++ b/WebCore/platform/graphics/cg/PathCG.cpp @@ -29,16 +29,43 @@ #if PLATFORM(CG) -#include "AffineTransform.h" +#include "TransformationMatrix.h" #include <ApplicationServices/ApplicationServices.h> #include "FloatRect.h" +#include "GraphicsContext.h" #include "IntRect.h" #include "PlatformString.h" +#include "StrokeStyleApplier.h" #include <wtf/MathExtras.h> namespace WebCore { +static size_t putBytesNowhere(void*, const void*, size_t count) +{ + return count; +} + +static CGContextRef createScratchContext() +{ + CGDataConsumerCallbacks callbacks = { putBytesNowhere, 0 }; + CGDataConsumerRef consumer = CGDataConsumerCreate(0, &callbacks); + CGContextRef context = CGPDFContextCreate(consumer, 0, 0); + CGDataConsumerRelease(consumer); + + CGFloat black[4] = { 0, 0, 0, 1 }; + CGContextSetFillColor(context, black); + CGContextSetStrokeColor(context, black); + + return context; +} + +static inline CGContextRef scratchContext() +{ + static CGContextRef context = createScratchContext(); + return context; +} + Path::Path() : m_path(CGPathCreateMutable()) { @@ -62,7 +89,6 @@ Path& Path::operator=(const Path& other) return *this; } - static void copyClosingSubpathsApplierFunction(void* info, const CGPathElement* element) { CGMutablePathRef path = static_cast<CGMutablePathRef>(info); @@ -109,6 +135,25 @@ bool Path::contains(const FloatPoint &point, WindRule rule) const return ret; } +bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const +{ + ASSERT(applier); + + CGContextRef context = scratchContext(); + + CGContextSaveGState(context); + CGContextBeginPath(context); + CGContextAddPath(context, platformPath()); + + GraphicsContext gc(context); + applier->strokeStyle(&gc); + + bool hitSuccess = CGContextPathContainsPoint(context, point, kCGPathStroke); + CGContextRestoreGState(context); + + return hitSuccess; +} + void Path::translate(const FloatSize& size) { CGAffineTransform translation = CGAffineTransformMake(1, 0, 0, 1, size.width(), size.height()); @@ -123,6 +168,26 @@ FloatRect Path::boundingRect() const return CGPathGetBoundingBox(m_path); } +FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) +{ + CGContextRef context = scratchContext(); + + CGContextSaveGState(context); + CGContextBeginPath(context); + CGContextAddPath(context, platformPath()); + + if (applier) { + GraphicsContext graphicsContext(context); + applier->strokeStyle(&graphicsContext); + } + + CGContextReplacePathWithStrokedPath(context); + CGRect box = CGContextIsPathEmpty(context) ? CGRectZero : CGContextGetPathBoundingBox(context); + CGContextRestoreGState(context); + + return box; +} + void Path::moveTo(const FloatPoint& point) { CGPathMoveToPoint(m_path, 0, point.x(), point.y()); @@ -184,8 +249,8 @@ bool Path::isEmpty() const static void CGPathToCFStringApplierFunction(void* info, const CGPathElement *element) { - CFMutableStringRef string = (CFMutableStringRef)info; - CFStringRef typeString = CFSTR(""); + CFMutableStringRef string = static_cast<CFMutableStringRef>(info); + CGPoint* points = element->points; switch (element->type) { case kCGPathElementMoveToPoint: @@ -204,7 +269,8 @@ static void CGPathToCFStringApplierFunction(void* info, const CGPathElement *ele points[2].x, points[2].y); break; case kCGPathElementCloseSubpath: - typeString = CFSTR("X"); break; + CFStringAppendFormat(string, 0, CFSTR("Z ")); + break; } } @@ -241,7 +307,7 @@ struct PathApplierInfo { PathApplierFunction function; }; -void CGPathApplierToPathApplier(void *info, const CGPathElement *element) +static void CGPathApplierToPathApplier(void *info, const CGPathElement *element) { PathApplierInfo* pinfo = (PathApplierInfo*)info; FloatPoint points[3]; @@ -277,7 +343,7 @@ void Path::apply(void* info, PathApplierFunction function) const CGPathApply(m_path, &pinfo, CGPathApplierToPathApplier); } -void Path::transform(const AffineTransform& transform) +void Path::transform(const TransformationMatrix& transform) { CGMutablePathRef path = CGPathCreateMutable(); CGAffineTransform transformCG = transform; diff --git a/WebCore/platform/graphics/cg/PatternCG.cpp b/WebCore/platform/graphics/cg/PatternCG.cpp index e1f7a69..2b9c12f 100644 --- a/WebCore/platform/graphics/cg/PatternCG.cpp +++ b/WebCore/platform/graphics/cg/PatternCG.cpp @@ -27,7 +27,7 @@ #include "config.h" #include "Pattern.h" -#include "AffineTransform.h" +#include "TransformationMatrix.h" #include "GraphicsContext.h" #include <ApplicationServices/ApplicationServices.h> @@ -50,11 +50,11 @@ static void patternReleaseCallback(void* info) static_cast<Image*>(info)->deref(); } -CGPatternRef Pattern::createPlatformPattern(const AffineTransform& transform) const +CGPatternRef Pattern::createPlatformPattern(const TransformationMatrix& transform) const { IntRect tileRect = tileImage()->rect(); - AffineTransform patternTransform = transform; + TransformationMatrix patternTransform = transform; patternTransform.scale(1, -1); patternTransform.translate(0, -tileRect.height()); diff --git a/WebCore/platform/graphics/cg/AffineTransformCG.cpp b/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp index 4f0bca0..9b3181a 100644 --- a/WebCore/platform/graphics/cg/AffineTransformCG.cpp +++ b/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp @@ -24,7 +24,7 @@ */ #include "config.h" -#include "AffineTransform.h" +#include "TransformationMatrix.h" #if PLATFORM(CG) @@ -36,12 +36,12 @@ namespace WebCore { -AffineTransform::AffineTransform() +TransformationMatrix::TransformationMatrix() : m_transform(CGAffineTransformIdentity) { } -AffineTransform::AffineTransform(double a, double b, double c, double d, double tx, double ty) +TransformationMatrix::TransformationMatrix(double a, double b, double c, double d, double tx, double ty) { m_transform = CGAffineTransformMake(narrowPrecisionToCGFloat(a), narrowPrecisionToCGFloat(b), @@ -51,12 +51,12 @@ AffineTransform::AffineTransform(double a, double b, double c, double d, double narrowPrecisionToCGFloat(ty)); } -AffineTransform::AffineTransform(const PlatformAffineTransform& t) +TransformationMatrix::TransformationMatrix(const PlatformTransformationMatrix& t) : m_transform(t) { } -void AffineTransform::setMatrix(double a, double b, double c, double d, double tx, double ty) +void TransformationMatrix::setMatrix(double a, double b, double c, double d, double tx, double ty) { m_transform = CGAffineTransformMake(narrowPrecisionToCGFloat(a), narrowPrecisionToCGFloat(b), @@ -66,147 +66,147 @@ void AffineTransform::setMatrix(double a, double b, double c, double d, double t narrowPrecisionToCGFloat(ty)); } -void AffineTransform::map(double x, double y, double *x2, double *y2) const +void TransformationMatrix::map(double x, double y, double *x2, double *y2) const { CGPoint result = CGPointApplyAffineTransform(CGPointMake(narrowPrecisionToCGFloat(x), narrowPrecisionToCGFloat(y)), m_transform); *x2 = result.x; *y2 = result.y; } -IntRect AffineTransform::mapRect(const IntRect &rect) const +IntRect TransformationMatrix::mapRect(const IntRect &rect) const { return enclosingIntRect(CGRectApplyAffineTransform(CGRect(rect), m_transform)); } -FloatRect AffineTransform::mapRect(const FloatRect &rect) const +FloatRect TransformationMatrix::mapRect(const FloatRect &rect) const { return FloatRect(CGRectApplyAffineTransform(CGRect(rect), m_transform)); } -bool AffineTransform::isIdentity() const +bool TransformationMatrix::isIdentity() const { return CGAffineTransformIsIdentity(m_transform); } -double AffineTransform::a() const +double TransformationMatrix::a() const { return m_transform.a; } -void AffineTransform::setA(double a) +void TransformationMatrix::setA(double a) { m_transform.a = narrowPrecisionToCGFloat(a); } -double AffineTransform::b() const +double TransformationMatrix::b() const { return m_transform.b; } -void AffineTransform::setB(double b) +void TransformationMatrix::setB(double b) { m_transform.b = narrowPrecisionToCGFloat(b); } -double AffineTransform::c() const +double TransformationMatrix::c() const { return m_transform.c; } -void AffineTransform::setC(double c) +void TransformationMatrix::setC(double c) { m_transform.c = narrowPrecisionToCGFloat(c); } -double AffineTransform::d() const +double TransformationMatrix::d() const { return m_transform.d; } -void AffineTransform::setD(double d) +void TransformationMatrix::setD(double d) { m_transform.d = narrowPrecisionToCGFloat(d); } -double AffineTransform::e() const +double TransformationMatrix::e() const { return m_transform.tx; } -void AffineTransform::setE(double e) +void TransformationMatrix::setE(double e) { m_transform.tx = narrowPrecisionToCGFloat(e); } -double AffineTransform::f() const +double TransformationMatrix::f() const { return m_transform.ty; } -void AffineTransform::setF(double f) +void TransformationMatrix::setF(double f) { m_transform.ty = narrowPrecisionToCGFloat(f); } -void AffineTransform::reset() +void TransformationMatrix::reset() { m_transform = CGAffineTransformIdentity; } -AffineTransform &AffineTransform::scale(double sx, double sy) +TransformationMatrix &TransformationMatrix::scale(double sx, double sy) { m_transform = CGAffineTransformScale(m_transform, narrowPrecisionToCGFloat(sx), narrowPrecisionToCGFloat(sy)); return *this; } -AffineTransform &AffineTransform::rotate(double d) +TransformationMatrix &TransformationMatrix::rotate(double d) { m_transform = CGAffineTransformRotate(m_transform, narrowPrecisionToCGFloat(deg2rad(d))); return *this; } -AffineTransform &AffineTransform::translate(double tx, double ty) +TransformationMatrix &TransformationMatrix::translate(double tx, double ty) { m_transform = CGAffineTransformTranslate(m_transform, narrowPrecisionToCGFloat(tx), narrowPrecisionToCGFloat(ty)); return *this; } -AffineTransform &AffineTransform::shear(double sx, double sy) +TransformationMatrix &TransformationMatrix::shear(double sx, double sy) { CGAffineTransform shear = CGAffineTransformMake(1.0f, narrowPrecisionToCGFloat(sy), narrowPrecisionToCGFloat(sx), 1.0f, 0.0f, 0.0f); m_transform = CGAffineTransformConcat(shear, m_transform); return *this; } -double AffineTransform::det() const +double TransformationMatrix::det() const { return m_transform.a * m_transform.d - m_transform.b * m_transform.c; } -AffineTransform AffineTransform::inverse() const +TransformationMatrix TransformationMatrix::inverse() const { if (isInvertible()) - return AffineTransform(CGAffineTransformInvert(m_transform)); - return AffineTransform(); + return TransformationMatrix(CGAffineTransformInvert(m_transform)); + return TransformationMatrix(); } -AffineTransform::operator PlatformAffineTransform() const +TransformationMatrix::operator PlatformTransformationMatrix() const { return m_transform; } -bool AffineTransform::operator== (const AffineTransform &m2) const +bool TransformationMatrix::operator== (const TransformationMatrix &m2) const { return CGAffineTransformEqualToTransform(m_transform, CGAffineTransform(m2)); } -AffineTransform &AffineTransform::operator*= (const AffineTransform &m2) +TransformationMatrix &TransformationMatrix::operator*= (const TransformationMatrix &m2) { m_transform = CGAffineTransformConcat(m_transform, CGAffineTransform(m2)); return *this; } -AffineTransform AffineTransform::operator* (const AffineTransform &m2) +TransformationMatrix TransformationMatrix::operator* (const TransformationMatrix &m2) { return CGAffineTransformConcat(m_transform, CGAffineTransform(m2)); } |