diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:41 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:41 -0800 |
commit | 648161bb0edfc3d43db63caed5cc5213bc6cb78f (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /WebCore/platform/graphics/cg | |
parent | a65af38181ac7d34544586bdb5cd004de93897ad (diff) | |
download | external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.zip external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.tar.gz external_webkit-648161bb0edfc3d43db63caed5cc5213bc6cb78f.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'WebCore/platform/graphics/cg')
19 files changed, 0 insertions, 3381 deletions
diff --git a/WebCore/platform/graphics/cg/AffineTransformCG.cpp b/WebCore/platform/graphics/cg/AffineTransformCG.cpp deleted file mode 100644 index 4f0bca0..0000000 --- a/WebCore/platform/graphics/cg/AffineTransformCG.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007 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 COMPUTER, 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 COMPUTER, 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 "AffineTransform.h" - -#if PLATFORM(CG) - -#include "FloatConversion.h" -#include "FloatRect.h" -#include "IntRect.h" - -#include <wtf/MathExtras.h> - -namespace WebCore { - -AffineTransform::AffineTransform() - : m_transform(CGAffineTransformIdentity) -{ -} - -AffineTransform::AffineTransform(double a, double b, double c, double d, double tx, double ty) -{ - m_transform = CGAffineTransformMake(narrowPrecisionToCGFloat(a), - narrowPrecisionToCGFloat(b), - narrowPrecisionToCGFloat(c), - narrowPrecisionToCGFloat(d), - narrowPrecisionToCGFloat(tx), - narrowPrecisionToCGFloat(ty)); -} - -AffineTransform::AffineTransform(const PlatformAffineTransform& t) - : m_transform(t) -{ -} - -void AffineTransform::setMatrix(double a, double b, double c, double d, double tx, double ty) -{ - m_transform = CGAffineTransformMake(narrowPrecisionToCGFloat(a), - narrowPrecisionToCGFloat(b), - narrowPrecisionToCGFloat(c), - narrowPrecisionToCGFloat(d), - narrowPrecisionToCGFloat(tx), - narrowPrecisionToCGFloat(ty)); -} - -void AffineTransform::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 -{ - return enclosingIntRect(CGRectApplyAffineTransform(CGRect(rect), m_transform)); -} - -FloatRect AffineTransform::mapRect(const FloatRect &rect) const -{ - return FloatRect(CGRectApplyAffineTransform(CGRect(rect), m_transform)); -} - -bool AffineTransform::isIdentity() const -{ - return CGAffineTransformIsIdentity(m_transform); -} - -double AffineTransform::a() const -{ - return m_transform.a; -} - -void AffineTransform::setA(double a) -{ - m_transform.a = narrowPrecisionToCGFloat(a); -} - -double AffineTransform::b() const -{ - return m_transform.b; -} - -void AffineTransform::setB(double b) -{ - m_transform.b = narrowPrecisionToCGFloat(b); -} - -double AffineTransform::c() const -{ - return m_transform.c; -} - -void AffineTransform::setC(double c) -{ - m_transform.c = narrowPrecisionToCGFloat(c); -} - -double AffineTransform::d() const -{ - return m_transform.d; -} - -void AffineTransform::setD(double d) -{ - m_transform.d = narrowPrecisionToCGFloat(d); -} - -double AffineTransform::e() const -{ - return m_transform.tx; -} - -void AffineTransform::setE(double e) -{ - m_transform.tx = narrowPrecisionToCGFloat(e); -} - -double AffineTransform::f() const -{ - return m_transform.ty; -} - -void AffineTransform::setF(double f) -{ - m_transform.ty = narrowPrecisionToCGFloat(f); -} - -void AffineTransform::reset() -{ - m_transform = CGAffineTransformIdentity; -} - -AffineTransform &AffineTransform::scale(double sx, double sy) -{ - m_transform = CGAffineTransformScale(m_transform, narrowPrecisionToCGFloat(sx), narrowPrecisionToCGFloat(sy)); - return *this; -} - -AffineTransform &AffineTransform::rotate(double d) -{ - m_transform = CGAffineTransformRotate(m_transform, narrowPrecisionToCGFloat(deg2rad(d))); - return *this; -} - -AffineTransform &AffineTransform::translate(double tx, double ty) -{ - m_transform = CGAffineTransformTranslate(m_transform, narrowPrecisionToCGFloat(tx), narrowPrecisionToCGFloat(ty)); - return *this; -} - -AffineTransform &AffineTransform::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 -{ - return m_transform.a * m_transform.d - m_transform.b * m_transform.c; -} - -AffineTransform AffineTransform::inverse() const -{ - if (isInvertible()) - return AffineTransform(CGAffineTransformInvert(m_transform)); - return AffineTransform(); -} - -AffineTransform::operator PlatformAffineTransform() const -{ - return m_transform; -} - -bool AffineTransform::operator== (const AffineTransform &m2) const -{ - return CGAffineTransformEqualToTransform(m_transform, CGAffineTransform(m2)); -} - -AffineTransform &AffineTransform::operator*= (const AffineTransform &m2) -{ - m_transform = CGAffineTransformConcat(m_transform, CGAffineTransform(m2)); - return *this; -} - -AffineTransform AffineTransform::operator* (const AffineTransform &m2) -{ - return CGAffineTransformConcat(m_transform, CGAffineTransform(m2)); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/ColorCG.cpp b/WebCore/platform/graphics/cg/ColorCG.cpp deleted file mode 100644 index 48ce9f2..0000000 --- a/WebCore/platform/graphics/cg/ColorCG.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007 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 COMPUTER, 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 COMPUTER, 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 "Color.h" - -#if PLATFORM(CG) - -#include <wtf/Assertions.h> -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -Color::Color(CGColorRef color) -{ - if (!color) { - m_color = 0; - m_valid = false; - return; - } - - size_t numComponents = CGColorGetNumberOfComponents(color); - const CGFloat* components = CGColorGetComponents(color); - - float r = 0; - float g = 0; - float b = 0; - float a = 0; - - switch (numComponents) { - case 2: - r = g = b = components[0]; - a = components[1]; - break; - case 4: - r = components[0]; - g = components[1]; - b = components[2]; - a = components[3]; - break; - default: - ASSERT_NOT_REACHED(); - } - - m_color = makeRGBA(r * 255, g * 255, b * 255, a * 255); -} - -#if !PLATFORM(MAC) - -CGColorRef cgColor(const Color& c) -{ - CGColorRef color = NULL; - CMProfileRef prof = NULL; - CMGetSystemProfile(&prof); - - CGColorSpaceRef rgbSpace = CGColorSpaceCreateWithPlatformColorSpace(prof); - - if (rgbSpace != NULL) - { - float components[4] = {c.red() / 255.0f, c.green() / 255.0f, c.blue() / 255.0f, c.alpha() / 255.0f}; - color = CGColorCreate(rgbSpace, components); - CGColorSpaceRelease(rgbSpace); - } - - CMCloseProfile(prof); - - return color; -} - -#endif // !PLATFORM(MAC) - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/FloatPointCG.cpp b/WebCore/platform/graphics/cg/FloatPointCG.cpp deleted file mode 100644 index f9c3353..0000000 --- a/WebCore/platform/graphics/cg/FloatPointCG.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2005 Nokia. 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 COMPUTER, 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 COMPUTER, 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 "FloatPoint.h" - -#if PLATFORM(CG) - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -FloatPoint::FloatPoint(const CGPoint& p) : m_x(p.x), m_y(p.y) -{ -} - -FloatPoint::operator CGPoint() const -{ - return CGPointMake(m_x, m_y); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/FloatRectCG.cpp b/WebCore/platform/graphics/cg/FloatRectCG.cpp deleted file mode 100644 index a1ce367..0000000 --- a/WebCore/platform/graphics/cg/FloatRectCG.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2005 Nokia. 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 COMPUTER, 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 COMPUTER, 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 "FloatRect.h" - -#if PLATFORM(CG) - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -FloatRect::FloatRect(const CGRect& r) : m_location(r.origin), m_size(r.size) -{ -} - -FloatRect::operator CGRect() const -{ - return CGRectMake(x(), y(), width(), height()); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/FloatSizeCG.cpp b/WebCore/platform/graphics/cg/FloatSizeCG.cpp deleted file mode 100644 index 383af21..0000000 --- a/WebCore/platform/graphics/cg/FloatSizeCG.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2005 Nokia. 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 COMPUTER, 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 COMPUTER, 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 "FloatSize.h" - -#if PLATFORM(CG) - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -FloatSize::FloatSize(const CGSize& s) : m_width(s.width), m_height(s.height) -{ -} - -FloatSize::operator CGSize() const -{ - return CGSizeMake(m_width, m_height); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/GradientCG.cpp b/WebCore/platform/graphics/cg/GradientCG.cpp deleted file mode 100644 index c189fd5..0000000 --- a/WebCore/platform/graphics/cg/GradientCG.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2007 Alp Toker <alp@atoker.com> - * - * 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 COMPUTER, 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 COMPUTER, 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 "Gradient.h" - -#include "CSSParser.h" -#include "GraphicsContext.h" - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -void Gradient::platformDestroy() -{ - CGShadingRelease(m_gradient); - m_gradient = 0; -} - -static void gradientCallback(void* info, const CGFloat* in, CGFloat* out) -{ - float r, g, b, a; - static_cast<const Gradient*>(info)->getColor(*in, &r, &g, &b, &a); - out[0] = r; - out[1] = g; - out[2] = b; - out[3] = a; -} - -CGShadingRef Gradient::platformGradient() -{ - if (m_gradient) - return m_gradient; - - const CGFloat intervalRanges[2] = { 0, 1 }; - const CGFloat colorComponentRanges[4 * 2] = { 0, 1, 0, 1, 0, 1, 0, 1 }; - const CGFunctionCallbacks gradientCallbacks = { 0, gradientCallback, 0 }; - CGFunctionRef colorFunction = CGFunctionCreate(this, 1, intervalRanges, 4, colorComponentRanges, &gradientCallbacks); - - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - - if (m_radial) - m_gradient = CGShadingCreateRadial(colorSpace, m_p0, m_r0, m_p1, m_r1, colorFunction, true, true); - else - m_gradient = CGShadingCreateAxial(colorSpace, m_p0, m_p1, colorFunction, true, true); - - CGColorSpaceRelease(colorSpace); - CGFunctionRelease(colorFunction); - - return m_gradient; -} - -void Gradient::fill(GraphicsContext* context, const FloatRect& rect) -{ - context->clip(rect); - CGContextDrawShading(context->platformContext(), platformGradient()); -} - -} //namespace diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp deleted file mode 100644 index 3f0e6e7..0000000 --- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ /dev/null @@ -1,1144 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2008 Eric Seidel <eric@webkit.org> - * - * 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 COMPUTER, 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 COMPUTER, 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. - */ - -#define _USE_MATH_DEFINES 1 -#include "config.h" -#include "GraphicsContext.h" - -#include "AffineTransform.h" -#include "FloatConversion.h" -#include "GraphicsContextPrivate.h" -#include "GraphicsContextPlatformPrivateCG.h" -#include "ImageBuffer.h" -#include "KURL.h" -#include "Path.h" -#include "Pattern.h" -#include <CoreGraphics/CGBitmapContext.h> -#include <CoreGraphics/CGPDFContext.h> -#include <wtf/MathExtras.h> -#include <wtf/OwnArrayPtr.h> -#include <wtf/RetainPtr.h> - -#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) -#define HAVE_CG_INTERPOLATION_MEDIUM 1 -#endif - -using namespace std; - -namespace WebCore { - -static void setCGFillColor(CGContextRef context, const Color& color) -{ - CGFloat red, green, blue, alpha; - color.getRGBA(red, green, blue, alpha); - CGContextSetRGBFillColor(context, red, green, blue, alpha); -} - -static void setCGStrokeColor(CGContextRef context, const Color& color) -{ - CGFloat red, green, blue, alpha; - color.getRGBA(red, green, blue, alpha); - CGContextSetRGBStrokeColor(context, red, green, blue, alpha); -} - -GraphicsContext::GraphicsContext(CGContextRef cgContext) - : m_common(createGraphicsContextPrivate()) - , m_data(new GraphicsContextPlatformPrivate(cgContext)) -{ - setPaintingDisabled(!cgContext); - if (cgContext) { - // Make sure the context starts in sync with our state. - setPlatformFillColor(fillColor()); - setPlatformStrokeColor(strokeColor()); - } -} - -GraphicsContext::~GraphicsContext() -{ - destroyGraphicsContextPrivate(m_common); - delete m_data; -} - -CGContextRef GraphicsContext::platformContext() const -{ - ASSERT(!paintingDisabled()); - ASSERT(m_data->m_cgContext); - return m_data->m_cgContext; -} - -void GraphicsContext::savePlatformState() -{ - // Note: Do not use this function within this class implementation, since we want to avoid the extra - // save of the secondary context (in GraphicsContextPlatformPrivateCG.h). - CGContextSaveGState(platformContext()); - m_data->save(); -} - -void GraphicsContext::restorePlatformState() -{ - // Note: Do not use this function within this class implementation, since we want to avoid the extra - // restore of the secondary context (in GraphicsContextPlatformPrivateCG.h). - CGContextRestoreGState(platformContext()); - m_data->restore(); - m_data->m_userToDeviceTransformKnownToBeIdentity = false; -} - -// Draws a filled rectangle with a stroked border. -void GraphicsContext::drawRect(const IntRect& rect) -{ - // FIXME: this function does not handle patterns and gradients - // like drawPath does, it probably should. - if (paintingDisabled()) - return; - - CGContextRef context = platformContext(); - - if (fillColor().alpha()) - CGContextFillRect(context, rect); - - if (strokeStyle() != NoStroke && strokeColor().alpha()) { - // We do a fill of four rects to simulate the stroke of a border. - Color oldFillColor = fillColor(); - if (oldFillColor != strokeColor()) - setCGFillColor(context, strokeColor()); - CGRect rects[4] = { - FloatRect(rect.x(), rect.y(), rect.width(), 1), - FloatRect(rect.x(), rect.bottom() - 1, rect.width(), 1), - FloatRect(rect.x(), rect.y() + 1, 1, rect.height() - 2), - FloatRect(rect.right() - 1, rect.y() + 1, 1, rect.height() - 2) - }; - CGContextFillRects(context, rects, 4); - if (oldFillColor != strokeColor()) - setCGFillColor(context, oldFillColor); - } -} - -// This is only used to draw borders. -void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) -{ - if (paintingDisabled()) - return; - - if (strokeStyle() == NoStroke || !strokeColor().alpha()) - return; - - float width = strokeThickness(); - - FloatPoint p1 = point1; - FloatPoint p2 = point2; - bool isVerticalLine = (p1.x() == p2.x()); - - // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic - // works out. For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g., - // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave - // us a perfect position, but an odd width gave us a position that is off by exactly 0.5. - if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) { - if (isVerticalLine) { - p1.move(0, width); - p2.move(0, -width); - } else { - p1.move(width, 0); - p2.move(-width, 0); - } - } - - if (((int)width) % 2) { - if (isVerticalLine) { - // We're a vertical line. Adjust our x. - p1.move(0.5f, 0.0f); - p2.move(0.5f, 0.0f); - } else { - // We're a horizontal line. Adjust our y. - p1.move(0.0f, 0.5f); - p2.move(0.0f, 0.5f); - } - } - - int patWidth = 0; - switch (strokeStyle()) { - case NoStroke: - case SolidStroke: - break; - case DottedStroke: - patWidth = (int)width; - break; - case DashedStroke: - patWidth = 3 * (int)width; - break; - } - - CGContextRef context = platformContext(); - CGContextSaveGState(context); - - CGContextSetShouldAntialias(context, false); - - if (patWidth) { - // 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. - if (isVerticalLine) { - CGContextFillRect(context, FloatRect(p1.x() - width / 2, p1.y() - width, width, width)); - CGContextFillRect(context, FloatRect(p2.x() - width / 2, p2.y(), width, width)); - } else { - CGContextFillRect(context, FloatRect(p1.x() - width, p1.y() - width / 2, width, width)); - CGContextFillRect(context, FloatRect(p2.x(), p2.y() - width / 2, width, width)); - } - - // Example: 80 pixels with a width of 30 pixels. - // Remainder is 20. The maximum pixels of line we could paint - // will be 50 pixels. - int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*(int)width; - int remainder = distance % patWidth; - int coverage = distance - remainder; - int numSegments = coverage / patWidth; - - float patternOffset = 0.0f; - // Special case 1px dotted borders for speed. - if (patWidth == 1) - patternOffset = 1.0f; - else { - bool evenNumberOfSegments = numSegments % 2 == 0; - if (remainder) - evenNumberOfSegments = !evenNumberOfSegments; - if (evenNumberOfSegments) { - if (remainder) { - patternOffset += patWidth - remainder; - patternOffset += remainder / 2; - } else - patternOffset = patWidth / 2; - } else { - if (remainder) - patternOffset = (patWidth - remainder)/2; - } - } - - const CGFloat dottedLine[2] = { patWidth, patWidth }; - CGContextSetLineDash(context, patternOffset, dottedLine, 2); - } - - CGContextBeginPath(context); - CGContextMoveToPoint(context, p1.x(), p1.y()); - CGContextAddLineToPoint(context, p2.x(), p2.y()); - - CGContextStrokePath(context); - - CGContextRestoreGState(context); -} - -// This method is only used to draw the little circles used in lists. -void GraphicsContext::drawEllipse(const IntRect& rect) -{ - // FIXME: CG added CGContextAddEllipseinRect in Tiger, so we should be able to quite easily draw an ellipse. - // This code can only handle circles, not ellipses. But khtml only - // uses it for circles. - ASSERT(rect.width() == rect.height()); - - if (paintingDisabled()) - return; - - CGContextRef context = platformContext(); - CGContextBeginPath(context); - float r = (float)rect.width() / 2; - CGContextAddArc(context, rect.x() + r, rect.y() + r, r, 0.0f, 2.0f * piFloat, 0); - CGContextClosePath(context); - - drawPath(); -} - - -void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) -{ - if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha()) - return; - - CGContextRef context = platformContext(); - CGContextSaveGState(context); - CGContextBeginPath(context); - CGContextSetShouldAntialias(context, false); - - int x = rect.x(); - int y = rect.y(); - float w = (float)rect.width(); - float h = (float)rect.height(); - float scaleFactor = h / w; - float reverseScaleFactor = w / h; - - if (w != h) - scale(FloatSize(1, scaleFactor)); - - float hRadius = w / 2; - float vRadius = h / 2; - float fa = startAngle; - float falen = fa + angleSpan; - float start = -fa * piFloat / 180.0f; - float end = -falen * piFloat / 180.0f; - CGContextAddArc(context, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, start, end, true); - - if (w != h) - scale(FloatSize(1, reverseScaleFactor)); - - - float width = strokeThickness(); - int patWidth = 0; - - switch (strokeStyle()) { - case DottedStroke: - patWidth = (int)(width / 2); - break; - case DashedStroke: - patWidth = 3 * (int)(width / 2); - break; - default: - break; - } - - if (patWidth) { - // Example: 80 pixels with a width of 30 pixels. - // Remainder is 20. The maximum pixels of line we could paint - // will be 50 pixels. - int distance; - if (hRadius == vRadius) - distance = static_cast<int>((piFloat * hRadius) / 2.0f); - else // We are elliptical and will have to estimate the distance - distance = static_cast<int>((piFloat * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0f)) / 2.0f); - - int remainder = distance % patWidth; - int coverage = distance - remainder; - int numSegments = coverage / patWidth; - - float patternOffset = 0.0f; - // Special case 1px dotted borders for speed. - if (patWidth == 1) - patternOffset = 1.0f; - else { - bool evenNumberOfSegments = numSegments % 2 == 0; - if (remainder) - evenNumberOfSegments = !evenNumberOfSegments; - if (evenNumberOfSegments) { - if (remainder) { - patternOffset += patWidth - remainder; - patternOffset += remainder / 2.0f; - } else - patternOffset = patWidth / 2.0f; - } else { - if (remainder) - patternOffset = (patWidth - remainder) / 2.0f; - } - } - - const CGFloat dottedLine[2] = { patWidth, patWidth }; - CGContextSetLineDash(context, patternOffset, dottedLine, 2); - } - - CGContextStrokePath(context); - - CGContextRestoreGState(context); -} - -void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias) -{ - if (paintingDisabled() || !fillColor().alpha() && (strokeThickness() <= 0 || strokeStyle() == NoStroke)) - return; - - if (npoints <= 1) - return; - - CGContextRef context = platformContext(); - - CGContextSaveGState(context); - - CGContextSetShouldAntialias(context, shouldAntialias); - - CGContextBeginPath(context); - CGContextMoveToPoint(context, points[0].x(), points[0].y()); - for (size_t i = 1; i < npoints; i++) - CGContextAddLineToPoint(context, points[i].x(), points[i].y()); - CGContextClosePath(context); - - drawPath(); - - CGContextRestoreGState(context); -} - -static void applyStrokePattern(GraphicsContext* context, Pattern* pattern) -{ - CGContextRef cgContext = context->platformContext(); - - CGPatternRef platformPattern = pattern->createPlatformPattern(context->getCTM()); - if (!platformPattern) - return; - - CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0); - CGContextSetStrokeColorSpace(cgContext, patternSpace); - CGColorSpaceRelease(patternSpace); - - const CGFloat patternAlpha = 1; - CGContextSetStrokePattern(cgContext, platformPattern, &patternAlpha); - CGPatternRelease(platformPattern); -} - -static void applyFillPattern(GraphicsContext* context, Pattern* pattern) -{ - CGContextRef cgContext = context->platformContext(); - - CGPatternRef platformPattern = pattern->createPlatformPattern(context->getCTM()); - if (!platformPattern) - return; - - CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0); - CGContextSetFillColorSpace(cgContext, patternSpace); - CGColorSpaceRelease(patternSpace); - - const CGFloat patternAlpha = 1; - CGContextSetFillPattern(cgContext, platformPattern, &patternAlpha); - CGPatternRelease(platformPattern); -} - -static inline bool calculateDrawingMode(const GraphicsContextState& state, CGPathDrawingMode& mode) -{ - bool shouldFill = state.fillColorSpace == PatternColorSpace || state.fillColor.alpha(); - bool shouldStroke = state.strokeColorSpace == PatternColorSpace || (state.strokeStyle != NoStroke && state.strokeColor.alpha()); - bool useEOFill = state.fillRule == RULE_EVENODD; - - if (shouldFill) { - if (shouldStroke) { - if (useEOFill) - mode = kCGPathEOFillStroke; - else - mode = kCGPathFillStroke; - } else { // fill, no stroke - if (useEOFill) - mode = kCGPathEOFill; - else - mode = kCGPathFill; - } - } else { - // Setting mode to kCGPathStroke even if shouldStroke is false. In that case, we return false and mode will not be used, - // but the compiler will not compain about an uninitialized variable. - mode = kCGPathStroke; - } - - return shouldFill || shouldStroke; -} - -void GraphicsContext::drawPath() -{ - if (paintingDisabled()) - return; - - CGContextRef context = platformContext(); - const GraphicsContextState& state = m_common->state; - - if (state.fillColorSpace == GradientColorSpace || state.strokeColorSpace == GradientColorSpace) { - // We don't have any optimized way to fill & stroke a path using gradients - fillPath(); - strokePath(); - return; - } - - if (state.fillColorSpace == PatternColorSpace) - applyFillPattern(this, m_common->state.fillPattern.get()); - if (state.strokeColorSpace == PatternColorSpace) - applyStrokePattern(this, m_common->state.strokePattern.get()); - - CGPathDrawingMode drawingMode; - if (calculateDrawingMode(state, drawingMode)) - CGContextDrawPath(context, drawingMode); -} - -static inline void fillPathWithFillRule(CGContextRef context, WindRule fillRule) -{ - if (fillRule == RULE_EVENODD) - CGContextEOFillPath(context); - else - CGContextFillPath(context); -} - -void GraphicsContext::fillPath() -{ - if (paintingDisabled()) - return; - - CGContextRef context = platformContext(); - switch (m_common->state.fillColorSpace) { - case SolidColorSpace: - if (fillColor().alpha()) - fillPathWithFillRule(context, fillRule()); - break; - case PatternColorSpace: - applyFillPattern(this, m_common->state.fillPattern.get()); - fillPathWithFillRule(context, fillRule()); - break; - case GradientColorSpace: - CGContextSaveGState(context); - if (fillRule() == RULE_EVENODD) - CGContextEOClip(context); - else - CGContextClip(context); - CGContextDrawShading(context, m_common->state.fillGradient->platformGradient()); - CGContextRestoreGState(context); - break; - } -} - -void GraphicsContext::strokePath() -{ - if (paintingDisabled()) - return; - - CGContextRef context = platformContext(); - switch (m_common->state.strokeColorSpace) { - case SolidColorSpace: - if (fillColor().alpha()) - CGContextStrokePath(context); - break; - case PatternColorSpace: - applyStrokePattern(this, m_common->state.strokePattern.get()); - CGContextStrokePath(context); - break; - case GradientColorSpace: - CGContextSaveGState(context); - CGContextReplacePathWithStrokedPath(context); - CGContextClip(context); - CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient()); - CGContextRestoreGState(context); - break; - } -} - -void GraphicsContext::fillRect(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - CGContextRef context = platformContext(); - switch (m_common->state.fillColorSpace) { - case SolidColorSpace: - if (fillColor().alpha()) - CGContextFillRect(context, rect); - break; - case PatternColorSpace: - applyFillPattern(this, m_common->state.fillPattern.get()); - CGContextFillRect(context, rect); - break; - case GradientColorSpace: - CGContextSaveGState(context); - CGContextClipToRect(context, rect); - CGContextDrawShading(context, m_common->state.fillGradient->platformGradient()); - CGContextRestoreGState(context); - break; - } -} - -void GraphicsContext::fillRect(const FloatRect& rect, const Color& color) -{ - if (paintingDisabled()) - return; - if (color.alpha()) { - CGContextRef context = platformContext(); - Color oldFillColor = fillColor(); - if (oldFillColor != color) - setCGFillColor(context, color); - CGContextFillRect(context, rect); - if (oldFillColor != color) - setCGFillColor(context, oldFillColor); - } -} - -void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color) -{ - if (paintingDisabled() || !color.alpha()) - return; - - CGContextRef context = platformContext(); - Color oldFillColor = fillColor(); - if (oldFillColor != color) - setCGFillColor(context, color); - - addPath(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight)); - fillPath(); - - if (oldFillColor != color) - setCGFillColor(context, oldFillColor); -} - -void GraphicsContext::clip(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - CGContextClipToRect(platformContext(), rect); - m_data->clip(rect); -} - -void GraphicsContext::clipOut(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - CGRect rects[2] = { CGContextGetClipBoundingBox(platformContext()), rect }; - CGContextBeginPath(platformContext()); - CGContextAddRects(platformContext(), rects, 2); - CGContextEOClip(platformContext()); -} - -void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - CGContextBeginPath(platformContext()); - CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); - CGContextAddEllipseInRect(platformContext(), rect); - CGContextEOClip(platformContext()); -} - -void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) -{ - if (paintingDisabled()) - return; - - clip(rect); - CGContextRef context = platformContext(); - - // Add outer ellipse - CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); - // Add inner ellipse. - CGContextAddEllipseInRect(context, CGRectMake(rect.x() + thickness, rect.y() + thickness, - rect.width() - (thickness * 2), rect.height() - (thickness * 2))); - - 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()) - return; - CGContextRef context = platformContext(); - CGContextSaveGState(context); - CGContextSetAlpha(context, opacity); - CGContextBeginTransparencyLayer(context, 0); - m_data->beginTransparencyLayer(); - m_data->m_userToDeviceTransformKnownToBeIdentity = false; -} - -void GraphicsContext::endTransparencyLayer() -{ - if (paintingDisabled()) - return; - CGContextRef context = platformContext(); - CGContextEndTransparencyLayer(context); - CGContextRestoreGState(context); - m_data->endTransparencyLayer(); - m_data->m_userToDeviceTransformKnownToBeIdentity = false; -} - -void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color) -{ - if (paintingDisabled()) - return; - 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; - - CGFloat smallEigenvalue = narrowPrecisionToCGFloat(sqrt(0.5 * ((A + D) - sqrt(4 * B * C + (A - D) * (A - D))))); - - // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp - CGFloat blurRadius = min(blur * smallEigenvalue, narrowPrecisionToCGFloat(1000.0)); - - CGSize sizeInDeviceSpace = CGSizeApplyAffineTransform(size, transform); - - CGFloat width = sizeInDeviceSpace.width; - CGFloat height = sizeInDeviceSpace.height; - - // Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated - // to the desired integer. - static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128); - if (width > 0) - width += extraShadowOffset; - else if (width < 0) - width -= extraShadowOffset; - - if (height > 0) - height += extraShadowOffset; - else if (height < 0) - height -= extraShadowOffset; - - // Check for an invalid color, as this means that the color was not set for the shadow - // and we should therefore just use the default shadow color. - if (!color.isValid()) - CGContextSetShadow(context, CGSizeMake(width, height), blurRadius); - else { - CGColorRef colorCG = cgColor(color); - CGContextSetShadowWithColor(context, - CGSizeMake(width, height), - blurRadius, - colorCG); - CGColorRelease(colorCG); - } -} - -void GraphicsContext::clearPlatformShadow() -{ - if (paintingDisabled()) - return; - CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0); -} - -void GraphicsContext::setMiterLimit(float limit) -{ - if (paintingDisabled()) - return; - CGContextSetMiterLimit(platformContext(), limit); -} - -void GraphicsContext::setAlpha(float alpha) -{ - if (paintingDisabled()) - return; - CGContextSetAlpha(platformContext(), alpha); -} - -void GraphicsContext::clearRect(const FloatRect& r) -{ - if (paintingDisabled()) - return; - CGContextClearRect(platformContext(), r); -} - -void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth) -{ - if (paintingDisabled()) - return; - CGContextStrokeRectWithWidth(platformContext(), r, lineWidth); -} - -void GraphicsContext::setLineCap(LineCap cap) -{ - if (paintingDisabled()) - return; - switch (cap) { - case ButtCap: - CGContextSetLineCap(platformContext(), kCGLineCapButt); - break; - case RoundCap: - CGContextSetLineCap(platformContext(), kCGLineCapRound); - break; - case SquareCap: - CGContextSetLineCap(platformContext(), kCGLineCapSquare); - break; - } -} - -void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) -{ - CGContextSetLineDash(platformContext(), dashOffset, dashes.data(), dashes.size()); -} - -void GraphicsContext::setLineJoin(LineJoin join) -{ - if (paintingDisabled()) - return; - switch (join) { - case MiterJoin: - CGContextSetLineJoin(platformContext(), kCGLineJoinMiter); - break; - case RoundJoin: - CGContextSetLineJoin(platformContext(), kCGLineJoinRound); - break; - case BevelJoin: - CGContextSetLineJoin(platformContext(), kCGLineJoinBevel); - break; - } -} - -void GraphicsContext::beginPath() -{ - CGContextBeginPath(platformContext()); -} - -void GraphicsContext::addPath(const Path& path) -{ - CGContextAddPath(platformContext(), path.platformPath()); -} - -void GraphicsContext::clip(const Path& path) -{ - if (paintingDisabled()) - return; - CGContextRef context = platformContext(); - CGContextBeginPath(context); - CGContextAddPath(context, path.platformPath()); - CGContextClip(context); - m_data->clip(path); -} - -void GraphicsContext::clipOut(const Path& path) -{ - if (paintingDisabled()) - return; - - CGContextBeginPath(platformContext()); - CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); - CGContextAddPath(platformContext(), path.platformPath()); - CGContextEOClip(platformContext()); -} - -void GraphicsContext::scale(const FloatSize& size) -{ - if (paintingDisabled()) - return; - CGContextScaleCTM(platformContext(), size.width(), size.height()); - m_data->scale(size); - m_data->m_userToDeviceTransformKnownToBeIdentity = false; -} - -void GraphicsContext::rotate(float angle) -{ - if (paintingDisabled()) - return; - CGContextRotateCTM(platformContext(), angle); - m_data->rotate(angle); - m_data->m_userToDeviceTransformKnownToBeIdentity = false; -} - -void GraphicsContext::translate(float x, float y) -{ - if (paintingDisabled()) - return; - CGContextTranslateCTM(platformContext(), x, y); - m_data->translate(x, y); - m_data->m_userToDeviceTransformKnownToBeIdentity = false; -} - -void GraphicsContext::concatCTM(const AffineTransform& transform) -{ - if (paintingDisabled()) - return; - CGContextConcatCTM(platformContext(), transform); - m_data->concatCTM(transform); - m_data->m_userToDeviceTransformKnownToBeIdentity = false; -} - -AffineTransform GraphicsContext::getCTM() const -{ - return CGContextGetCTM(platformContext()); -} - -FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) -{ - // It is not enough just to round to pixels in device space. The rotation part of the - // affine transform matrix to device space can mess with this conversion if we have a - // rotating image like the hands of the world clock widget. We just need the scale, so - // we get the affine transform matrix and extract the scale. - - if (m_data->m_userToDeviceTransformKnownToBeIdentity) - return rect; - - CGAffineTransform deviceMatrix = CGContextGetUserSpaceToDeviceSpaceTransform(platformContext()); - if (CGAffineTransformIsIdentity(deviceMatrix)) { - m_data->m_userToDeviceTransformKnownToBeIdentity = true; - return rect; - } - - float deviceScaleX = sqrtf(deviceMatrix.a * deviceMatrix.a + deviceMatrix.b * deviceMatrix.b); - float deviceScaleY = sqrtf(deviceMatrix.c * deviceMatrix.c + deviceMatrix.d * deviceMatrix.d); - - CGPoint deviceOrigin = CGPointMake(rect.x() * deviceScaleX, rect.y() * deviceScaleY); - CGPoint deviceLowerRight = CGPointMake((rect.x() + rect.width()) * deviceScaleX, - (rect.y() + rect.height()) * deviceScaleY); - - deviceOrigin.x = roundf(deviceOrigin.x); - deviceOrigin.y = roundf(deviceOrigin.y); - deviceLowerRight.x = roundf(deviceLowerRight.x); - deviceLowerRight.y = roundf(deviceLowerRight.y); - - // Don't let the height or width round to 0 unless either was originally 0 - if (deviceOrigin.y == deviceLowerRight.y && rect.height() != 0) - deviceLowerRight.y += 1; - if (deviceOrigin.x == deviceLowerRight.x && rect.width() != 0) - deviceLowerRight.x += 1; - - FloatPoint roundedOrigin = FloatPoint(deviceOrigin.x / deviceScaleX, deviceOrigin.y / deviceScaleY); - FloatPoint roundedLowerRight = FloatPoint(deviceLowerRight.x / deviceScaleX, deviceLowerRight.y / deviceScaleY); - return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); -} - -void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool printing) -{ - if (paintingDisabled()) - return; - - if (width <= 0) - return; - - CGContextSaveGState(platformContext()); - - float x = point.x(); - float y = point.y(); - float lineLength = width; - - // Use a minimum thickness of 0.5 in user space. - // 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); - - 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); - - // FIXME: This should be done a better way. - // We try to round all parameters to integer boundaries in device space. If rounding pixels in device space - // makes our thickness more than double, then there must be a shrinking-scale factor and rounding to pixels - // in device space will make the underlines too thick. - CGRect lineRect = roundToDevicePixels(FloatRect(x, y, lineLength, adjustedThickness)); - if (lineRect.size.height < thickness * 2.0) { - x = lineRect.origin.x; - y = lineRect.origin.y; - lineLength = lineRect.size.width; - thickness = lineRect.size.height; - CGContextSetShouldAntialias(platformContext(), false); - } - } - - if (fillColor() != strokeColor()) - setCGFillColor(platformContext(), strokeColor()); - CGContextFillRect(platformContext(), CGRectMake(x, y, lineLength, thickness)); - - CGContextRestoreGState(platformContext()); -} - -void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) -{ - if (paintingDisabled()) - return; - - CFURLRef urlRef = link.createCFURL(); - if (urlRef) { - CGContextRef context = platformContext(); - - // Get the bounding box to handle clipping. - CGRect box = CGContextGetClipBoundingBox(context); - - IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height); - IntRect rect = destRect; - rect.intersect(intBox); - - CGPDFContextSetURLForRect(context, urlRef, - CGRectApplyAffineTransform(rect, CGContextGetCTM(context))); - - CFRelease(urlRef); - } -} - -void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode) -{ - if (paintingDisabled()) - return; - - CGInterpolationQuality quality = kCGInterpolationDefault; - switch (mode) { - case InterpolationDefault: - quality = kCGInterpolationDefault; - break; - case InterpolationNone: - quality = kCGInterpolationNone; - break; - case InterpolationLow: - quality = kCGInterpolationLow; - break; - - // Fall through to InterpolationHigh if kCGInterpolationMedium is not available - case InterpolationMedium: -#if HAVE(CG_INTERPOLATION_MEDIUM) - quality = kCGInterpolationMedium; - break; -#endif - case InterpolationHigh: - quality = kCGInterpolationHigh; - break; - } - CGContextSetInterpolationQuality(platformContext(), quality); -} - -InterpolationQuality GraphicsContext::imageInterpolationQuality() const -{ - if (paintingDisabled()) - return InterpolationDefault; - - CGInterpolationQuality quality = CGContextGetInterpolationQuality(platformContext()); - switch (quality) { - case kCGInterpolationDefault: - return InterpolationDefault; - case kCGInterpolationNone: - return InterpolationNone; - case kCGInterpolationLow: - return InterpolationLow; -#if HAVE(CG_INTERPOLATION_MEDIUM) - case kCGInterpolationMedium: - return InterpolationMedium; -#endif - case kCGInterpolationHigh: - return InterpolationHigh; - } - return InterpolationDefault; -} - -void GraphicsContext::setPlatformTextDrawingMode(int mode) -{ - if (paintingDisabled()) - return; - - // Wow, wish CG had used bits here. - CGContextRef context = platformContext(); - switch (mode) { - case cTextInvisible: // Invisible - CGContextSetTextDrawingMode(context, kCGTextInvisible); - break; - case cTextFill: // Fill - CGContextSetTextDrawingMode(context, kCGTextFill); - break; - case cTextStroke: // Stroke - CGContextSetTextDrawingMode(context, kCGTextStroke); - break; - case 3: // Fill | Stroke - CGContextSetTextDrawingMode(context, kCGTextFillStroke); - break; - case cTextClip: // Clip - CGContextSetTextDrawingMode(context, kCGTextClip); - break; - case 5: // Fill | Clip - CGContextSetTextDrawingMode(context, kCGTextFillClip); - break; - case 6: // Stroke | Clip - CGContextSetTextDrawingMode(context, kCGTextStrokeClip); - break; - case 7: // Fill | Stroke | Clip - CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip); - break; - default: - break; - } -} - -void GraphicsContext::setPlatformStrokeColor(const Color& color) -{ - if (paintingDisabled()) - return; - setCGStrokeColor(platformContext(), color); -} - -void GraphicsContext::setPlatformStrokeThickness(float thickness) -{ - if (paintingDisabled()) - return; - CGContextSetLineWidth(platformContext(), thickness); -} - -void GraphicsContext::setPlatformFillColor(const Color& color) -{ - if (paintingDisabled()) - return; - setCGFillColor(platformContext(), color); -} - -void GraphicsContext::setUseAntialiasing(bool enable) -{ - if (paintingDisabled()) - return; - CGContextSetShouldAntialias(platformContext(), enable); -} - -#ifndef BUILDING_ON_TIGER // Tiger's setCompositeOperation() is defined in GraphicsContextMac.mm. -void GraphicsContext::setCompositeOperation(CompositeOperator mode) -{ - if (paintingDisabled()) - return; - - CGBlendMode target = kCGBlendModeNormal; - switch (mode) { - case CompositeClear: - target = kCGBlendModeClear; - break; - case CompositeCopy: - target = kCGBlendModeCopy; - break; - case CompositeSourceOver: - //kCGBlendModeNormal - break; - case CompositeSourceIn: - target = kCGBlendModeSourceIn; - break; - case CompositeSourceOut: - target = kCGBlendModeSourceOut; - break; - case CompositeSourceAtop: - target = kCGBlendModeSourceAtop; - break; - case CompositeDestinationOver: - target = kCGBlendModeDestinationOver; - break; - case CompositeDestinationIn: - target = kCGBlendModeDestinationIn; - break; - case CompositeDestinationOut: - target = kCGBlendModeDestinationOut; - break; - case CompositeDestinationAtop: - target = kCGBlendModeDestinationAtop; - break; - case CompositeXOR: - target = kCGBlendModeXOR; - break; - case CompositePlusDarker: - target = kCGBlendModePlusDarker; - break; - case CompositeHighlight: - // currently unsupported - break; - case CompositePlusLighter: - target = kCGBlendModePlusLighter; - break; - } - CGContextSetBlendMode(platformContext(), target); -} -#endif - -} - diff --git a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h deleted file mode 100644 index 8827ff7..0000000 --- a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2006, 2007 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 COMPUTER, 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 COMPUTER, 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 <CoreGraphics/CGContext.h> - -namespace WebCore { - -class GraphicsContextPlatformPrivate { -public: - GraphicsContextPlatformPrivate(CGContextRef cgContext) - : m_cgContext(cgContext) -#if PLATFORM(WIN) - , m_hdc(0) - , m_transparencyCount(0) -#endif - , m_userToDeviceTransformKnownToBeIdentity(false) - { - CGContextRetain(m_cgContext); - } - - ~GraphicsContextPlatformPrivate() - { - CGContextRelease(m_cgContext); - } - -#if PLATFORM(MAC) || PLATFORM(CHROMIUM) - // These methods do nothing on Mac. - void save() {} - void restore() {} - void clip(const FloatRect&) {} - void clip(const Path&) {} - void scale(const FloatSize&) {} - void rotate(float) {} - void translate(float, float) {} - void concatCTM(const AffineTransform&) {} - void beginTransparencyLayer() {} - void endTransparencyLayer() {} -#endif - -#if PLATFORM(WIN) - // On Windows, we need to update the HDC for form controls to draw in the right place. - void save(); - void restore(); - void clip(const FloatRect&); - void clip(const Path&); - void scale(const FloatSize&); - void rotate(float); - void translate(float, float); - void concatCTM(const AffineTransform&); - void beginTransparencyLayer() { m_transparencyCount++; } - void endTransparencyLayer() { m_transparencyCount--; } - - HDC m_hdc; - unsigned m_transparencyCount; -#endif - - CGContextRef m_cgContext; - bool m_userToDeviceTransformKnownToBeIdentity; -}; - -} diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp deleted file mode 100644 index 502313b..0000000 --- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - * 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 COMPUTER, 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 COMPUTER, 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 "ImageBuffer.h" - -#include "Base64.h" -#include "BitmapImage.h" -#include "CString.h" -#include "GraphicsContext.h" -#include "ImageData.h" -#include "MIMETypeRegistry.h" -#include "PlatformString.h" -#include <ApplicationServices/ApplicationServices.h> -#include <wtf/Assertions.h> -#include <wtf/OwnArrayPtr.h> -#include <wtf/RetainPtr.h> - -using namespace std; - -namespace WebCore { - -ImageBufferData::ImageBufferData(const IntSize&) - : m_data(0) -{ -} - -ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success) - : m_data(size) - , m_size(size) -{ - success = false; // Make early return mean failure. - unsigned bytesPerRow; - if (size.width() < 0 || size.height() < 0) - return; - bytesPerRow = size.width(); - if (!grayScale) { - // Protect against overflow - if (bytesPerRow > 0x3FFFFFFF) - return; - bytesPerRow *= 4; - } - - m_data.m_data = tryFastCalloc(size.height(), bytesPerRow); - ASSERT((reinterpret_cast<size_t>(m_data.m_data) & 2) == 0); - - CGColorSpaceRef colorSpace = grayScale ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB(); - CGContextRef cgContext = CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow, - colorSpace, grayScale ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast); - CGColorSpaceRelease(colorSpace); - if (!cgContext) - return; - - m_context.set(new GraphicsContext(cgContext)); - m_context->scale(FloatSize(1, -1)); - m_context->translate(0, -size.height()); - CGContextRelease(cgContext); - success = true; -} - -ImageBuffer::~ImageBuffer() -{ - fastFree(m_data.m_data); -} - -GraphicsContext* ImageBuffer::context() const -{ - return m_context.get(); -} - -Image* ImageBuffer::image() const -{ - 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 m_image.get(); -} - -PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const -{ - PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); - 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()); - - int originx = rect.x(); - int destx = 0; - if (originx < 0) { - destx = -originx; - originx = 0; - } - int endx = rect.x() + rect.width(); - if (endx > m_size.width()) - endx = m_size.width(); - int numColumns = endx - originx; - - int originy = rect.y(); - int desty = 0; - if (originy < 0) { - desty = -originy; - originy = 0; - } - int endy = rect.y() + rect.height(); - if (endy > m_size.height()) - endy = m_size.height(); - int numRows = endy - originy; - - unsigned srcBytesPerRow = 4 * m_size.width(); - unsigned destBytesPerRow = 4 * rect.width(); - - // ::create ensures that all ImageBuffers have valid data, so we don't need to check it here. - unsigned char* srcRows = reinterpret_cast<unsigned char*>(m_data.m_data) + originy * srcBytesPerRow + originx * 4; - unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; - for (int y = 0; y < numRows; ++y) { - for (int x = 0; x < numColumns; x++) { - int basex = x * 4; - if (unsigned char alpha = srcRows[basex + 3]) { - destRows[basex] = (srcRows[basex] * 255) / alpha; - destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha; - destRows[basex + 2] = (srcRows[basex + 2] * 255) / alpha; - destRows[basex + 3] = alpha; - } else - reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<uint32_t*>(srcRows + basex)[0]; - } - srcRows += srcBytesPerRow; - destRows += destBytesPerRow; - } - return result; -} - -void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) -{ - ASSERT(sourceRect.width() > 0); - ASSERT(sourceRect.height() > 0); - - int originx = sourceRect.x(); - int destx = destPoint.x() + sourceRect.x(); - ASSERT(destx >= 0); - ASSERT(destx < m_size.width()); - ASSERT(originx >= 0); - ASSERT(originx <= sourceRect.right()); - - int endx = destPoint.x() + sourceRect.right(); - ASSERT(endx <= m_size.width()); - - int numColumns = endx - destx; - - int originy = sourceRect.y(); - int desty = destPoint.y() + sourceRect.y(); - ASSERT(desty >= 0); - ASSERT(desty < m_size.height()); - ASSERT(originy >= 0); - ASSERT(originy <= sourceRect.bottom()); - - int endy = destPoint.y() + sourceRect.bottom(); - ASSERT(endy <= m_size.height()); - int numRows = endy - desty; - - unsigned srcBytesPerRow = 4 * source->width(); - unsigned destBytesPerRow = 4 * m_size.width(); - - 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++) { - int basex = x * 4; - unsigned char alpha = srcRows[basex + 3]; - if (alpha != 255) { - destRows[basex] = (srcRows[basex] * alpha + 254) / 255; - destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255; - destRows[basex + 2] = (srcRows[basex + 2] * alpha + 254) / 255; - destRows[basex + 3] = alpha; - } else - reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<uint32_t*>(srcRows + basex)[0]; - } - destRows += destBytesPerRow; - srcRows += srcBytesPerRow; - } -} - -static RetainPtr<CFStringRef> utiFromMIMEType(const String& mimeType) -{ -#if PLATFORM(MAC) - RetainPtr<CFStringRef> mimeTypeCFString(AdoptCF, mimeType.createCFString()); - return RetainPtr<CFStringRef>(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeTypeCFString.get(), 0)); -#else - // FIXME: Add Windows support for all the supported UTIs when a way to convert from MIMEType to UTI reliably is found. - // For now, only support PNG, JPEG, and GIF. See <rdar://problem/6095286>. - static const CFStringRef kUTTypePNG = CFSTR("public.png"); - static const CFStringRef kUTTypeJPEG = CFSTR("public.jpeg"); - static const CFStringRef kUTTypeGIF = CFSTR("com.compuserve.gif"); - - if (equalIgnoringCase(mimeType, "image/png")) - return kUTTypePNG; - if (equalIgnoringCase(mimeType, "image/jpeg")) - return kUTTypeJPEG; - if (equalIgnoringCase(mimeType, "image/gif")) - return kUTTypeGIF; - - ASSERT_NOT_REACHED(); - return kUTTypePNG; -#endif -} - -String ImageBuffer::toDataURL(const String& mimeType) const -{ - ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); - - RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(context()->platformContext())); - if (!image) - return "data:,"; - - size_t width = CGImageGetWidth(image.get()); - size_t height = CGImageGetHeight(image.get()); - - OwnArrayPtr<uint32_t> imageData(new uint32_t[width * height]); - if (!imageData) - return "data:,"; - - RetainPtr<CGImageRef> transformedImage(AdoptCF, CGBitmapContextCreateImage(context()->platformContext())); - if (!transformedImage) - return "data:,"; - - RetainPtr<CFMutableDataRef> transformedImageData(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0)); - if (!transformedImageData) - return "data:,"; - - RetainPtr<CGImageDestinationRef> imageDestination(AdoptCF, CGImageDestinationCreateWithData(transformedImageData.get(), - utiFromMIMEType(mimeType).get(), 1, 0)); - if (!imageDestination) - return "data:,"; - - CGImageDestinationAddImage(imageDestination.get(), transformedImage.get(), 0); - CGImageDestinationFinalize(imageDestination.get()); - - Vector<char> in; - in.append(CFDataGetBytePtr(transformedImageData.get()), CFDataGetLength(transformedImageData.get())); - - Vector<char> out; - base64Encode(in, out); - out.append('\0'); - - return String::format("data:%s;base64,%s", mimeType.utf8().data(), out.data()); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/cg/ImageBufferData.h b/WebCore/platform/graphics/cg/ImageBufferData.h deleted file mode 100644 index 5e6fc4c..0000000 --- a/WebCore/platform/graphics/cg/ImageBufferData.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 Google 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 COMPUTER, 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 COMPUTER, 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 ImageBufferData_h -#define ImageBufferData_h - -namespace WebCore { - -class IntSize; - -class ImageBufferData { -public: - ImageBufferData(const IntSize&); - - void* m_data; -}; - -} // namespace WebCore - -#endif // ImageBufferData_h diff --git a/WebCore/platform/graphics/cg/ImageCG.cpp b/WebCore/platform/graphics/cg/ImageCG.cpp deleted file mode 100644 index 8609c46..0000000 --- a/WebCore/platform/graphics/cg/ImageCG.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 "BitmapImage.h" - -#if PLATFORM(CG) - -#include "AffineTransform.h" -#include "FloatConversion.h" -#include "FloatRect.h" -#include "GraphicsContext.h" -#include "ImageObserver.h" -#include "PDFDocumentImage.h" -#include "PlatformString.h" -#include <ApplicationServices/ApplicationServices.h> - -#if PLATFORM(MAC) || PLATFORM(CHROMIUM) -#include "WebCoreSystemInterface.h" -#endif - -#if PLATFORM(WIN) -#include <WebKitSystemInterface/WebKitSystemInterface.h> -#endif - -namespace WebCore { - -void FrameData::clear() -{ - 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. - } -} - -// ================================================ -// Image Class -// ================================================ - -BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer) - : Image(observer) - , m_currentFrame(0) - , m_frames(0) - , m_frameTimer(0) - , m_repetitionCount(cAnimationNone) - , m_repetitionCountStatus(Unknown) - , m_repetitionsComplete(0) - , m_isSolidColor(false) - , m_animationFinished(true) - , m_allDataReceived(true) - , m_haveSize(true) - , m_sizeAvailable(true) - , m_decodedSize(0) - , m_haveFrameCount(true) - , m_frameCount(1) -{ - initPlatformData(); - - CGFloat width = CGImageGetWidth(cgImage); - CGFloat height = CGImageGetHeight(cgImage); - m_decodedSize = width * height * 4; - m_size = IntSize(width, height); - - m_frames.grow(1); - m_frames[0].m_frame = cgImage; - m_frames[0].m_hasAlpha = true; - m_frames[0].m_haveMetadata = true; - checkForSolidColor(); -} - -// Drawing Routines - -void BitmapImage::checkForSolidColor() -{ - if (frameCount() > 1) - m_isSolidColor = false; - else { - CGImageRef image = frameAtIndex(0); - - // Currently we only check for solid color in the important special case of a 1x1 image. - if (image && CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) { - unsigned char pixel[4]; // RGBA - CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); - CGContextRef bmap = CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), space, - kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); - if (bmap) { - GraphicsContext(bmap).setCompositeOperation(CompositeCopy); - CGRect dst = { {0, 0}, {1, 1} }; - CGContextDrawImage(bmap, dst, image); - if (pixel[3] == 0) - m_solidColor = Color(0, 0, 0, 0); - else - m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]); - m_isSolidColor = true; - CFRelease(bmap); - } - CFRelease(space); - } - } -} - -CGImageRef BitmapImage::getCGImageRef() -{ - return frameAtIndex(0); -} - -void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp) -{ - startAnimation(); - - CGImageRef image = frameAtIndex(m_currentFrame); - if (!image) // If it's too early we won't have an image yet. - return; - - if (mayFillWithSolidColor()) { - fillWithSolidColor(ctxt, destRect, solidColor(), compositeOp); - return; - } - - float currHeight = CGImageGetHeight(image); - if (currHeight <= srcRect.y()) - return; - - CGContextRef context = ctxt->platformContext(); - ctxt->save(); - - bool shouldUseSubimage = false; - - // If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image - // and then set a clip to the portion that we want to display. - FloatRect adjustedDestRect = destRect; - FloatSize selfSize = currentFrameSize(); - if (srcRect.size() != selfSize) { - CGInterpolationQuality interpolationQuality = CGContextGetInterpolationQuality(context); - // When the image is scaled using high-quality interpolation, we create a temporary CGImage - // containing only the portion we want to display. We need to do this because high-quality - // 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(); - if (shouldUseSubimage) { - image = CGImageCreateWithImageInRect(image, srcRect); - if (currHeight < srcRect.bottom()) { - ASSERT(CGImageGetHeight(image) == currHeight - CGRectIntegral(srcRect).origin.y); - adjustedDestRect.setHeight(destRect.height() / srcRect.height() * CGImageGetHeight(image)); - } - } 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); - } - } - - // 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()); - CGContextScaleCTM(context, 1, -1); - adjustedDestRect.setLocation(FloatPoint()); - - // Draw the image. - CGContextDrawImage(context, adjustedDestRect, image); - - if (shouldUseSubimage) - CGImageRelease(image); - - ctxt->restore(); - - if (imageObserver()) - imageObserver()->didDraw(this); -} - -void Image::drawPatternCallback(void* info, CGContextRef context) -{ - CGImageRef image = (CGImageRef)info; - CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect(0, 0, CGImageGetWidth(image), CGImageGetHeight(image))), image); -} - -void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, - const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) -{ - if (!nativeImageForCurrentFrame()) - return; - - ASSERT(patternTransform.isInvertible()); - if (!patternTransform.isInvertible()) - // Avoid a hang under CGContextDrawTiledImage on release builds. - return; - - CGContextRef context = ctxt->platformContext(); - ctxt->save(); - CGContextClipToRect(context, destRect); - ctxt->setCompositeOperation(op); - CGContextTranslateCTM(context, destRect.x(), destRect.y() + destRect.height()); - CGContextScaleCTM(context, 1, -1); - - // Compute the scaled tile size. - float scaledTileHeight = tileRect.height() * narrowPrecisionToFloat(patternTransform.d()); - - // We have to adjust the phase to deal with the fact we're in Cartesian space now (with the bottom left corner of destRect being - // the origin). - float adjustedX = phase.x() - destRect.x() + tileRect.x() * narrowPrecisionToFloat(patternTransform.a()); // We translated the context so that destRect.x() is the origin, so subtract it out. - float adjustedY = destRect.height() - (phase.y() - destRect.y() + tileRect.y() * narrowPrecisionToFloat(patternTransform.d()) + scaledTileHeight); - - CGImageRef tileImage = nativeImageForCurrentFrame(); - float h = CGImageGetHeight(tileImage); - - CGImageRef subImage; - if (tileRect.size() == size()) - subImage = tileImage; - else { - // Copying a sub-image out of a partially-decoded image stops the decoding of the original image. It should never happen - // because sub-images are only used for border-image, which only renders when the image is fully decoded. - ASSERT(h == height()); - subImage = CGImageCreateWithImageInRect(tileImage, tileRect); - } - -#ifndef BUILDING_ON_TIGER - // Leopard has an optimized call for the tiling of image patterns, but we can only use it if the image has been decoded enough that - // 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. - float scaledTileWidth = tileRect.width() * narrowPrecisionToFloat(patternTransform.a()); - float w = CGImageGetWidth(tileImage); - if (w == size().width() && h == size().height()) - CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage); - else { -#endif - - // On Leopard, this code now only runs for partially decoded images whose buffers do not yet match the overall size of the image. - // On Tiger this code runs all the time. This code is suboptimal because the pattern does not reference the image directly, and the - // pattern is destroyed before exiting the function. This means any decoding the pattern does doesn't end up cached anywhere, so we - // redecode every time we paint. - static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, NULL }; - CGAffineTransform matrix = CGAffineTransformMake(narrowPrecisionToCGFloat(patternTransform.a()), 0, 0, narrowPrecisionToCGFloat(patternTransform.d()), adjustedX, adjustedY); - matrix = CGAffineTransformConcat(matrix, CGContextGetCTM(context)); - // The top of a partially-decoded image is drawn at the bottom of the tile. Map it to the top. - matrix = CGAffineTransformTranslate(matrix, 0, size().height() - h); - CGPatternRef pattern = CGPatternCreate(subImage, CGRectMake(0, 0, tileRect.width(), tileRect.height()), - matrix, tileRect.width(), tileRect.height(), - kCGPatternTilingConstantSpacing, true, &patternCallbacks); - if (pattern == NULL) { - if (subImage != tileImage) - CGImageRelease(subImage); - ctxt->restore(); - return; - } - - CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL); - - CGFloat alpha = 1; - CGColorRef color = CGColorCreateWithPattern(patternSpace, pattern, &alpha); - CGContextSetFillColorSpace(context, patternSpace); - CGColorSpaceRelease(patternSpace); - CGPatternRelease(pattern); - - // FIXME: Really want a public API for this. It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy). - wkSetPatternBaseCTM(context, CGAffineTransformIdentity); - CGContextSetPatternPhase(context, CGSizeZero); - - CGContextSetFillColorWithColor(context, color); - CGContextFillRect(context, CGContextGetClipBoundingBox(context)); - - CGColorRelease(color); - -#ifndef BUILDING_ON_TIGER - } -#endif - - if (subImage != tileImage) - CGImageRelease(subImage); - ctxt->restore(); - - if (imageObserver()) - imageObserver()->didDraw(this); -} - - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp deleted file mode 100644 index 73907c9..0000000 --- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 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 COMPUTER, 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 COMPUTER, 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 "ImageSource.h" - -#if PLATFORM(CG) - -#include "IntSize.h" -#include "SharedBuffer.h" -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -static const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32"); - -ImageSource::ImageSource() - : m_decoder(0) -{ -} - -ImageSource::~ImageSource() -{ - clear(); -} - -void ImageSource::clear() -{ - if (m_decoder) { - CFRelease(m_decoder); - m_decoder = 0; - } -} - -CFDictionaryRef imageSourceOptions() -{ - static CFDictionaryRef options; - - if (!options) { - const void* keys[2] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32 }; - const void* values[2] = { kCFBooleanTrue, kCFBooleanTrue }; - options = CFDictionaryCreate(NULL, keys, values, 2, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - } - return options; -} - -bool ImageSource::initialized() const -{ - return m_decoder; -} - -void ImageSource::setData(SharedBuffer* data, bool allDataReceived) -{ - if (!m_decoder) - m_decoder = CGImageSourceCreateIncremental(NULL); -#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 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); -#endif - CGImageSourceUpdateData(m_decoder, cfData, allDataReceived); - CFRelease(cfData); -} - -bool ImageSource::isSizeAvailable() -{ - bool result = false; - CGImageSourceStatus imageSourceStatus = CGImageSourceGetStatus(m_decoder); - - // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus! - if (imageSourceStatus >= kCGImageStatusIncomplete) { - CFDictionaryRef image0Properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions()); - if (image0Properties) { - CFNumberRef widthNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties, kCGImagePropertyPixelWidth); - CFNumberRef heightNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties, kCGImagePropertyPixelHeight); - result = widthNumber && heightNumber; - CFRelease(image0Properties); - } - } - - return result; -} - -IntSize ImageSource::frameSizeAtIndex(size_t index) const -{ - IntSize result; - CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions()); - if (properties) { - int w = 0, h = 0; - CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth); - if (num) - CFNumberGetValue(num, kCFNumberIntType, &w); - num = (CFNumberRef)CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight); - if (num) - CFNumberGetValue(num, kCFNumberIntType, &h); - result = IntSize(w, h); - CFRelease(properties); - } - return result; -} - -IntSize ImageSource::size() const -{ - return frameSizeAtIndex(0); -} - -int ImageSource::repetitionCount() -{ - int result = cAnimationLoopOnce; // No property means loop once. - if (!initialized()) - return result; - - // A property with value 0 means loop forever. - CFDictionaryRef properties = CGImageSourceCopyProperties(m_decoder, imageSourceOptions()); - if (properties) { - CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary); - if (gifProperties) { - CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFLoopCount); - if (num) - CFNumberGetValue(num, kCFNumberIntType, &result); - } else - result = cAnimationNone; // Turns out we're not a GIF after all, so we don't animate. - - CFRelease(properties); - } - - return result; -} - -size_t ImageSource::frameCount() const -{ - return m_decoder ? CGImageSourceGetCount(m_decoder) : 0; -} - -CGImageRef ImageSource::createFrameAtIndex(size_t index) -{ - if (!initialized()) - return 0; - - CGImageRef image = CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions()); - CFStringRef imageUTI = CGImageSourceGetType(m_decoder); - static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image"); - if (!imageUTI || !CFEqual(imageUTI, xbmUTI)) - return image; - - // If it is an xbm image, mask out all the white areas to render them transparent. - const CGFloat maskingColors[6] = {255, 255, 255, 255, 255, 255}; - CGImageRef maskedImage = CGImageCreateWithMaskingColors(image, maskingColors); - if (!maskedImage) - return image; - - CGImageRelease(image); - return maskedImage; -} - -bool ImageSource::frameIsCompleteAtIndex(size_t index) -{ - return CGImageSourceGetStatusAtIndex(m_decoder, index) == kCGImageStatusComplete; -} - -float ImageSource::frameDurationAtIndex(size_t index) -{ - if (!initialized()) - return 0; - - float duration = 0; - CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions()); - if (properties) { - CFDictionaryRef typeProperties = (CFDictionaryRef)CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary); - if (typeProperties) { - CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, kCGImagePropertyGIFDelayTime); - if (num) - CFNumberGetValue(num, kCFNumberFloatType, &duration); - } - CFRelease(properties); - } - - // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. - // We follow WinIE's behavior and use a duration of 100 ms for any frames that specify - // a duration of <= 50 ms. See <http://bugs.webkit.org/show_bug.cgi?id=14413> or Radar 4051389 for more. - if (duration < 0.051f) - return 0.100f; - return duration; -} - -bool ImageSource::frameHasAlphaAtIndex(size_t index) -{ - // 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. - // FIXME: Could return false for JPEG and other non-transparent image formats. - // FIXME: Could maybe return false for a GIF Frame if we have enough info in the GIF properties dictionary - // to determine whether or not a transparent color was defined. - return true; -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/IntPointCG.cpp b/WebCore/platform/graphics/cg/IntPointCG.cpp deleted file mode 100644 index 95dbe5f..0000000 --- a/WebCore/platform/graphics/cg/IntPointCG.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 "IntPoint.h" - -#if PLATFORM(CG) - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -IntPoint::IntPoint(const CGPoint& p) : m_x(static_cast<int>(p.x)), m_y(static_cast<int>(p.y)) -{ -} - -IntPoint::operator CGPoint() const -{ - return CGPointMake(m_x, m_y); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/IntRectCG.cpp b/WebCore/platform/graphics/cg/IntRectCG.cpp deleted file mode 100644 index 73fd63f..0000000 --- a/WebCore/platform/graphics/cg/IntRectCG.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 "IntRect.h" - -#if PLATFORM(CG) - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -IntRect::operator CGRect() const -{ - return CGRectMake(x(), y(), width(), height()); -} - -IntRect enclosingIntRect(const CGRect& rect) -{ - int l = static_cast<int>(floorf(rect.origin.x)); - int t = static_cast<int>(floorf(rect.origin.y)); - int r = static_cast<int>(ceilf(CGRectGetMaxX(rect))); - int b = static_cast<int>(ceilf(CGRectGetMaxY(rect))); - return IntRect(l, t, r - l, b - t); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/IntSizeCG.cpp b/WebCore/platform/graphics/cg/IntSizeCG.cpp deleted file mode 100644 index d8e8c83..0000000 --- a/WebCore/platform/graphics/cg/IntSizeCG.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 "IntSize.h" - -#if PLATFORM(CG) - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -IntSize::IntSize(const CGSize& s) : m_width(static_cast<int>(s.width)), m_height(static_cast<int>(s.height)) -{ -} - -IntSize::operator CGSize() const -{ - return CGSizeMake(m_width, m_height); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/PDFDocumentImage.cpp b/WebCore/platform/graphics/cg/PDFDocumentImage.cpp deleted file mode 100644 index 2578f08..0000000 --- a/WebCore/platform/graphics/cg/PDFDocumentImage.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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. - */ - -#define _USE_MATH_DEFINES 1 -#include "config.h" -#include "PDFDocumentImage.h" - -#if PLATFORM(CG) - -#include "GraphicsContext.h" -#include "ImageObserver.h" -#include <wtf/MathExtras.h> - -using namespace std; - -namespace WebCore { - -PDFDocumentImage::PDFDocumentImage() - : Image(0) // PDFs don't animate - , m_document(0) - , m_rotation(0.0f) - , m_currentPage(-1) -{ -} - -PDFDocumentImage::~PDFDocumentImage() -{ - CGPDFDocumentRelease(m_document); -} - -IntSize PDFDocumentImage::size() const -{ - const float sina = sinf(-m_rotation); - const float cosa = cosf(-m_rotation); - const float width = m_mediaBox.size().width(); - const float height = m_mediaBox.size().height(); - const float rotWidth = width * cosa - height * sina; - const float rotHeight = width * sina + height * cosa; - - return IntSize((int)(fabsf(rotWidth) + 0.5f), (int)(fabsf(rotHeight) + 0.5f)); -} - -bool PDFDocumentImage::dataChanged(bool allDataReceived) -{ - if (allDataReceived && !m_document) { -#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(); -#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); -#endif - CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(data); - CFRelease(data); - m_document = CGPDFDocumentCreateWithProvider(dataProvider); - CGDataProviderRelease(dataProvider); - setCurrentPage(0); - } - return m_document; // return true if size is available -} - -void PDFDocumentImage::adjustCTM(GraphicsContext* context) const -{ - // rotate the crop box and calculate bounding box - float sina = sinf(-m_rotation); - float cosa = cosf(-m_rotation); - float width = m_cropBox.width(); - float height = m_cropBox.height(); - - // calculate rotated x and y edges of the corp box. if they're negative, it means part of the image has - // been rotated outside of the bounds and we need to shift over the image so it lies inside the bounds again - CGPoint rx = CGPointMake(width * cosa, width * sina); - CGPoint ry = CGPointMake(-height * sina, height * cosa); - - // adjust so we are at the crop box origin - const CGFloat zero = 0; - CGContextTranslateCTM(context->platformContext(), floorf(-min(zero, min(rx.x, ry.x))), floorf(-min(zero, min(rx.y, ry.y)))); - - // rotate -ve to remove rotation - CGContextRotateCTM(context->platformContext(), -m_rotation); - - // shift so we are completely within media box - CGContextTranslateCTM(context->platformContext(), m_mediaBox.x() - m_cropBox.x(), m_mediaBox.y() - m_cropBox.y()); -} - -void PDFDocumentImage::setCurrentPage(int page) -{ - if (!m_document) - return; - - if (page == m_currentPage) - return; - - if (!(page >= 0 && page < pageCount())) - return; - - m_currentPage = page; - - CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document, page + 1); - - // get media box (guaranteed) - m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox); - - // get crop box (not always there). if not, use media box - CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox); - if (!CGRectIsEmpty(r)) - m_cropBox = r; - else - m_cropBox = m_mediaBox; - - // get page rotation angle - m_rotation = CGPDFPageGetRotationAngle(cgPage) * piFloat / 180.0f; // to radians -} - -int PDFDocumentImage::pageCount() const -{ - return m_document ? CGPDFDocumentGetNumberOfPages(m_document) : 0; -} - -void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator op) -{ - if (!m_document || m_currentPage == -1) - return; - - context->save(); - - context->setCompositeOperation(op); - - float hScale = dstRect.width() / srcRect.width(); - float vScale = dstRect.height() / srcRect.height(); - - // Scale and translate so the document is rendered in the correct location, - // including accounting for the fact that a GraphicsContext is always flipped - // and doing appropriate flipping. - CGContextTranslateCTM(context->platformContext(), dstRect.x() - srcRect.x() * hScale, dstRect.y() - srcRect.y() * vScale); - CGContextScaleCTM(context->platformContext(), hScale, vScale); - CGContextScaleCTM(context->platformContext(), 1, -1); - CGContextTranslateCTM(context->platformContext(), 0, -srcRect.height()); - CGContextClipToRect(context->platformContext(), CGRectIntegral(srcRect)); - - // Rotate translate image into position according to doc properties. - adjustCTM(context); - - CGContextTranslateCTM(context->platformContext(), -m_mediaBox.x(), -m_mediaBox.y()); - CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document, m_currentPage + 1)); - - context->restore(); - - if (imageObserver()) - imageObserver()->didDraw(this); -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/PDFDocumentImage.h b/WebCore/platform/graphics/cg/PDFDocumentImage.h deleted file mode 100644 index 5c9d4e1..0000000 --- a/WebCore/platform/graphics/cg/PDFDocumentImage.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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 "Image.h" - -#include "FloatRect.h" -#include "GraphicsTypes.h" - -#if PLATFORM(CG) - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - - class GraphicsContext; - - class PDFDocumentImage : public Image { - public: - static PassRefPtr<PDFDocumentImage> create() - { - return adoptRef(new PDFDocumentImage); - } - ~PDFDocumentImage(); - - virtual bool hasSingleSecurityOrigin() const { return true; } - - virtual bool dataChanged(bool allDataReceived); - - // 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 unsigned decodedSize() const { return 0; } - - virtual IntSize size() const; - - private: - PDFDocumentImage(); - virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator); - - void setCurrentPage(int); - int pageCount() const; - void adjustCTM(GraphicsContext*) const; - - CGPDFDocumentRef m_document; - FloatRect m_mediaBox; - FloatRect m_cropBox; - float m_rotation; - int m_currentPage; - }; - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/PathCG.cpp b/WebCore/platform/graphics/cg/PathCG.cpp deleted file mode 100644 index 1382589..0000000 --- a/WebCore/platform/graphics/cg/PathCG.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. - * 2006, 2008 Rob Buis <buis@kde.org> - * - * 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 COMPUTER, 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 COMPUTER, 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 "Path.h" - -#if PLATFORM(CG) - -#include "AffineTransform.h" -#include <ApplicationServices/ApplicationServices.h> -#include "FloatRect.h" -#include "IntRect.h" -#include "PlatformString.h" - -#include <wtf/MathExtras.h> - -namespace WebCore { - -Path::Path() - : m_path(CGPathCreateMutable()) -{ -} - -Path::~Path() -{ - CGPathRelease(m_path); -} - -Path::Path(const Path& other) - : m_path(CGPathCreateMutableCopy(other.m_path)) -{ -} - -Path& Path::operator=(const Path& other) -{ - CGMutablePathRef path = CGPathCreateMutableCopy(other.m_path); - CGPathRelease(m_path); - m_path = path; - return *this; -} - - -static void copyClosingSubpathsApplierFunction(void* info, const CGPathElement* element) -{ - CGMutablePathRef path = static_cast<CGMutablePathRef>(info); - CGPoint* points = element->points; - - switch (element->type) { - case kCGPathElementMoveToPoint: - if (!CGPathIsEmpty(path)) // to silence a warning when trying to close an empty path - CGPathCloseSubpath(path); // This is the only change from CGPathCreateMutableCopy - CGPathMoveToPoint(path, 0, points[0].x, points[0].y); - break; - case kCGPathElementAddLineToPoint: - CGPathAddLineToPoint(path, 0, points[0].x, points[0].y); - break; - case kCGPathElementAddQuadCurveToPoint: - CGPathAddQuadCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y); - break; - case kCGPathElementAddCurveToPoint: - CGPathAddCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y); - break; - case kCGPathElementCloseSubpath: - CGPathCloseSubpath(path); - break; - } -} - -static CGMutablePathRef copyCGPathClosingSubpaths(CGPathRef originalPath) -{ - CGMutablePathRef path = CGPathCreateMutable(); - CGPathApply(originalPath, path, copyClosingSubpathsApplierFunction); - CGPathCloseSubpath(path); - return path; -} - -bool Path::contains(const FloatPoint &point, WindRule rule) const -{ - if (!boundingRect().contains(point)) - return false; - - // CGPathContainsPoint returns false for non-closed paths, as a work-around, we copy and close the path first. Radar 4758998 asks for a better CG API to use - CGMutablePathRef path = copyCGPathClosingSubpaths(m_path); - bool ret = CGPathContainsPoint(path, 0, point, rule == RULE_EVENODD ? true : false); - CGPathRelease(path); - return ret; -} - -void Path::translate(const FloatSize& size) -{ - CGAffineTransform translation = CGAffineTransformMake(1, 0, 0, 1, size.width(), size.height()); - CGMutablePathRef newPath = CGPathCreateMutable(); - CGPathAddPath(newPath, &translation, m_path); - CGPathRelease(m_path); - m_path = newPath; -} - -FloatRect Path::boundingRect() const -{ - return CGPathGetBoundingBox(m_path); -} - -void Path::moveTo(const FloatPoint& point) -{ - CGPathMoveToPoint(m_path, 0, point.x(), point.y()); -} - -void Path::addLineTo(const FloatPoint& p) -{ - CGPathAddLineToPoint(m_path, 0, p.x(), p.y()); -} - -void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p) -{ - CGPathAddQuadCurveToPoint(m_path, 0, cp.x(), cp.y(), p.x(), p.y()); -} - -void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p) -{ - CGPathAddCurveToPoint(m_path, 0, cp1.x(), cp1.y(), cp2.x(), cp2.y(), p.x(), p.y()); -} - -void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) -{ - CGPathAddArcToPoint(m_path, 0, p1.x(), p1.y(), p2.x(), p2.y(), radius); -} - -void Path::closeSubpath() -{ - if (!CGPathIsEmpty(m_path)) // to silence a warning when trying to close an empty path - CGPathCloseSubpath(m_path); -} - -void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool clockwise) -{ - // Workaround for <rdar://problem/5189233> CGPathAddArc hangs or crashes when passed inf as start or end angle - if (isfinite(sa) && isfinite(ea)) - CGPathAddArc(m_path, 0, p.x(), p.y(), r, sa, ea, clockwise); -} - -void Path::addRect(const FloatRect& r) -{ - CGPathAddRect(m_path, 0, r); -} - -void Path::addEllipse(const FloatRect& r) -{ - CGPathAddEllipseInRect(m_path, 0, r); -} - -void Path::clear() -{ - CGPathRelease(m_path); - m_path = CGPathCreateMutable(); -} - -bool Path::isEmpty() const -{ - return CGPathIsEmpty(m_path); - } - -static void CGPathToCFStringApplierFunction(void* info, const CGPathElement *element) -{ - CFMutableStringRef string = (CFMutableStringRef)info; - CFStringRef typeString = CFSTR(""); - CGPoint* points = element->points; - switch (element->type) { - case kCGPathElementMoveToPoint: - CFStringAppendFormat(string, 0, CFSTR("M%.2f,%.2f "), points[0].x, points[0].y); - break; - case kCGPathElementAddLineToPoint: - CFStringAppendFormat(string, 0, CFSTR("L%.2f,%.2f "), points[0].x, points[0].y); - break; - case kCGPathElementAddQuadCurveToPoint: - CFStringAppendFormat(string, 0, CFSTR("Q%.2f,%.2f,%.2f,%.2f "), - points[0].x, points[0].y, points[1].x, points[1].y); - break; - case kCGPathElementAddCurveToPoint: - CFStringAppendFormat(string, 0, CFSTR("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f "), - points[0].x, points[0].y, points[1].x, points[1].y, - points[2].x, points[2].y); - break; - case kCGPathElementCloseSubpath: - typeString = CFSTR("X"); break; - } -} - -static CFStringRef CFStringFromCGPath(CGPathRef path) -{ - if (!path) - return 0; - - CFMutableStringRef string = CFStringCreateMutable(NULL, 0); - CGPathApply(path, string, CGPathToCFStringApplierFunction); - CFStringTrimWhitespace(string); - - - return string; -} - - -#pragma mark - -#pragma mark Path Management - -String Path::debugString() const -{ - String result; - if (!isEmpty()) { - CFStringRef pathString = CFStringFromCGPath(m_path); - result = String(pathString); - CFRelease(pathString); - } - return result; -} - -struct PathApplierInfo { - void* info; - PathApplierFunction function; -}; - -void CGPathApplierToPathApplier(void *info, const CGPathElement *element) -{ - PathApplierInfo* pinfo = (PathApplierInfo*)info; - FloatPoint points[3]; - PathElement pelement; - pelement.type = (PathElementType)element->type; - pelement.points = points; - CGPoint* cgPoints = element->points; - switch (element->type) { - case kCGPathElementMoveToPoint: - case kCGPathElementAddLineToPoint: - points[0] = cgPoints[0]; - break; - case kCGPathElementAddQuadCurveToPoint: - points[0] = cgPoints[0]; - points[1] = cgPoints[1]; - break; - case kCGPathElementAddCurveToPoint: - points[0] = cgPoints[0]; - points[1] = cgPoints[1]; - points[2] = cgPoints[2]; - break; - case kCGPathElementCloseSubpath: - break; - } - pinfo->function(pinfo->info, &pelement); -} - -void Path::apply(void* info, PathApplierFunction function) const -{ - PathApplierInfo pinfo; - pinfo.info = info; - pinfo.function = function; - CGPathApply(m_path, &pinfo, CGPathApplierToPathApplier); -} - -void Path::transform(const AffineTransform& transform) -{ - CGMutablePathRef path = CGPathCreateMutable(); - CGAffineTransform transformCG = transform; - CGPathAddPath(path, &transformCG, m_path); - CGPathRelease(m_path); - m_path = path; -} - -} - -#endif // PLATFORM(CG) diff --git a/WebCore/platform/graphics/cg/PatternCG.cpp b/WebCore/platform/graphics/cg/PatternCG.cpp deleted file mode 100644 index e1f7a69..0000000 --- a/WebCore/platform/graphics/cg/PatternCG.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2008 Eric Seidel <eric@webkit.org> - * - * 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 COMPUTER, 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 COMPUTER, 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 "Pattern.h" - -#include "AffineTransform.h" -#include "GraphicsContext.h" - -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -static void patternCallback(void* info, CGContextRef context) -{ - CGImageRef platformImage = static_cast<Image*>(info)->getCGImageRef(); - if (!platformImage) - return; - - CGRect rect = GraphicsContext(context).roundToDevicePixels( - FloatRect(0, 0, CGImageGetWidth(platformImage), CGImageGetHeight(platformImage))); - CGContextDrawImage(context, rect, platformImage); -} - -static void patternReleaseCallback(void* info) -{ - static_cast<Image*>(info)->deref(); -} - -CGPatternRef Pattern::createPlatformPattern(const AffineTransform& transform) const -{ - IntRect tileRect = tileImage()->rect(); - - AffineTransform patternTransform = transform; - patternTransform.scale(1, -1); - patternTransform.translate(0, -tileRect.height()); - - // 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); - - // The pattern will release the tile when it's done rendering in patternReleaseCallback - tileImage()->ref(); - - const CGPatternCallbacks patternCallbacks = { 0, patternCallback, patternReleaseCallback }; - return CGPatternCreate(tileImage(), tileRect, patternTransform, xStep, yStep, - kCGPatternTilingConstantSpacing, TRUE, &patternCallbacks); -} - -} |