diff options
Diffstat (limited to 'Source/WebCore/svg/SVGPaint.cpp')
-rw-r--r-- | Source/WebCore/svg/SVGPaint.cpp | 184 |
1 files changed, 120 insertions, 64 deletions
diff --git a/Source/WebCore/svg/SVGPaint.cpp b/Source/WebCore/svg/SVGPaint.cpp index 76c13d5..c9e08db 100644 --- a/Source/WebCore/svg/SVGPaint.cpp +++ b/Source/WebCore/svg/SVGPaint.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,96 +24,152 @@ #if ENABLE(SVG) #include "SVGPaint.h" +#include "SVGException.h" #include "SVGURIReference.h" +#include <wtf/text/StringConcatenate.h> namespace WebCore { -SVGPaint::SVGPaint() - : m_paintType(SVG_PAINTTYPE_UNKNOWN) +static inline SVGColor::SVGColorType colorTypeForPaintType(const SVGPaint::SVGPaintType& paintType) { + switch (paintType) { + case SVGPaint::SVG_PAINTTYPE_NONE: + case SVGPaint::SVG_PAINTTYPE_UNKNOWN: + case SVGPaint::SVG_PAINTTYPE_URI: + case SVGPaint::SVG_PAINTTYPE_URI_NONE: + return SVGColor::SVG_COLORTYPE_UNKNOWN; + case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR: + case SVGPaint::SVG_PAINTTYPE_RGBCOLOR: + return SVGColor::SVG_COLORTYPE_RGBCOLOR; + case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: + case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + return SVGColor::SVG_COLORTYPE_RGBCOLOR_ICCCOLOR; + case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR: + return SVGColor::SVG_COLORTYPE_CURRENTCOLOR; + } + + ASSERT_NOT_REACHED(); + return SVGColor::SVG_COLORTYPE_UNKNOWN; } -SVGPaint::SVGPaint(const String& uri) - : m_paintType(SVG_PAINTTYPE_URI_RGBCOLOR) -{ - setUri(uri); -} - -SVGPaint::SVGPaint(SVGPaintType paintType) - : m_paintType(paintType) -{ -} - -SVGPaint::SVGPaint(SVGPaintType paintType, const String& uri, const String& rgbPaint, const String&) - : SVGColor(rgbPaint) +SVGPaint::SVGPaint(const SVGPaintType& paintType, String uri) + : SVGColor(colorTypeForPaintType(paintType)) , m_paintType(paintType) + , m_uri(uri) { - setUri(uri); -} - -SVGPaint::SVGPaint(const Color& c) - : SVGColor(c) - , m_paintType(SVG_PAINTTYPE_RGBCOLOR) -{ -} - -SVGPaint::SVGPaint(const String& uri, const Color& c) - : SVGColor(c) - , m_paintType(SVG_PAINTTYPE_URI_RGBCOLOR) -{ - setUri(uri); -} - -SVGPaint* SVGPaint::defaultFill() -{ - static SVGPaint* staticDefaultFill = create(Color::black).releaseRef(); - return staticDefaultFill; -} - -SVGPaint* SVGPaint::defaultStroke() -{ - static SVGPaint* staticDefaultStroke = create(SVG_PAINTTYPE_NONE).releaseRef(); - return staticDefaultStroke; -} - -String SVGPaint::uri() const -{ - return m_uri; } void SVGPaint::setUri(const String& uri) { + // Spec: Sets the paintType to SVG_PAINTTYPE_URI_NONE and sets uri to the specified value. m_uri = uri; + m_paintType = SVG_PAINTTYPE_URI_NONE; + setColor(Color()); + setColorType(colorTypeForPaintType(m_paintType)); + setNeedsStyleRecalc(); } -void SVGPaint::setPaint(SVGPaintType paintType, const String& uri, const String& rgbPaint, const String&, ExceptionCode&) +void SVGPaint::setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionCode& ec) { - m_paintType = paintType; - - if (m_paintType == SVG_PAINTTYPE_URI) - setUri(uri); - else if (m_paintType == SVG_PAINTTYPE_RGBCOLOR) - setRGBColor(rgbPaint); + if ((paintType > SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR && paintType < SVG_PAINTTYPE_NONE) || paintType > SVG_PAINTTYPE_URI) { + ec = SVGException::SVG_WRONG_TYPE_ERR; + return; + } + + bool requiresURI = false; + + SVGPaintType type = static_cast<SVGPaintType>(paintType); + switch (type) { + case SVG_PAINTTYPE_UNKNOWN: + // Spec: It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type. + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + case SVG_PAINTTYPE_RGBCOLOR: + case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_NONE: + case SVG_PAINTTYPE_CURRENTCOLOR: + break; + case SVG_PAINTTYPE_URI_NONE: + case SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_URI: + requiresURI = true; + break; + }; + + // Spec: If paintType requires a URI, then uri must be non-null; otherwise, uri must be null. + if (requiresURI && uri.isEmpty()) { + ec = SVGException::SVG_INVALID_VALUE_ERR; + return; + } + + SVGColor::SVGColorType colorType = colorTypeForPaintType(type); + if (colorType == SVGColor::SVG_COLORTYPE_UNKNOWN) { + // The standard setColor() code path used in the else branch + // raises an exception when attempting to switch to an unknown color type. + // Here we explicitely want to reset to Color() and an unknown type, so force it. + setColorType(colorType); + setColor(Color()); + } else { + setColor(colorType, rgbColor, iccColor, ec); + if (ec) + return; + } + + m_paintType = type; + m_uri = requiresURI ? uri : String(); + setNeedsStyleRecalc(); } String SVGPaint::cssText() const { - if (m_paintType == SVG_PAINTTYPE_NONE) + switch (m_paintType) { + case SVG_PAINTTYPE_UNKNOWN: + case SVG_PAINTTYPE_RGBCOLOR: + case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_CURRENTCOLOR: + return SVGColor::cssText(); + case SVG_PAINTTYPE_NONE: return "none"; - if (m_paintType == SVG_PAINTTYPE_CURRENTCOLOR) - return "currentColor"; - if (m_paintType == SVG_PAINTTYPE_URI) - return "url(" + m_uri + ")"; - - return SVGColor::cssText(); + case SVG_PAINTTYPE_URI_NONE: + return makeString(m_uri, " none"); + case SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: { + String color = SVGColor::cssText(); + if (color.isEmpty()) + return m_uri; + return makeString(m_uri, ' ', color); + } + case SVG_PAINTTYPE_URI: + return m_uri; + }; + + ASSERT_NOT_REACHED(); + return String(); } bool SVGPaint::matchesTargetURI(const String& referenceId) { - if (m_paintType != SVG_PAINTTYPE_URI && m_paintType != SVG_PAINTTYPE_URI_RGBCOLOR) + switch (m_paintType) { + case SVG_PAINTTYPE_UNKNOWN: + case SVG_PAINTTYPE_RGBCOLOR: + case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_CURRENTCOLOR: + case SVG_PAINTTYPE_NONE: return false; - - return referenceId == SVGURIReference::getTarget(m_uri); + case SVG_PAINTTYPE_URI_NONE: + case SVG_PAINTTYPE_URI_CURRENTCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR: + case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: + case SVG_PAINTTYPE_URI: + return referenceId == SVGURIReference::getTarget(m_uri); + } + + ASSERT_NOT_REACHED(); + return false; } } |