summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/svg
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/svg
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/svg')
-rw-r--r--Source/WebCore/svg/SVGAnimateElement.cpp291
-rw-r--r--Source/WebCore/svg/SVGAnimateElement.h16
-rw-r--r--Source/WebCore/svg/SVGAnimateMotionElement.cpp35
-rw-r--r--Source/WebCore/svg/SVGAnimateMotionElement.h4
-rw-r--r--Source/WebCore/svg/SVGAnimateTransformElement.cpp56
-rw-r--r--Source/WebCore/svg/SVGAnimateTransformElement.h5
-rw-r--r--Source/WebCore/svg/SVGAnimationElement.cpp95
-rw-r--r--Source/WebCore/svg/SVGAnimationElement.h7
-rw-r--r--Source/WebCore/svg/SVGCircleElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGColor.cpp121
-rw-r--r--Source/WebCore/svg/SVGColor.h60
-rw-r--r--Source/WebCore/svg/SVGColor.idl28
-rw-r--r--Source/WebCore/svg/SVGCursorElement.cpp7
-rw-r--r--Source/WebCore/svg/SVGDocumentExtensions.cpp52
-rw-r--r--Source/WebCore/svg/SVGDocumentExtensions.h6
-rw-r--r--Source/WebCore/svg/SVGElement.cpp10
-rw-r--r--Source/WebCore/svg/SVGElement.h2
-rw-r--r--Source/WebCore/svg/SVGEllipseElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGFEBlendElement.cpp16
-rw-r--r--Source/WebCore/svg/SVGFEBlendElement.h1
-rw-r--r--Source/WebCore/svg/SVGFEColorMatrixElement.cpp15
-rw-r--r--Source/WebCore/svg/SVGFEColorMatrixElement.h1
-rw-r--r--Source/WebCore/svg/SVGFECompositeElement.cpp27
-rw-r--r--Source/WebCore/svg/SVGFECompositeElement.h1
-rw-r--r--Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp32
-rw-r--r--Source/WebCore/svg/SVGFEConvolveMatrixElement.h1
-rw-r--r--Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp40
-rw-r--r--Source/WebCore/svg/SVGFEDiffuseLightingElement.h3
-rw-r--r--Source/WebCore/svg/SVGFEDisplacementMapElement.cpp20
-rw-r--r--Source/WebCore/svg/SVGFEDisplacementMapElement.h1
-rw-r--r--Source/WebCore/svg/SVGFELightElement.cpp27
-rw-r--r--Source/WebCore/svg/SVGFELightElement.h2
-rw-r--r--Source/WebCore/svg/SVGFEMorphologyElement.cpp18
-rw-r--r--Source/WebCore/svg/SVGFEMorphologyElement.h1
-rw-r--r--Source/WebCore/svg/SVGFESpecularLightingElement.cpp85
-rw-r--r--Source/WebCore/svg/SVGFESpecularLightingElement.h5
-rw-r--r--Source/WebCore/svg/SVGFETurbulenceElement.cpp24
-rw-r--r--Source/WebCore/svg/SVGFETurbulenceElement.h1
-rw-r--r--Source/WebCore/svg/SVGFilterElement.cpp2
-rw-r--r--Source/WebCore/svg/SVGFont.cpp6
-rw-r--r--Source/WebCore/svg/SVGForeignObjectElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGGElement.cpp17
-rw-r--r--Source/WebCore/svg/SVGGElement.h2
-rw-r--r--Source/WebCore/svg/SVGHKernElement.cpp2
-rw-r--r--Source/WebCore/svg/SVGImageElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGImageLoader.cpp2
-rw-r--r--Source/WebCore/svg/SVGLineElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGPaint.cpp184
-rw-r--r--Source/WebCore/svg/SVGPaint.h66
-rw-r--r--Source/WebCore/svg/SVGPaint.idl30
-rw-r--r--Source/WebCore/svg/SVGPathElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGPolyElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGPreserveAspectRatio.cpp7
-rw-r--r--Source/WebCore/svg/SVGPreserveAspectRatio.h6
-rw-r--r--Source/WebCore/svg/SVGRectElement.cpp6
-rw-r--r--Source/WebCore/svg/SVGSVGElement.cpp20
-rw-r--r--Source/WebCore/svg/SVGScriptElement.cpp20
-rw-r--r--Source/WebCore/svg/SVGScriptElement.h3
-rw-r--r--Source/WebCore/svg/SVGStyledElement.cpp5
-rw-r--r--Source/WebCore/svg/SVGStyledElement.h1
-rw-r--r--Source/WebCore/svg/SVGStyledTransformableElement.cpp16
-rw-r--r--Source/WebCore/svg/SVGStyledTransformableElement.h1
-rw-r--r--Source/WebCore/svg/SVGTextContentElement.cpp2
-rw-r--r--Source/WebCore/svg/SVGTransformable.cpp5
-rw-r--r--Source/WebCore/svg/SVGTransformable.h2
-rw-r--r--Source/WebCore/svg/SVGUseElement.cpp8
-rw-r--r--Source/WebCore/svg/SVGVKernElement.cpp2
-rw-r--r--Source/WebCore/svg/animation/SMILTimeContainer.cpp23
-rw-r--r--Source/WebCore/svg/animation/SMILTimeContainer.h3
-rw-r--r--Source/WebCore/svg/animation/SVGSMILElement.cpp55
-rw-r--r--Source/WebCore/svg/animation/SVGSMILElement.h9
-rw-r--r--Source/WebCore/svg/graphics/SVGImage.cpp12
72 files changed, 1102 insertions, 573 deletions
diff --git a/Source/WebCore/svg/SVGAnimateElement.cpp b/Source/WebCore/svg/SVGAnimateElement.cpp
index 0dfe086..33ca46b 100644
--- a/Source/WebCore/svg/SVGAnimateElement.cpp
+++ b/Source/WebCore/svg/SVGAnimateElement.cpp
@@ -24,6 +24,8 @@
#if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
#include "SVGAnimateElement.h"
+#include "CSSComputedStyleDeclaration.h"
+#include "CSSParser.h"
#include "CSSPropertyNames.h"
#include "ColorDistance.h"
#include "FloatConversion.h"
@@ -35,6 +37,7 @@
#include "SVGPathParserFactory.h"
#include "SVGPathSegList.h"
#include "SVGPointList.h"
+#include "SVGStyledElement.h"
using namespace std;
@@ -42,7 +45,7 @@ namespace WebCore {
SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document* document)
: SVGAnimationElement(tagName, document)
- , m_propertyType(StringProperty)
+ , m_animatedAttributeType(AnimatedString)
, m_fromNumber(0)
, m_toNumber(0)
, m_animatedNumber(numeric_limits<double>::infinity())
@@ -85,55 +88,125 @@ static bool parseNumberValueAndUnit(const String& in, double& value, String& uni
return ok;
}
-static inline bool adjustForCurrentColor(Color& color, const String& value, SVGElement* target)
+static inline void adjustForCurrentColor(SVGElement* targetElement, Color& color)
{
- if (!target || !target->isStyled() || value != "currentColor")
- return false;
+ ASSERT(targetElement);
- if (RenderObject* targetRenderer = target->renderer())
+ if (RenderObject* targetRenderer = targetElement->renderer())
color = targetRenderer->style()->visitedDependentColor(CSSPropertyColor);
+ else
+ color = Color();
+}
- return true;
+static inline void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String& value)
+{
+ // FIXME: At the moment the computed style gets returned as a String and needs to get parsed again.
+ // In the future we might want to work with the value type directly to avoid the String parsing.
+ ASSERT(targetElement);
+
+ Element* parent = targetElement->parentElement();
+ if (!parent || !parent->isSVGElement())
+ return;
+
+ SVGElement* svgParent = static_cast<SVGElement*>(parent);
+ if (svgParent->isStyled())
+ value = computedStyle(svgParent)->getPropertyValue(cssPropertyID(attributeName.localName()));
+}
+
+bool SVGAnimateElement::hasValidAttributeType() const
+{
+ SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
+ return false;
+
+ return determineAnimatedAttributeType(targetElement) != AnimatedUnknown;
}
-SVGAnimateElement::PropertyType SVGAnimateElement::determinePropertyType(const String& attribute) const
+AnimatedAttributeType SVGAnimateElement::determineAnimatedAttributeType(SVGElement* targetElement) const
{
- // FIXME: We should not allow animation of attribute types other than AnimatedColor for <animateColor>.
- if (hasTagName(SVGNames::animateColorTag))
- return ColorProperty;
-
- // FIXME: Now that we have a full property table we need a more granular type specific animation.
- AnimatedAttributeType type = targetElement()->animatedPropertyTypeForAttribute(QualifiedName(nullAtom, attribute, nullAtom));
- if (type == AnimatedColor)
- return ColorProperty;
- if (type == AnimatedPath)
- return PathProperty;
- if (type == AnimatedPoints)
- return PointsProperty;
- return NumberProperty;
+ ASSERT(targetElement);
+
+ AnimatedAttributeType type = targetElement->animatedPropertyTypeForAttribute(attributeName());
+ if (type == AnimatedUnknown || (hasTagName(SVGNames::animateColorTag) && type != AnimatedColor))
+ return AnimatedUnknown;
+
+ // FIXME: We need type specific animations in the future. Many animations marked as AnimatedString today will
+ // support continuous animations.
+ switch (type) {
+ case AnimatedBoolean:
+ case AnimatedEnumeration:
+ case AnimatedLengthList:
+ case AnimatedNumberList:
+ case AnimatedNumberOptionalNumber:
+ case AnimatedPreserveAspectRatio:
+ case AnimatedRect:
+ case AnimatedString:
+ return AnimatedString;
+ case AnimatedAngle:
+ case AnimatedInteger:
+ case AnimatedLength:
+ case AnimatedNumber:
+ return AnimatedNumber;
+ case AnimatedPath:
+ return AnimatedPath;
+ case AnimatedPoints:
+ return AnimatedPoints;
+ case AnimatedColor:
+ return AnimatedColor;
+ case AnimatedUnknown:
+ case AnimatedTransformList:
+ // Animations of transform lists are not allowed for <animate> or <set>
+ // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
+ return AnimatedUnknown;
+ }
+
+ ASSERT_NOT_REACHED();
+ return AnimatedUnknown;
}
void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement)
{
- ASSERT(percentage >= 0.f && percentage <= 1.f);
+ ASSERT(percentage >= 0 && percentage <= 1);
ASSERT(resultElement);
- bool isInFirstHalfOfAnimation = percentage < 0.5;
+ bool isInFirstHalfOfAnimation = percentage < 0.5f;
AnimationMode animationMode = this->animationMode();
+ SVGElement* targetElement = 0;
+ // Avoid targetElement() call if possible. It might slow down animations.
+ if (m_fromPropertyValueType == InheritValue || m_toPropertyValueType == InheritValue
+ || m_fromPropertyValueType == CurrentColorValue || m_toPropertyValueType == CurrentColorValue) {
+ targetElement = this->targetElement();
+ if (!targetElement)
+ return;
+ }
if (hasTagName(SVGNames::setTag))
- percentage = 1.f;
+ percentage = 1;
if (!resultElement->hasTagName(SVGNames::animateTag) && !resultElement->hasTagName(SVGNames::animateColorTag)
&& !resultElement->hasTagName(SVGNames::setTag))
return;
SVGAnimateElement* results = static_cast<SVGAnimateElement*>(resultElement);
// Can't accumulate over a string property.
- if (results->m_propertyType == StringProperty && m_propertyType != StringProperty)
+ if (results->m_animatedAttributeType == AnimatedString && m_animatedAttributeType != AnimatedString)
return;
- if (m_propertyType == NumberProperty) {
+ if (m_animatedAttributeType == AnimatedNumber) {
// To animation uses contributions from the lower priority animations as the base value.
if (animationMode == ToAnimation)
m_fromNumber = results->m_animatedNumber;
+ // Replace 'currentColor' / 'inherit' by their computed property values.
+ if (m_fromPropertyValueType == InheritValue) {
+ String fromNumberString;
+ adjustForInheritance(targetElement, attributeName(), fromNumberString);
+ if (!parseNumberValueAndUnit(fromNumberString, m_fromNumber, m_numberUnit))
+ return;
+ }
+ if (m_toPropertyValueType == InheritValue) {
+ String toNumberString;
+ adjustForInheritance(targetElement, attributeName(), toNumberString);
+ if (!parseNumberValueAndUnit(toNumberString, m_toNumber, m_numberUnit))
+ return;
+ }
+
double number;
if (calcMode() == CalcModeDiscrete)
number = isInFirstHalfOfAnimation ? m_fromNumber : m_toNumber;
@@ -149,9 +222,26 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
results->m_animatedNumber = number;
return;
}
- if (m_propertyType == ColorProperty) {
+ if (m_animatedAttributeType == AnimatedColor) {
if (animationMode == ToAnimation)
m_fromColor = results->m_animatedColor;
+
+ // Replace 'currentColor' / 'inherit' by their computed property values.
+ if (m_fromPropertyValueType == CurrentColorValue)
+ adjustForCurrentColor(targetElement, m_fromColor);
+ else if (m_fromPropertyValueType == InheritValue) {
+ String fromColorString;
+ adjustForInheritance(targetElement, attributeName(), fromColorString);
+ m_fromColor = SVGColor::colorFromRGBColorString(fromColorString);
+ }
+ if (m_toPropertyValueType == CurrentColorValue)
+ adjustForCurrentColor(targetElement, m_toColor);
+ else if (m_toPropertyValueType == InheritValue) {
+ String toColorString;
+ adjustForInheritance(targetElement, attributeName(), toColorString);
+ m_toColor = SVGColor::colorFromRGBColorString(toColorString);
+ }
+
Color color;
if (calcMode() == CalcModeDiscrete)
color = isInFirstHalfOfAnimation ? m_fromColor : m_toColor;
@@ -165,7 +255,7 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
results->m_animatedColor = color;
return;
}
- if (m_propertyType == PathProperty) {
+ if (m_animatedAttributeType == AnimatedPath) {
if (animationMode == ToAnimation) {
ASSERT(results->m_animatedPathPointer);
m_fromPath = results->m_animatedPathPointer->copy();
@@ -174,7 +264,7 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
ASSERT(m_fromPath);
ASSERT(percentage >= 0);
results->m_animatedPathPointer = m_fromPath.get();
- } else if (percentage == 1.f) {
+ } else if (percentage == 1) {
ASSERT(m_toPath);
results->m_animatedPathPointer = m_toPath.get();
} else {
@@ -192,16 +282,16 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
ASSERT(m_fromPath);
ASSERT(m_toPath);
ASSERT(!results->m_animatedPath);
- results->m_animatedPathPointer = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f)
+ results->m_animatedPathPointer = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1)
? m_toPath.get() : m_fromPath.get();
}
}
return;
}
- if (m_propertyType == PointsProperty) {
+ if (m_animatedAttributeType == AnimatedPoints) {
if (!percentage)
results->m_animatedPoints = m_fromPoints;
- else if (percentage == 1.f)
+ else if (percentage == 1)
results->m_animatedPoints = m_toPoints;
else {
if (!m_fromPoints.isEmpty() && !m_toPoints.isEmpty())
@@ -210,40 +300,75 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
results->m_animatedPoints.clear();
// Fall back to discrete animation if the points are not compatible
if (results->m_animatedPoints.isEmpty())
- results->m_animatedPoints = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f)
+ results->m_animatedPoints = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1)
? m_toPoints : m_fromPoints;
}
return;
}
ASSERT(animationMode == FromToAnimation || animationMode == ToAnimation || animationMode == ValuesAnimation);
- if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f)
+ // Replace 'currentColor' / 'inherit' by their computed property values.
+ if (m_fromPropertyValueType == InheritValue)
+ adjustForInheritance(targetElement, attributeName(), m_fromString);
+ if (m_toPropertyValueType == InheritValue)
+ adjustForInheritance(targetElement, attributeName(), m_toString);
+
+ if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1)
results->m_animatedString = m_toString;
else
results->m_animatedString = m_fromString;
// Higher priority replace animation overrides any additive results so far.
- results->m_propertyType = StringProperty;
+ results->m_animatedAttributeType = AnimatedString;
+}
+
+static bool inheritsFromProperty(SVGElement* targetElement, const QualifiedName& attributeName, const String& value)
+{
+ ASSERT(targetElement);
+ DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit"));
+
+ if (value.isEmpty() || value != inherit || !targetElement->isStyled())
+ return false;
+ return SVGStyledElement::isAnimatableCSSProperty(attributeName);
+}
+
+static bool attributeValueIsCurrentColor(const String& value)
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, currentColor, ("currentColor"));
+ return value == currentColor;
}
bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const String& toString)
{
+ SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
+ return false;
+ m_fromPropertyValueType = inheritsFromProperty(targetElement, attributeName(), fromString) ? InheritValue : RegularPropertyValue;
+ m_toPropertyValueType = inheritsFromProperty(targetElement, attributeName(), toString) ? InheritValue : RegularPropertyValue;
+
// FIXME: Needs more solid way determine target attribute type.
- m_propertyType = determinePropertyType(attributeName());
- if (m_propertyType == ColorProperty) {
- SVGElement* targetElement = this->targetElement();
- if (!adjustForCurrentColor(m_fromColor, fromString, targetElement))
+ m_animatedAttributeType = determineAnimatedAttributeType(targetElement);
+ if (m_animatedAttributeType == AnimatedColor) {
+ bool fromIsCurrentColor = attributeValueIsCurrentColor(fromString);
+ bool toIsCurrentColor = attributeValueIsCurrentColor(toString);
+ if (fromIsCurrentColor)
+ m_fromPropertyValueType = CurrentColorValue;
+ else
m_fromColor = SVGColor::colorFromRGBColorString(fromString);
- if (!adjustForCurrentColor(m_toColor, toString, targetElement))
+ if (toIsCurrentColor)
+ m_toPropertyValueType = CurrentColorValue;
+ else
m_toColor = SVGColor::colorFromRGBColorString(toString);
- if ((m_fromColor.isValid() && m_toColor.isValid()) || (m_toColor.isValid() && animationMode() == ToAnimation))
+ bool fromIsValid = m_fromColor.isValid() || fromIsCurrentColor || m_fromPropertyValueType == InheritValue;
+ bool toIsValid = m_toColor.isValid() || toIsCurrentColor || m_toPropertyValueType == InheritValue;
+ if ((fromIsValid && toIsValid) || (toIsValid && animationMode() == ToAnimation))
return true;
- } else if (m_propertyType == NumberProperty) {
+ } else if (m_animatedAttributeType == AnimatedNumber) {
m_numberUnit = String();
if (parseNumberValueAndUnit(toString, m_toNumber, m_numberUnit)) {
// For to-animations the from number is calculated later
if (animationMode() == ToAnimation || parseNumberValueAndUnit(fromString, m_fromNumber, m_numberUnit))
return true;
}
- } else if (m_propertyType == PathProperty) {
+ } else if (m_animatedAttributeType == AnimatedPath) {
SVGPathParserFactory* factory = SVGPathParserFactory::self();
if (factory->buildSVGPathByteStreamFromString(toString, m_toPath, UnalteredParsing)) {
// For to-animations the from number is calculated later
@@ -252,7 +377,7 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const
}
m_fromPath.clear();
m_toPath.clear();
- } else if (m_propertyType == PointsProperty) {
+ } else if (m_animatedAttributeType == AnimatedPoints) {
m_fromPoints.clear();
if (pointsListFromSVGData(m_fromPoints, fromString)) {
m_toPoints.clear();
@@ -262,22 +387,34 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const
}
m_fromString = fromString;
m_toString = toString;
- m_propertyType = StringProperty;
+ m_animatedAttributeType = AnimatedString;
return true;
}
bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const String& byString)
{
+ SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
+ return false;
+ m_fromPropertyValueType = inheritsFromProperty(targetElement, attributeName(), fromString) ? InheritValue : RegularPropertyValue;
+ m_toPropertyValueType = inheritsFromProperty(targetElement, attributeName(), byString) ? InheritValue : RegularPropertyValue;
+
ASSERT(!hasTagName(SVGNames::setTag));
- m_propertyType = determinePropertyType(attributeName());
- if (m_propertyType == ColorProperty) {
- SVGElement* targetElement = this->targetElement();
- if (!adjustForCurrentColor(m_fromColor, fromString, targetElement))
- m_fromColor = fromString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(fromString);
- if (!adjustForCurrentColor(m_toColor, byString, targetElement))
+ m_animatedAttributeType = determineAnimatedAttributeType(targetElement);
+ if (m_animatedAttributeType == AnimatedColor) {
+ bool fromIsCurrentColor = attributeValueIsCurrentColor(fromString);
+ bool byIsCurrentColor = attributeValueIsCurrentColor(byString);
+ if (fromIsCurrentColor)
+ m_fromPropertyValueType = CurrentColorValue;
+ else
+ m_fromColor = SVGColor::colorFromRGBColorString(fromString);
+ if (byIsCurrentColor)
+ m_toPropertyValueType = CurrentColorValue;
+ else
m_toColor = SVGColor::colorFromRGBColorString(byString);
- m_toColor = ColorDistance::addColorsAndClamp(m_fromColor, m_toColor);
- if (!m_fromColor.isValid() || !m_toColor.isValid())
+
+ if ((!m_fromColor.isValid() && !fromIsCurrentColor)
+ || (!m_toColor.isValid() && !byIsCurrentColor))
return false;
} else {
m_numberUnit = String();
@@ -293,16 +430,18 @@ bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const
void SVGAnimateElement::resetToBaseValue(const String& baseString)
{
+ SVGElement* targetElement = this->targetElement();
+ ASSERT(targetElement);
m_animatedString = baseString;
- PropertyType lastType = m_propertyType;
- m_propertyType = determinePropertyType(attributeName());
- if (m_propertyType == ColorProperty) {
+ AnimatedAttributeType lastType = m_animatedAttributeType;
+ m_animatedAttributeType = determineAnimatedAttributeType(targetElement);
+ if (m_animatedAttributeType == AnimatedColor) {
m_animatedColor = baseString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(baseString);
if (isContributing(elapsed())) {
- m_propertyType = lastType;
+ m_animatedAttributeType = lastType;
return;
}
- } else if (m_propertyType == NumberProperty) {
+ } else if (m_animatedAttributeType == AnimatedNumber) {
if (baseString.isEmpty()) {
m_animatedNumber = 0;
m_numberUnit = String();
@@ -310,27 +449,27 @@ void SVGAnimateElement::resetToBaseValue(const String& baseString)
}
if (parseNumberValueAndUnit(baseString, m_animatedNumber, m_numberUnit))
return;
- } else if (m_propertyType == PathProperty) {
+ } else if (m_animatedAttributeType == AnimatedPath) {
m_animatedPath.clear();
SVGPathParserFactory* factory = SVGPathParserFactory::self();
factory->buildSVGPathByteStreamFromString(baseString, m_animatedPath, UnalteredParsing);
m_animatedPathPointer = m_animatedPath.get();
return;
- } else if (m_propertyType == PointsProperty) {
+ } else if (m_animatedAttributeType == AnimatedPoints) {
m_animatedPoints.clear();
return;
}
- m_propertyType = StringProperty;
+ m_animatedAttributeType = AnimatedString;
}
void SVGAnimateElement::applyResultsToTarget()
{
String valueToApply;
- if (m_propertyType == ColorProperty)
- valueToApply = m_animatedColor.name();
- else if (m_propertyType == NumberProperty)
+ if (m_animatedAttributeType == AnimatedColor)
+ valueToApply = m_animatedColor.serialized();
+ else if (m_animatedAttributeType == AnimatedNumber)
valueToApply = String::number(m_animatedNumber) + m_numberUnit;
- else if (m_propertyType == PathProperty) {
+ else if (m_animatedAttributeType == AnimatedPath) {
if (!m_animatedPathPointer || m_animatedPathPointer->isEmpty())
valueToApply = m_animatedString;
else {
@@ -341,7 +480,7 @@ void SVGAnimateElement::applyResultsToTarget()
SVGPathParserFactory* factory = SVGPathParserFactory::self();
factory->buildStringFromByteStream(m_animatedPathPointer, valueToApply, UnalteredParsing);
}
- } else if (m_propertyType == PointsProperty)
+ } else if (m_animatedAttributeType == AnimatedPoints)
valueToApply = m_animatedPoints.isEmpty() ? m_animatedString : m_animatedPoints.valueAsString();
else
valueToApply = m_animatedString;
@@ -351,31 +490,31 @@ void SVGAnimateElement::applyResultsToTarget()
float SVGAnimateElement::calculateDistance(const String& fromString, const String& toString)
{
- m_propertyType = determinePropertyType(attributeName());
- if (m_propertyType == NumberProperty) {
+ SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
+ return -1;
+ m_animatedAttributeType = determineAnimatedAttributeType(targetElement);
+ if (m_animatedAttributeType == AnimatedNumber) {
double from;
double to;
String unit;
if (!parseNumberValueAndUnit(fromString, from, unit))
- return -1.f;
+ return -1;
if (!parseNumberValueAndUnit(toString, to, unit))
- return -1.f;
+ return -1;
return narrowPrecisionToFloat(fabs(to - from));
}
- if (m_propertyType == ColorProperty) {
+ if (m_animatedAttributeType == AnimatedColor) {
Color from = SVGColor::colorFromRGBColorString(fromString);
if (!from.isValid())
- return -1.f;
+ return -1;
Color to = SVGColor::colorFromRGBColorString(toString);
if (!to.isValid())
- return -1.f;
+ return -1;
return ColorDistance(from, to).distance();
}
- return -1.f;
+ return -1;
}
}
-
-// vim:ts=4:noet
#endif // ENABLE(SVG)
-
diff --git a/Source/WebCore/svg/SVGAnimateElement.h b/Source/WebCore/svg/SVGAnimateElement.h
index 3217c4a..75be4b2 100644
--- a/Source/WebCore/svg/SVGAnimateElement.h
+++ b/Source/WebCore/svg/SVGAnimateElement.h
@@ -51,10 +51,20 @@ protected:
virtual float calculateDistance(const String& fromString, const String& toString);
private:
- enum PropertyType { NumberProperty, ColorProperty, StringProperty, PathProperty, PointsProperty };
- PropertyType determinePropertyType(const String& attribute) const;
- PropertyType m_propertyType;
+ // If we have 'currentColor' or 'inherit' as animation value, we need to grab the value during the animation
+ // since the value can be animated itself.
+ enum AnimatedPropertyValueType {
+ RegularPropertyValue,
+ CurrentColorValue,
+ InheritValue
+ };
+
+ virtual bool hasValidAttributeType() const;
+ AnimatedAttributeType determineAnimatedAttributeType(SVGElement*) const;
+ AnimatedAttributeType m_animatedAttributeType;
+ AnimatedPropertyValueType m_fromPropertyValueType;
+ AnimatedPropertyValueType m_toPropertyValueType;
double m_fromNumber;
double m_toNumber;
double m_animatedNumber;
diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.cpp b/Source/WebCore/svg/SVGAnimateMotionElement.cpp
index ec51548..e0202e4 100644
--- a/Source/WebCore/svg/SVGAnimateMotionElement.cpp
+++ b/Source/WebCore/svg/SVGAnimateMotionElement.cpp
@@ -53,14 +53,17 @@ PassRefPtr<SVGAnimateMotionElement> SVGAnimateMotionElement::create(const Qualif
return adoptRef(new SVGAnimateMotionElement(tagName, document));
}
-bool SVGAnimateMotionElement::hasValidTarget() const
+bool SVGAnimateMotionElement::hasValidAttributeType() const
{
- if (!SVGAnimationElement::hasValidTarget())
- return false;
SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
+ return false;
+
+ // We don't have a special attribute name to verify the animation type. Check the element name instead.
if (!targetElement->isStyledTransformable() && !targetElement->hasTagName(SVGNames::textTag))
return false;
// Spec: SVG 1.1 section 19.2.15
+ // FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could cause problems.
if (targetElement->hasTagName(gTag)
|| targetElement->hasTagName(defsTag)
|| targetElement->hasTagName(useTag)
@@ -134,11 +137,11 @@ static bool parsePoint(const String& s, FloatPoint& point)
if (!skipOptionalSpaces(cur, end))
return false;
- float x = 0.0f;
+ float x = 0;
if (!parseNumber(cur, end, x))
return false;
- float y = 0.0f;
+ float y = 0;
if (!parseNumber(cur, end, y))
return false;
@@ -150,10 +153,9 @@ static bool parsePoint(const String& s, FloatPoint& point)
void SVGAnimateMotionElement::resetToBaseValue(const String&)
{
- if (!hasValidTarget())
+ if (!hasValidAttributeType())
return;
- SVGElement* target = targetElement();
- AffineTransform* transform = target->supplementalTransform();
+ AffineTransform* transform = targetElement()->supplementalTransform();
if (!transform)
return;
transform->makeIdentity();
@@ -177,15 +179,15 @@ bool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString,
void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned, SVGSMILElement*)
{
- SVGElement* target = targetElement();
- if (!target)
+ SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
return;
- AffineTransform* transform = target->supplementalTransform();
+ AffineTransform* transform = targetElement->supplementalTransform();
if (!transform)
return;
- if (target->renderer())
- target->renderer()->setNeedsTransformUpdate();
+ if (RenderObject* targetRenderer = targetElement->renderer())
+ targetRenderer->setNeedsTransformUpdate();
if (!isAdditive())
transform->makeIdentity();
@@ -204,7 +206,7 @@ void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned,
if (rotateMode == RotateAuto || rotateMode == RotateAutoReverse) {
float angle = path.normalAngleAtLength(positionOnPath, ok);
if (rotateMode == RotateAutoReverse)
- angle += 180.f;
+ angle += 180;
transform->rotate(angle);
}
}
@@ -250,13 +252,12 @@ float SVGAnimateMotionElement::calculateDistance(const String& fromString, const
FloatPoint from;
FloatPoint to;
if (!parsePoint(fromString, from))
- return -1.f;
+ return -1;
if (!parsePoint(toString, to))
- return -1.f;
+ return -1;
FloatSize diff = to - from;
return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
}
}
-
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.h b/Source/WebCore/svg/SVGAnimateMotionElement.h
index 7e168c3..96861b6 100644
--- a/Source/WebCore/svg/SVGAnimateMotionElement.h
+++ b/Source/WebCore/svg/SVGAnimateMotionElement.h
@@ -34,7 +34,7 @@ public:
private:
SVGAnimateMotionElement(const QualifiedName&, Document*);
- virtual bool hasValidTarget() const;
+ virtual bool hasValidAttributeType() const;
virtual void parseMappedAttribute(Attribute*);
@@ -73,5 +73,3 @@ private:
#endif // ENABLE(SVG_ANIMATION)
#endif // SVGAnimateMotionElement_h
-
-// vim:ts=4:noet
diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.cpp b/Source/WebCore/svg/SVGAnimateTransformElement.cpp
index bdcab38..6e1fb99 100644
--- a/Source/WebCore/svg/SVGAnimateTransformElement.cpp
+++ b/Source/WebCore/svg/SVGAnimateTransformElement.cpp
@@ -59,14 +59,25 @@ PassRefPtr<SVGAnimateTransformElement> SVGAnimateTransformElement::create(const
return adoptRef(new SVGAnimateTransformElement(tagName, document));
}
-bool SVGAnimateTransformElement::hasValidTarget() const
+bool SVGAnimateTransformElement::hasValidAttributeType() const
{
SVGElement* targetElement = this->targetElement();
- return SVGAnimationElement::hasValidTarget()
- && (targetElement->isStyledTransformable()
- || targetElement->hasTagName(SVGNames::textTag)
- || targetElement->hasTagName(SVGNames::linearGradientTag)
- || targetElement->hasTagName(SVGNames::radialGradientTag));
+ if (!targetElement)
+ return false;
+
+ return determineAnimatedAttributeType(targetElement) == AnimatedTransformList;
+}
+
+AnimatedAttributeType SVGAnimateTransformElement::determineAnimatedAttributeType(SVGElement* targetElement) const
+{
+ ASSERT(targetElement);
+
+ // Just transform lists can be animated with <animateTransform>
+ // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
+ if (targetElement->animatedPropertyTypeForAttribute(attributeName()) != AnimatedTransformList)
+ return AnimatedUnknown;
+
+ return AnimatedTransformList;
}
void SVGAnimateTransformElement::parseMappedAttribute(Attribute* attr)
@@ -102,26 +113,27 @@ static SVGTransformList* transformListFor(SVGElement* element)
void SVGAnimateTransformElement::resetToBaseValue(const String& baseValue)
{
- if (!hasValidTarget())
+ SVGElement* targetElement = this->targetElement();
+ if (!targetElement || determineAnimatedAttributeType(targetElement) == AnimatedUnknown)
return;
- if (targetElement()->hasTagName(SVGNames::linearGradientTag) || targetElement()->hasTagName(SVGNames::radialGradientTag)) {
- targetElement()->setAttribute(SVGNames::gradientTransformAttr, baseValue.isEmpty() ? "matrix(1 0 0 1 0 0)" : baseValue);
+ if (targetElement->hasTagName(SVGNames::linearGradientTag) || targetElement->hasTagName(SVGNames::radialGradientTag)) {
+ targetElement->setAttribute(SVGNames::gradientTransformAttr, baseValue.isEmpty() ? "matrix(1 0 0 1 0 0)" : baseValue);
return;
}
if (baseValue.isEmpty()) {
- if (SVGTransformList* list = transformListFor(targetElement()))
+ if (SVGTransformList* list = transformListFor(targetElement))
list->clear();
} else
- targetElement()->setAttribute(SVGNames::transformAttr, baseValue);
+ targetElement->setAttribute(SVGNames::transformAttr, baseValue);
}
-void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement)
+void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement*)
{
- if (!hasValidTarget())
+ SVGElement* targetElement = this->targetElement();
+ if (!targetElement || determineAnimatedAttributeType(targetElement) == AnimatedUnknown)
return;
- SVGElement* targetElement = resultElement->targetElement();
SVGTransformList* transformList = transformListFor(targetElement);
ASSERT(transformList);
@@ -146,7 +158,6 @@ bool SVGAnimateTransformElement::calculateFromAndToValues(const String& fromStri
bool SVGAnimateTransformElement::calculateFromAndByValues(const String& fromString, const String& byString)
{
-
m_fromTransform = parseTransformValue(fromString);
if (!m_fromTransform.isValid())
return false;
@@ -168,13 +179,11 @@ SVGTransform SVGAnimateTransformElement::parseTransformValue(const String& value
void SVGAnimateTransformElement::applyResultsToTarget()
{
- if (!hasValidTarget())
- return;
- // We accumulate to the target element transform list so there is not much to do here.
SVGElement* targetElement = this->targetElement();
- if (!targetElement)
+ if (!targetElement || determineAnimatedAttributeType(targetElement) == AnimatedUnknown)
return;
+ // We accumulate to the target element transform list so there is not much to do here.
if (RenderObject* renderer = targetElement->renderer()) {
renderer->setNeedsTransformUpdate();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
@@ -210,10 +219,10 @@ float SVGAnimateTransformElement::calculateDistance(const String& fromString, co
// is paced separately. To implement this we need to treat each component as individual animation everywhere.
SVGTransform from = parseTransformValue(fromString);
if (!from.isValid())
- return -1.f;
+ return -1;
SVGTransform to = parseTransformValue(toString);
if (!to.isValid() || from.type() != to.type())
- return -1.f;
+ return -1;
if (to.type() == SVGTransform::SVG_TRANSFORM_TRANSLATE) {
FloatSize diff = to.translate() - from.translate();
return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
@@ -224,11 +233,8 @@ float SVGAnimateTransformElement::calculateDistance(const String& fromString, co
FloatSize diff = to.scale() - from.scale();
return sqrtf(diff.width() * diff.width() + diff.height() * diff.height());
}
- return -1.f;
+ return -1;
}
}
-
-// vim:ts=4:noet
#endif // ENABLE(SVG)
-
diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.h b/Source/WebCore/svg/SVGAnimateTransformElement.h
index 0f806d7..6ebc97e 100644
--- a/Source/WebCore/svg/SVGAnimateTransformElement.h
+++ b/Source/WebCore/svg/SVGAnimateTransformElement.h
@@ -39,7 +39,8 @@ public:
private:
SVGAnimateTransformElement(const QualifiedName&, Document*);
- virtual bool hasValidTarget() const;
+ virtual bool hasValidAttributeType() const;
+ AnimatedAttributeType determineAnimatedAttributeType(SVGElement*) const;
virtual void parseMappedAttribute(Attribute*);
@@ -64,5 +65,3 @@ private:
#endif // ENABLE(SVG)
#endif // SVGAnimateTransformElement_h
-
-// vim:ts=4:noet
diff --git a/Source/WebCore/svg/SVGAnimationElement.cpp b/Source/WebCore/svg/SVGAnimationElement.cpp
index c56e3b6..21784c2 100644
--- a/Source/WebCore/svg/SVGAnimationElement.cpp
+++ b/Source/WebCore/svg/SVGAnimationElement.cpp
@@ -41,6 +41,7 @@
#include "SVGElementInstance.h"
#include "SVGNames.h"
#include "SVGParserUtilities.h"
+#include "SVGStyledElement.h"
#include "SVGURIReference.h"
#include "SVGUseElement.h"
#include "XLinkNames.h"
@@ -68,7 +69,7 @@ static void parseKeyTimes(const String& parse, Vector<float>& result, bool verif
String timeString = parseList[n];
bool ok;
float time = timeString.toFloat(&ok);
- if (!ok || time < 0 || time > 1.f)
+ if (!ok || time < 0 || time > 1)
goto fail;
if (verifyOrder) {
if (!n) {
@@ -97,25 +98,25 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result)
bool delimParsed = false;
while (cur < end) {
delimParsed = false;
- float posA = 0.0f;
+ float posA = 0;
if (!parseNumber(cur, end, posA)) {
result.clear();
return;
}
- float posB = 0.0f;
+ float posB = 0;
if (!parseNumber(cur, end, posB)) {
result.clear();
return;
}
- float posC = 0.0f;
+ float posC = 0;
if (!parseNumber(cur, end, posC)) {
result.clear();
return;
}
- float posD = 0.0f;
+ float posD = 0;
if (!parseNumber(cur, end, posD, false)) {
result.clear();
return;
@@ -289,72 +290,56 @@ bool SVGAnimationElement::isAccumulated() const
return value == sum && animationMode() != ToAnimation;
}
-bool SVGAnimationElement::hasValidTarget() const
+bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement, const QualifiedName& attributeName)
{
- return targetElement();
-}
-
-bool SVGAnimationElement::attributeIsCSS(const String& attributeName)
-{
- // FIXME: We should have a map of all SVG properties and their attribute types so we
- // could validate animations better. The spec is very vague about this.
- unsigned id = cssPropertyID(attributeName);
- // SVG range
- if (id >= CSSPropertyClipPath && id <= CSSPropertyWritingMode)
- return true;
- // Regular CSS properties also in SVG
- return id == CSSPropertyColor || id == CSSPropertyDisplay || id == CSSPropertyOpacity
- || (id >= CSSPropertyFont && id <= CSSPropertyFontWeight)
- || id == CSSPropertyOverflow || id == CSSPropertyVisibility;
-}
-
-bool SVGAnimationElement::targetAttributeIsCSS() const
-{
- AttributeType type = attributeType();
- if (type == AttributeTypeCSS)
- return true;
- if (type == AttributeTypeXML)
+ ASSERT(targetElement);
+ if (!targetElement->isStyled())
return false;
- return attributeIsCSS(attributeName());
+
+ return SVGStyledElement::isAnimatableCSSProperty(attributeName);
}
void SVGAnimationElement::setTargetAttributeAnimatedValue(const String& value)
{
- if (!hasValidTarget())
+ if (!hasValidAttributeType())
return;
- SVGElement* target = targetElement();
- String attributeName = this->attributeName();
- if (!target || attributeName.isEmpty() || value.isNull())
+ SVGElement* targetElement = this->targetElement();
+ QualifiedName attributeName = this->attributeName();
+ if (!targetElement || attributeName == anyQName() || value.isNull())
return;
// We don't want the instance tree to get rebuild. Instances are updated in the loop below.
- if (target->isStyled())
- static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(true);
+ if (targetElement->isStyled())
+ static_cast<SVGStyledElement*>(targetElement)->setInstanceUpdatesBlocked(true);
+ bool attributeIsCSSProperty = isTargetAttributeCSSProperty(targetElement, attributeName);
+ // Stop animation, if attributeType is set to CSS by the user, but the attribute itself is not a CSS property.
+ if (!attributeIsCSSProperty && attributeType() == AttributeTypeCSS)
+ return;
+
ExceptionCode ec;
- bool isCSS = targetAttributeIsCSS();
- if (isCSS) {
+ if (attributeIsCSSProperty) {
// FIXME: This should set the override style, not the inline style.
// Sadly override styles are not yet implemented.
- target->style()->setProperty(attributeName, value, "", ec);
+ targetElement->style()->setProperty(attributeName.localName(), value, "", ec);
} else {
// FIXME: This should set the 'presentation' value, not the actual
// attribute value. Whatever that means in practice.
- target->setAttribute(attributeName, value, ec);
+ targetElement->setAttribute(attributeName, value, ec);
}
- if (target->isStyled())
- static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(false);
+ if (targetElement->isStyled())
+ static_cast<SVGStyledElement*>(targetElement)->setInstanceUpdatesBlocked(false);
// If the target element is used in an <use> instance tree, update that as well.
- const HashSet<SVGElementInstance*>& instances = target->instancesForElement();
+ const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
if (!shadowTreeElement)
continue;
- if (isCSS)
- shadowTreeElement->style()->setProperty(attributeName, value, "", ec);
+ if (attributeIsCSSProperty)
+ shadowTreeElement->style()->setProperty(attributeName.localName(), value, "", ec);
else
shadowTreeElement->setAttribute(attributeName, value, ec);
(*it)->correspondingUseElement()->setNeedsStyleRecalc();
@@ -385,13 +370,13 @@ void SVGAnimationElement::calculateKeyTimesForCalcModePaced()
// Normalize.
for (unsigned n = 1; n < keyTimesForPaced.size() - 1; ++n)
keyTimesForPaced[n] = keyTimesForPaced[n - 1] + keyTimesForPaced[n] / totalDistance;
- keyTimesForPaced[keyTimesForPaced.size() - 1] = 1.f;
+ keyTimesForPaced[keyTimesForPaced.size() - 1] = 1;
// Use key times calculated based on pacing instead of the user provided ones.
m_keyTimes.swap(keyTimesForPaced);
}
-static inline double solveEpsilon(double duration) { return 1. / (200. * duration); }
+static inline double solveEpsilon(double duration) { return 1 / (200 * duration); }
unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const
{
@@ -429,9 +414,9 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const
float toKeyPoint = m_keyPoints[index + 1];
if (calcMode() == CalcModeDiscrete)
- return percent == 1.0f ? toKeyPoint : fromKeyPoint;
+ return percent == 1 ? toKeyPoint : fromKeyPoint;
- float keyPointPercent = percent == 1.0f ? 1.0f : (percent - fromPercent) / (toPercent - fromPercent);
+ float keyPointPercent = percent == 1 ? 1 : (percent - fromPercent) / (toPercent - fromPercent);
if (calcMode() == CalcModeSpline) {
ASSERT(m_keySplines.size() == m_keyPoints.size() - 1);
@@ -446,7 +431,7 @@ void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effec
ASSERT(m_keyPoints.size() == m_keyTimes.size());
ASSERT(calcMode() != CalcModePaced);
effectivePercent = calculatePercentFromKeyPoints(percent);
- unsigned index = effectivePercent == 1.0f ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1));
+ unsigned index = effectivePercent == 1 ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1));
from = m_values[index];
to = m_values[index + 1];
}
@@ -468,10 +453,10 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
unsigned index = calculateKeyTimesIndex(percent);
if (calcMode == CalcModeDiscrete) {
if (!keyTimesCount)
- index = percent == 1.0f ? valuesCount - 1 : static_cast<unsigned>(percent * valuesCount);
+ index = percent == 1 ? valuesCount - 1 : static_cast<unsigned>(percent * valuesCount);
from = m_values[index];
to = m_values[index];
- effectivePercent = 0.0f;
+ effectivePercent = 0;
return;
}
@@ -491,7 +476,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
from = m_values[index];
to = m_values[index + 1];
ASSERT(toPercent > fromPercent);
- effectivePercent = percent == 1.0f ? 1.0f : (percent - fromPercent) / (toPercent - fromPercent);
+ effectivePercent = percent == 1 ? 1 : (percent - fromPercent) / (toPercent - fromPercent);
if (calcMode == CalcModeSpline) {
ASSERT(m_keySplines.size() == m_values.size() - 1);
@@ -503,7 +488,7 @@ void SVGAnimationElement::startedActiveInterval()
{
m_animationValid = false;
- if (!hasValidTarget())
+ if (!hasValidAttributeType())
return;
// These validations are appropriate for all animation modes.
@@ -579,7 +564,5 @@ void SVGAnimationElement::endedActiveInterval()
}
}
-
-// vim:ts=4:noet
#endif // ENABLE(SVG_ANIMATION)
diff --git a/Source/WebCore/svg/SVGAnimationElement.h b/Source/WebCore/svg/SVGAnimationElement.h
index 59d7f9e..8aa2cdb 100644
--- a/Source/WebCore/svg/SVGAnimationElement.h
+++ b/Source/WebCore/svg/SVGAnimationElement.h
@@ -55,8 +55,8 @@ public:
virtual void beginElementAt(float offset);
virtual void endElement();
virtual void endElementAt(float offset);
-
- static bool attributeIsCSS(const String& attributeName);
+
+ static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&);
protected:
SVGAnimationElement(const QualifiedName&, Document*);
@@ -75,12 +75,9 @@ protected:
enum AnimationMode { NoAnimation, ToAnimation, ByAnimation, ValuesAnimation, FromToAnimation, FromByAnimation, PathAnimation };
AnimationMode animationMode() const;
-
- virtual bool hasValidTarget() const;
String targetAttributeBaseValue() const;
void setTargetAttributeAnimatedValue(const String&);
- bool targetAttributeIsCSS() const;
bool isAdditive() const;
bool isAccumulated() const;
diff --git a/Source/WebCore/svg/SVGCircleElement.cpp b/Source/WebCore/svg/SVGCircleElement.cpp
index 6a3a0d4..2ab0640 100644
--- a/Source/WebCore/svg/SVGCircleElement.cpp
+++ b/Source/WebCore/svg/SVGCircleElement.cpp
@@ -90,12 +90,6 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
diff --git a/Source/WebCore/svg/SVGColor.cpp b/Source/WebCore/svg/SVGColor.cpp
index 75900ad..911d02f 100644
--- a/Source/WebCore/svg/SVGColor.cpp
+++ b/Source/WebCore/svg/SVGColor.cpp
@@ -1,6 +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 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
@@ -19,6 +20,7 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "SVGColor.h"
@@ -28,28 +30,11 @@
namespace WebCore {
-SVGColor::SVGColor()
- : m_colorType(SVG_COLORTYPE_UNKNOWN)
-{
-}
-
-SVGColor::SVGColor(const String& rgbColor)
- : m_colorType(SVG_COLORTYPE_RGBCOLOR)
-{
- setRGBColor(rgbColor);
-}
-
-SVGColor::SVGColor(SVGColorType colorType)
+SVGColor::SVGColor(const SVGColorType& colorType)
: m_colorType(colorType)
{
}
-SVGColor::SVGColor(const Color& c)
- : m_color(c)
- , m_colorType(SVG_COLORTYPE_RGBCOLOR)
-{
-}
-
PassRefPtr<RGBColor> SVGColor::rgbColor() const
{
return RGBColor::create(m_color.rgb());
@@ -58,43 +43,111 @@ PassRefPtr<RGBColor> SVGColor::rgbColor() const
void SVGColor::setRGBColor(const String& rgbColor, ExceptionCode& ec)
{
Color color = SVGColor::colorFromRGBColorString(rgbColor);
- if (color.isValid())
- m_color = color;
- else
+ if (!color.isValid()) {
ec = SVGException::SVG_INVALID_VALUE_ERR;
+ return;
+ }
+
+ m_color = color;
+ m_colorType = SVG_COLORTYPE_RGBCOLOR;
+ setNeedsStyleRecalc();
}
Color SVGColor::colorFromRGBColorString(const String& colorString)
{
- String s = colorString.stripWhiteSpace();
- // FIXME: rework css parser so it is more svg aware
+ // FIXME: Rework css parser so it is more SVG aware.
RGBA32 color;
- if (CSSParser::parseColor(color, s))
+ if (CSSParser::parseColor(color, colorString.stripWhiteSpace()))
return color;
return Color();
}
-void SVGColor::setRGBColorICCColor(const String& /* rgbColor */, const String& /* iccColor */, ExceptionCode&)
+void SVGColor::setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionCode& ec)
{
- // TODO: implement me!
+ if (rgbColor.isEmpty() || iccColor.isEmpty()) {
+ ec = SVGException::SVG_INVALID_VALUE_ERR;
+ return;
+ }
+
+ // FIXME: No support for ICC colors. We're just ignoring it.
+ setRGBColor(rgbColor, ec);
+ if (ec)
+ return;
+
+ m_colorType = SVG_COLORTYPE_RGBCOLOR_ICCCOLOR;
+ setNeedsStyleRecalc();
}
-void SVGColor::setColor(unsigned short colorType, const String& /* rgbColor */ , const String& /* iccColor */, ExceptionCode&)
+void SVGColor::setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionCode& ec)
{
- // TODO: implement me!
- m_colorType = colorType;
+ if (colorType > SVG_COLORTYPE_CURRENTCOLOR) {
+ ec = SVGException::SVG_WRONG_TYPE_ERR;
+ return;
+ }
+
+ bool requiresRGBColor = false;
+ bool requiresICCColor = false;
+
+ SVGColorType type = static_cast<SVGColorType>(colorType);
+ switch (type) {
+ case SVG_COLORTYPE_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_COLORTYPE_RGBCOLOR_ICCCOLOR:
+ requiresICCColor = true;
+ case SVG_COLORTYPE_RGBCOLOR:
+ requiresRGBColor = true;
+ break;
+ case SVG_COLORTYPE_CURRENTCOLOR:
+ break;
+ }
+
+ // Spec: If colorType requires an RGBColor, then rgbColor must be a string that matches <color>; otherwise, rgbColor must be null.
+ if (requiresRGBColor && rgbColor.isEmpty()) {
+ ec = SVGException::SVG_INVALID_VALUE_ERR;
+ return;
+ }
+
+ // Spec: If colorType requires an SVGICCColor, then iccColor must be a string that matches <icccolor>; otherwise, iccColor must be null.
+ if (requiresICCColor && iccColor.isEmpty()) {
+ ec = SVGException::SVG_INVALID_VALUE_ERR;
+ return;
+ }
+
+ setNeedsStyleRecalc();
+ m_colorType = type;
+ if (!requiresRGBColor) {
+ ASSERT(!requiresICCColor);
+ m_color = Color();
+ return;
+ }
+
+ if (requiresICCColor)
+ setRGBColorICCColor(rgbColor, iccColor, ec);
+ else
+ setRGBColor(rgbColor, ec);
}
String SVGColor::cssText() const
{
- if (m_colorType == SVG_COLORTYPE_RGBCOLOR)
- return m_color.name();
-
+ switch (m_colorType) {
+ case SVG_COLORTYPE_UNKNOWN:
+ return String();
+ case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR:
+ case SVG_COLORTYPE_RGBCOLOR:
+ // FIXME: No ICC color support.
+ return m_color.serialized();
+ case SVG_COLORTYPE_CURRENTCOLOR:
+ if (m_color.isValid())
+ return m_color.serialized();
+ return "currentColor";
+ }
+
+ ASSERT_NOT_REACHED();
return String();
}
}
-// vim:ts=4:noet
#endif // ENABLE(SVG)
-
diff --git a/Source/WebCore/svg/SVGColor.h b/Source/WebCore/svg/SVGColor.h
index 6d8b94e..58dc704 100644
--- a/Source/WebCore/svg/SVGColor.h
+++ b/Source/WebCore/svg/SVGColor.h
@@ -1,6 +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 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
@@ -20,9 +21,9 @@
#ifndef SVGColor_h
#define SVGColor_h
-#if ENABLE(SVG)
-#include "CSSValue.h"
+#if ENABLE(SVG)
+#include "CSSMutableValue.h"
#include "Color.h"
#include <wtf/PassRefPtr.h>
@@ -30,63 +31,62 @@ namespace WebCore {
class RGBColor;
-class SVGColor : public CSSValue {
+class SVGColor : public CSSMutableValue {
public:
- static PassRefPtr<SVGColor> create(const String& color)
+ enum SVGColorType {
+ SVG_COLORTYPE_UNKNOWN = 0,
+ SVG_COLORTYPE_RGBCOLOR = 1,
+ SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2,
+ SVG_COLORTYPE_CURRENTCOLOR = 3
+ };
+
+ static PassRefPtr<SVGColor> createFromString(const String& rgbColor)
{
- return adoptRef(new SVGColor(color));
+ RefPtr<SVGColor> color = adoptRef(new SVGColor(SVG_COLORTYPE_RGBCOLOR));
+ color->setColor(colorFromRGBColorString(rgbColor));
+ return color.release();
}
- static PassRefPtr<SVGColor> create(const Color& color)
+
+ static PassRefPtr<SVGColor> createFromColor(const Color& rgbColor)
{
- return adoptRef(new SVGColor(color));
+ RefPtr<SVGColor> color = adoptRef(new SVGColor(SVG_COLORTYPE_RGBCOLOR));
+ color->setColor(rgbColor);
+ return color.release();
}
+
static PassRefPtr<SVGColor> createCurrentColor()
{
return adoptRef(new SVGColor(SVG_COLORTYPE_CURRENTCOLOR));
}
- enum SVGColorType {
- SVG_COLORTYPE_UNKNOWN = 0,
- SVG_COLORTYPE_RGBCOLOR = 1,
- SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2,
- SVG_COLORTYPE_CURRENTCOLOR = 3
- };
-
- // 'SVGColor' functions
- unsigned short colorType() const { return m_colorType; }
-
+ const Color& color() const { return m_color; }
+ const SVGColorType& colorType() const { return m_colorType; }
PassRefPtr<RGBColor> rgbColor() const;
static Color colorFromRGBColorString(const String&);
- void setRGBColor(const String& rgbColor) { ExceptionCode ignored = 0; setRGBColor(rgbColor, ignored); }
void setRGBColor(const String& rgbColor, ExceptionCode&);
void setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionCode&);
void setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionCode&);
- const Color& color() const { return m_color; }
-
protected:
- SVGColor();
- SVGColor(const String& color);
- SVGColor(const Color&);
+ friend class CSSComputedStyleDeclaration;
+ SVGColor(const SVGColorType&);
+ virtual ~SVGColor() { }
virtual String cssText() const;
-private:
- SVGColor(SVGColorType);
-
- static void create(int); // compile-time guard
+ void setColor(const Color& color) { m_color = color; }
+ void setColorType(const SVGColorType& type) { m_colorType = type; }
+private:
virtual bool isSVGColor() const { return true; }
Color m_color;
- unsigned short m_colorType;
+ SVGColorType m_colorType;
};
} // namespace WebCore
#endif // ENABLE(SVG)
#endif // SVGColor_h
-
-// vim:ts=4:noet
diff --git a/Source/WebCore/svg/SVGColor.idl b/Source/WebCore/svg/SVGColor.idl
index d7af0e9..59bb630 100644
--- a/Source/WebCore/svg/SVGColor.idl
+++ b/Source/WebCore/svg/SVGColor.idl
@@ -22,25 +22,23 @@
module svg {
interface [Conditional=SVG] SVGColor : CSSValue {
- // Color Types
- const unsigned short SVG_COLORTYPE_UNKNOWN = 0;
- const unsigned short SVG_COLORTYPE_RGBCOLOR = 1;
+ const unsigned short SVG_COLORTYPE_UNKNOWN = 0;
+ const unsigned short SVG_COLORTYPE_RGBCOLOR = 1;
const unsigned short SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2;
- const unsigned short SVG_COLORTYPE_CURRENTCOLOR = 3;
+ const unsigned short SVG_COLORTYPE_CURRENTCOLOR = 3;
readonly attribute unsigned short colorType;
- readonly attribute RGBColor rgbColor;
- /*readonly attribute SVGICCColor iccColor;*/
+ readonly attribute RGBColor rgbColor;
+ // FIXME: readonly attribute SVGICCColor iccColor;
- void setRGBColor(in DOMString rgbColor)
- raises(SVGException);
- void setRGBColorICCColor(in DOMString rgbColor,
- in DOMString iccColor)
- raises(SVGException);
- void setColor(in unsigned short colorType,
- in DOMString rgbColor,
- in DOMString iccColor)
- raises(SVGException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setRGBColor(in DOMString rgbColor)
+ raises(DOMException, SVGException);
+
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setRGBColorICCColor(in DOMString rgbColor, in DOMString iccColor)
+ raises(DOMException, SVGException);
+
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setColor(in unsigned short colorType, in DOMString rgbColor, in DOMString iccColor)
+ raises(DOMException, SVGException);
};
}
diff --git a/Source/WebCore/svg/SVGCursorElement.cpp b/Source/WebCore/svg/SVGCursorElement.cpp
index c49f799..12b47c9 100644
--- a/Source/WebCore/svg/SVGCursorElement.cpp
+++ b/Source/WebCore/svg/SVGCursorElement.cpp
@@ -94,8 +94,11 @@ void SVGCursorElement::addClient(SVGElement* element)
void SVGCursorElement::removeClient(SVGElement* element)
{
- m_clients.remove(element);
- element->cursorElementRemoved();
+ HashSet<SVGElement*>::iterator it = m_clients.find(element);
+ if (it != m_clients.end()) {
+ m_clients.remove(it);
+ element->cursorElementRemoved();
+ }
}
void SVGCursorElement::removeReferencedElement(SVGElement* element)
diff --git a/Source/WebCore/svg/SVGDocumentExtensions.cpp b/Source/WebCore/svg/SVGDocumentExtensions.cpp
index 7f7ba67..e47fe96 100644
--- a/Source/WebCore/svg/SVGDocumentExtensions.cpp
+++ b/Source/WebCore/svg/SVGDocumentExtensions.cpp
@@ -32,6 +32,7 @@
#include "FrameLoader.h"
#include "Page.h"
#include "SMILTimeContainer.h"
+#include "SVGElement.h"
#include "SVGSMILElement.h"
#include "SVGSVGElement.h"
#include "ScriptController.h"
@@ -48,6 +49,7 @@ SVGDocumentExtensions::SVGDocumentExtensions(Document* document)
SVGDocumentExtensions::~SVGDocumentExtensions()
{
+ deleteAllValues(m_animatedElements);
deleteAllValues(m_pendingResources);
}
@@ -135,6 +137,56 @@ bool SVGDocumentExtensions::sampleAnimationAtTime(const String& elementId, SVGSM
#endif
}
+void SVGDocumentExtensions::addAnimationElementToTarget(SVGSMILElement* animationElement, SVGElement* targetElement)
+{
+ ASSERT(targetElement);
+ ASSERT(animationElement);
+
+ if (HashSet<SVGSMILElement*>* animationElementsForTarget = m_animatedElements.get(targetElement)) {
+ animationElementsForTarget->add(animationElement);
+ return;
+ }
+
+ HashSet<SVGSMILElement*>* animationElementsForTarget = new HashSet<SVGSMILElement*>;
+ animationElementsForTarget->add(animationElement);
+ m_animatedElements.set(targetElement, animationElementsForTarget);
+}
+
+void SVGDocumentExtensions::removeAnimationElementFromTarget(SVGSMILElement* animationElement, SVGElement* targetElement)
+{
+ ASSERT(targetElement);
+ ASSERT(animationElement);
+
+ HashMap<SVGElement*, HashSet<SVGSMILElement*>* >::iterator it = m_animatedElements.find(targetElement);
+ ASSERT(it != m_animatedElements.end());
+
+ HashSet<SVGSMILElement*>* animationElementsForTarget = it->second;
+ ASSERT(!animationElementsForTarget->isEmpty());
+
+ animationElementsForTarget->remove(animationElement);
+ if (animationElementsForTarget->isEmpty()) {
+ m_animatedElements.remove(it);
+ delete animationElementsForTarget;
+ }
+}
+
+void SVGDocumentExtensions::removeAllAnimationElementsFromTarget(SVGElement* targetElement)
+{
+ ASSERT(targetElement);
+ HashSet<SVGSMILElement*>* animationElementsForTarget = m_animatedElements.take(targetElement);
+ if (!animationElementsForTarget)
+ return;
+#if ENABLE(SVG_ANIMATION)
+ HashSet<SVGSMILElement*>::iterator it = animationElementsForTarget->begin();
+ HashSet<SVGSMILElement*>::iterator end = animationElementsForTarget->end();
+ for (; it != end; ++it)
+ (*it)->resetTargetElement();
+ delete animationElementsForTarget;
+#else
+ ASSERT_NOT_REACHED();
+#endif
+}
+
// FIXME: Callers should probably use ScriptController::eventHandlerLineNumber()
static int parserLineNumber(Document* document)
{
diff --git a/Source/WebCore/svg/SVGDocumentExtensions.h b/Source/WebCore/svg/SVGDocumentExtensions.h
index 0ed62a9..4e28b0d 100644
--- a/Source/WebCore/svg/SVGDocumentExtensions.h
+++ b/Source/WebCore/svg/SVGDocumentExtensions.h
@@ -34,6 +34,7 @@ namespace WebCore {
class Document;
class RenderSVGResourceContainer;
+class SVGElement;
class SVGStyledElement;
class SVGSMILElement;
class SVGSVGElement;
@@ -56,6 +57,10 @@ public:
void pauseAnimations();
void unpauseAnimations();
bool sampleAnimationAtTime(const String& elementId, SVGSMILElement*, double time);
+
+ void addAnimationElementToTarget(SVGSMILElement*, SVGElement*);
+ void removeAnimationElementFromTarget(SVGSMILElement*, SVGElement*);
+ void removeAllAnimationElementsFromTarget(SVGElement*);
void reportWarning(const String&);
void reportError(const String&);
@@ -65,6 +70,7 @@ public:
private:
Document* m_document; // weak reference
HashSet<SVGSVGElement*> m_timeContainers; // For SVG 1.2 support this will need to be made more general.
+ HashMap<SVGElement*, HashSet<SVGSMILElement*>* > m_animatedElements;
HashMap<AtomicString, RenderSVGResourceContainer*> m_resources;
HashMap<AtomicString, SVGPendingElements*> m_pendingResources;
OwnPtr<SVGResourcesCache> m_resourcesCache;
diff --git a/Source/WebCore/svg/SVGElement.cpp b/Source/WebCore/svg/SVGElement.cpp
index 99134b2..4630ccb 100644
--- a/Source/WebCore/svg/SVGElement.cpp
+++ b/Source/WebCore/svg/SVGElement.cpp
@@ -82,6 +82,7 @@ SVGElement::~SVGElement()
delete rareData;
rareDataMap.remove(it);
}
+ document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
}
SVGElementRareData* SVGElement::rareSVGData() const
@@ -117,6 +118,12 @@ void SVGElement::setXmlbase(const String& value, ExceptionCode&)
setAttribute(XMLNames::baseAttr, value);
}
+void SVGElement::removedFromDocument()
+{
+ document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
+ StyledElement::removedFromDocument();
+}
+
SVGSVGElement* SVGElement::ownerSVGElement() const
{
ContainerNode* n = parentOrHostNode();
@@ -371,6 +378,9 @@ void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls)
if (isSynchronizingSVGAttributes())
return;
+ if (isIdAttributeName(attr->name()))
+ document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
+
// Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods),
// so we don't want changes to the style attribute to result in extra work here.
if (attr->name() != HTMLNames::styleAttr)
diff --git a/Source/WebCore/svg/SVGElement.h b/Source/WebCore/svg/SVGElement.h
index ceb0973..380fa0e 100644
--- a/Source/WebCore/svg/SVGElement.h
+++ b/Source/WebCore/svg/SVGElement.h
@@ -118,6 +118,8 @@ protected:
virtual void insertedIntoDocument();
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
virtual bool childShouldCreateRenderer(Node*) const;
+
+ virtual void removedFromDocument();
SVGElementRareData* rareSVGData() const;
SVGElementRareData* ensureRareSVGData();
diff --git a/Source/WebCore/svg/SVGEllipseElement.cpp b/Source/WebCore/svg/SVGEllipseElement.cpp
index 129e1cd..73f921e 100644
--- a/Source/WebCore/svg/SVGEllipseElement.cpp
+++ b/Source/WebCore/svg/SVGEllipseElement.cpp
@@ -97,12 +97,6 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
diff --git a/Source/WebCore/svg/SVGFEBlendElement.cpp b/Source/WebCore/svg/SVGFEBlendElement.cpp
index b0f580c..ff2f197 100644
--- a/Source/WebCore/svg/SVGFEBlendElement.cpp
+++ b/Source/WebCore/svg/SVGFEBlendElement.cpp
@@ -68,12 +68,24 @@ void SVGFEBlendElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FEBlend* blend = static_cast<FEBlend*>(effect);
+ if (attrName == SVGNames::modeAttr)
+ return blend->setBlendMode(static_cast<BlendModeType>(mode()));
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
- if (attrName == SVGNames::modeAttr
- || attrName == SVGNames::inAttr
+ if (attrName == SVGNames::modeAttr)
+ primitiveAttributeChanged(attrName);
+
+ if (attrName == SVGNames::inAttr
|| attrName == SVGNames::in2Attr)
invalidate();
}
diff --git a/Source/WebCore/svg/SVGFEBlendElement.h b/Source/WebCore/svg/SVGFEBlendElement.h
index c579ac5..b429d4b 100644
--- a/Source/WebCore/svg/SVGFEBlendElement.h
+++ b/Source/WebCore/svg/SVGFEBlendElement.h
@@ -36,6 +36,7 @@ private:
SVGFEBlendElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp
index d3229d0..19acf0f 100644
--- a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp
+++ b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp
@@ -69,13 +69,26 @@ void SVGFEColorMatrixElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FEColorMatrix* colorMatrix = static_cast<FEColorMatrix*>(effect);
+ if (attrName == SVGNames::typeAttr)
+ return colorMatrix->setType(static_cast<ColorMatrixType>(type()));
+ if (attrName == SVGNames::valuesAttr)
+ return colorMatrix->setValues(values());
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
void SVGFEColorMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
if (attrName == SVGNames::typeAttr
- || attrName == SVGNames::inAttr
|| attrName == SVGNames::valuesAttr)
+ primitiveAttributeChanged(attrName);
+ if (attrName == SVGNames::inAttr)
invalidate();
}
diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.h b/Source/WebCore/svg/SVGFEColorMatrixElement.h
index 7bff011..ec7ea9b 100644
--- a/Source/WebCore/svg/SVGFEColorMatrixElement.h
+++ b/Source/WebCore/svg/SVGFEColorMatrixElement.h
@@ -37,6 +37,7 @@ private:
SVGFEColorMatrixElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
diff --git a/Source/WebCore/svg/SVGFECompositeElement.cpp b/Source/WebCore/svg/SVGFECompositeElement.cpp
index af738a9..1c40921 100644
--- a/Source/WebCore/svg/SVGFECompositeElement.cpp
+++ b/Source/WebCore/svg/SVGFECompositeElement.cpp
@@ -82,17 +82,38 @@ void SVGFECompositeElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FEComposite* composite = static_cast<FEComposite*>(effect);
+ if (attrName == SVGNames::operatorAttr)
+ return composite->setOperation(static_cast<CompositeOperationType>(_operator()));
+ if (attrName == SVGNames::k1Attr)
+ return composite->setK1(k1());
+ if (attrName == SVGNames::k2Attr)
+ return composite->setK2(k2());
+ if (attrName == SVGNames::k3Attr)
+ return composite->setK3(k3());
+ if (attrName == SVGNames::k4Attr)
+ return composite->setK4(k4());
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+
void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
- if (attrName == SVGNames::inAttr
- || attrName == SVGNames::in2Attr
- || attrName == SVGNames::operatorAttr
+ if (attrName == SVGNames::operatorAttr
|| attrName == SVGNames::k1Attr
|| attrName == SVGNames::k2Attr
|| attrName == SVGNames::k3Attr
|| attrName == SVGNames::k4Attr)
+ primitiveAttributeChanged(attrName);
+
+ if (attrName == SVGNames::inAttr
+ || attrName == SVGNames::in2Attr)
invalidate();
}
diff --git a/Source/WebCore/svg/SVGFECompositeElement.h b/Source/WebCore/svg/SVGFECompositeElement.h
index a4a9617..6557d0b 100644
--- a/Source/WebCore/svg/SVGFECompositeElement.h
+++ b/Source/WebCore/svg/SVGFECompositeElement.h
@@ -37,6 +37,7 @@ private:
SVGFECompositeElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp
index 07ebc41..4fa5e30 100644
--- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp
+++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp
@@ -128,6 +128,28 @@ void SVGFEConvolveMatrixElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFEConvolveMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FEConvolveMatrix* convolveMatrix = static_cast<FEConvolveMatrix*>(effect);
+ if (attrName == SVGNames::edgeModeAttr)
+ return convolveMatrix->setEdgeMode(static_cast<EdgeModeType>(edgeMode()));
+ if (attrName == SVGNames::divisorAttr)
+ return convolveMatrix->setDivisor(divisor());
+ if (attrName == SVGNames::biasAttr)
+ return convolveMatrix->setBias(bias());
+ if (attrName == SVGNames::targetXAttr)
+ return convolveMatrix->setTargetOffset(IntPoint(targetX(), targetY()));
+ if (attrName == SVGNames::targetYAttr)
+ return convolveMatrix->setTargetOffset(IntPoint(targetX(), targetY()));
+ if (attrName == SVGNames::kernelUnitLengthAttr)
+ return convolveMatrix->setKernelUnitLength(FloatPoint(kernelUnitLengthX(), kernelUnitLengthY()));
+ if (attrName == SVGNames::preserveAlphaAttr)
+ return convolveMatrix->setPreserveAlpha(preserveAlpha());
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
void SVGFEConvolveMatrixElement::setOrder(float x, float y)
{
setOrderXBaseValue(x);
@@ -146,16 +168,18 @@ void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrNa
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
- if (attrName == SVGNames::inAttr
- || attrName == SVGNames::orderAttr
- || attrName == SVGNames::edgeModeAttr
- || attrName == SVGNames::kernelMatrixAttr
+ if (attrName == SVGNames::edgeModeAttr
|| attrName == SVGNames::divisorAttr
|| attrName == SVGNames::biasAttr
|| attrName == SVGNames::targetXAttr
|| attrName == SVGNames::targetYAttr
|| attrName == SVGNames::kernelUnitLengthAttr
|| attrName == SVGNames::preserveAlphaAttr)
+ primitiveAttributeChanged(attrName);
+
+ if (attrName == SVGNames::inAttr
+ || attrName == SVGNames::orderAttr
+ || attrName == SVGNames::kernelMatrixAttr)
invalidate();
}
diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h
index ccc45ce..42f093d 100644
--- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h
+++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h
@@ -42,6 +42,7 @@ private:
SVGFEConvolveMatrixElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
virtual AttributeToPropertyTypeMap& attributeToPropertyTypeMap();
diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
index 1e86097..a4c2a6b 100644
--- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
+++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
@@ -97,7 +97,9 @@ bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect,
}
LightSource* lightSource = const_cast<LightSource*>(diffuseLighting->lightSource());
- const SVGFELightElement* lightElement = findLightElement();
+ const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
+ ASSERT(lightSource);
+ ASSERT(lightElement);
if (attrName == SVGNames::azimuthAttr)
return lightSource->setAzimuth(lightElement->azimuth());
@@ -140,7 +142,7 @@ void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrN
void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
{
- if (findLightElement() != lightElement)
+ if (SVGFELightElement::findLightElement(this) != lightElement)
return;
// The light element has different attribute names.
@@ -192,39 +194,23 @@ void SVGFEDiffuseLightingElement::fillAttributeToPropertyTypeMap()
PassRefPtr<FilterEffect> SVGFEDiffuseLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
FilterEffect* input1 = filterBuilder->getEffectById(in1());
-
+
if (!input1)
return 0;
-
+
+ RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this);
+ if (!lightSource)
+ return 0;
+
RefPtr<RenderStyle> filterStyle = styleForRenderer();
Color color = filterStyle->svgStyle()->lightingColor();
-
- RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(),
- kernelUnitLengthX(), kernelUnitLengthY(), findLight());
+
+ RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(),
+ kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release());
effect->inputEffects().append(input1);
return effect.release();
}
-SVGFELightElement* SVGFEDiffuseLightingElement::findLightElement() const
-{
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(SVGNames::feDistantLightTag)
- || node->hasTagName(SVGNames::fePointLightTag)
- || node->hasTagName(SVGNames::feSpotLightTag)) {
- return static_cast<SVGFELightElement*>(node);
- }
- }
- return 0;
-}
-
-PassRefPtr<LightSource> SVGFEDiffuseLightingElement::findLight() const
-{
- SVGFELightElement* lightNode = findLightElement();
- if (!lightNode)
- return 0;
- return lightNode->lightSource();
-}
-
}
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h
index 5f698c2..99dcfde 100644
--- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h
+++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h
@@ -56,9 +56,6 @@ private:
DECLARE_ANIMATED_NUMBER(SurfaceScale, surfaceScale)
DECLARE_ANIMATED_NUMBER(KernelUnitLengthX, kernelUnitLengthX)
DECLARE_ANIMATED_NUMBER(KernelUnitLengthY, kernelUnitLengthY)
-
- SVGFELightElement* findLightElement() const;
- PassRefPtr<LightSource> findLight() const;
};
} // namespace WebCore
diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp
index b5f2e32..873f85a 100644
--- a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp
+++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp
@@ -79,15 +79,31 @@ void SVGFEDisplacementMapElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect);
+ if (attrName == SVGNames::xChannelSelectorAttr)
+ return displacementMap->setXChannelSelector(static_cast<ChannelSelectorType>(xChannelSelector()));
+ if (attrName == SVGNames::yChannelSelectorAttr)
+ return displacementMap->setYChannelSelector(static_cast<ChannelSelectorType>(yChannelSelector()));
+ if (attrName == SVGNames::scaleAttr)
+ return displacementMap->setScale(scale());
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
if (attrName == SVGNames::xChannelSelectorAttr
|| attrName == SVGNames::yChannelSelectorAttr
- || attrName == SVGNames::inAttr
- || attrName == SVGNames::in2Attr
|| attrName == SVGNames::scaleAttr)
+ primitiveAttributeChanged(attrName);
+
+ if (attrName == SVGNames::inAttr
+ || attrName == SVGNames::in2Attr)
invalidate();
}
diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.h b/Source/WebCore/svg/SVGFEDisplacementMapElement.h
index c211de5..7aee539 100644
--- a/Source/WebCore/svg/SVGFEDisplacementMapElement.h
+++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.h
@@ -38,6 +38,7 @@ private:
SVGFEDisplacementMapElement(const QualifiedName& tagName, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
diff --git a/Source/WebCore/svg/SVGFELightElement.cpp b/Source/WebCore/svg/SVGFELightElement.cpp
index 58a2f26..110011f 100644
--- a/Source/WebCore/svg/SVGFELightElement.cpp
+++ b/Source/WebCore/svg/SVGFELightElement.cpp
@@ -28,6 +28,7 @@
#include "RenderObject.h"
#include "RenderSVGResource.h"
#include "SVGFEDiffuseLightingElement.h"
+#include "SVGFESpecularLightingElement.h"
#include "SVGFilterElement.h"
#include "SVGFilterPrimitiveStandardAttributes.h"
#include "SVGNames.h"
@@ -52,6 +53,26 @@ SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document* doc
{
}
+SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement* svgElement)
+{
+ for (Node* node = svgElement->firstChild(); node; node = node->nextSibling()) {
+ if (node->hasTagName(SVGNames::feDistantLightTag)
+ || node->hasTagName(SVGNames::fePointLightTag)
+ || node->hasTagName(SVGNames::feSpotLightTag)) {
+ return static_cast<SVGFELightElement*>(node);
+ }
+ }
+ return 0;
+}
+
+PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement)
+{
+ SVGFELightElement* lightNode = findLightElement(svgElement);
+ if (!lightNode)
+ return 0;
+ return lightNode->lightSource();
+}
+
void SVGFELightElement::parseMappedAttribute(Attribute* attr)
{
const String& value = attr->value();
@@ -105,9 +126,11 @@ void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
SVGFEDiffuseLightingElement* diffuseLighting = static_cast<SVGFEDiffuseLightingElement*>(parent);
diffuseLighting->lightElementAttributeChanged(this, attrName);
return;
+ } else if (parent->hasTagName(SVGNames::feSpecularLightingTag)) {
+ SVGFESpecularLightingElement* specularLighting = static_cast<SVGFESpecularLightingElement*>(parent);
+ specularLighting->lightElementAttributeChanged(this, attrName);
+ return;
}
- // Handler for SpecularLighting has not implemented yet.
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
}
diff --git a/Source/WebCore/svg/SVGFELightElement.h b/Source/WebCore/svg/SVGFELightElement.h
index 606a499..1e88a49 100644
--- a/Source/WebCore/svg/SVGFELightElement.h
+++ b/Source/WebCore/svg/SVGFELightElement.h
@@ -32,6 +32,8 @@ namespace WebCore {
class SVGFELightElement : public SVGElement {
public:
virtual PassRefPtr<LightSource> lightSource() const = 0;
+ static SVGFELightElement* findLightElement(const SVGElement*);
+ static PassRefPtr<LightSource> findLightSource(const SVGElement*);
protected:
SVGFELightElement(const QualifiedName&, Document*);
diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.cpp b/Source/WebCore/svg/SVGFEMorphologyElement.cpp
index 1a44e3c..2b02b6a 100644
--- a/Source/WebCore/svg/SVGFEMorphologyElement.cpp
+++ b/Source/WebCore/svg/SVGFEMorphologyElement.cpp
@@ -86,13 +86,27 @@ void SVGFEMorphologyElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FEMorphology* morphology = static_cast<FEMorphology*>(effect);
+ if (attrName == SVGNames::operatorAttr)
+ return morphology->setMorphologyOperator(static_cast<MorphologyOperatorType>(_operator()));
+ if (attrName == SVGNames::radiusAttr)
+ return (morphology->setRadiusX(radiusX()) || morphology->setRadiusY(radiusY()));
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
- if (attrName == SVGNames::inAttr
- || attrName == SVGNames::operatorAttr
+ if (attrName == SVGNames::operatorAttr
|| attrName == SVGNames::radiusAttr)
+ primitiveAttributeChanged(attrName);
+
+ if (attrName == SVGNames::inAttr)
invalidate();
}
diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.h b/Source/WebCore/svg/SVGFEMorphologyElement.h
index 931288f..d7c1c16 100644
--- a/Source/WebCore/svg/SVGFEMorphologyElement.h
+++ b/Source/WebCore/svg/SVGFEMorphologyElement.h
@@ -38,6 +38,7 @@ private:
SVGFEMorphologyElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
diff --git a/Source/WebCore/svg/SVGFESpecularLightingElement.cpp b/Source/WebCore/svg/SVGFESpecularLightingElement.cpp
index f4f2648..60684ed 100644
--- a/Source/WebCore/svg/SVGFESpecularLightingElement.cpp
+++ b/Source/WebCore/svg/SVGFESpecularLightingElement.cpp
@@ -89,18 +89,69 @@ void SVGFESpecularLightingElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FESpecularLighting* specularLighting = static_cast<FESpecularLighting*>(effect);
+ if (attrName == SVGNames::surfaceScaleAttr)
+ return specularLighting->setSurfaceScale(surfaceScale());
+ if (attrName == SVGNames::specularConstantAttr)
+ return specularLighting->setSpecularConstant(specularConstant());
+ if (attrName == SVGNames::specularExponentAttr)
+ return specularLighting->setSpecularExponent(specularExponent());
+
+ LightSource* lightSource = const_cast<LightSource*>(specularLighting->lightSource());
+ const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
+ ASSERT(lightSource);
+ ASSERT(lightElement);
+
+ if (attrName == SVGNames::azimuthAttr)
+ return lightSource->setAzimuth(lightElement->azimuth());
+ if (attrName == SVGNames::elevationAttr)
+ return lightSource->setElevation(lightElement->elevation());
+ if (attrName == SVGNames::xAttr)
+ return lightSource->setX(lightElement->x());
+ if (attrName == SVGNames::yAttr)
+ return lightSource->setY(lightElement->y());
+ if (attrName == SVGNames::zAttr)
+ return lightSource->setZ(lightElement->z());
+ if (attrName == SVGNames::pointsAtXAttr)
+ return lightSource->setPointsAtX(lightElement->pointsAtX());
+ if (attrName == SVGNames::pointsAtYAttr)
+ return lightSource->setPointsAtY(lightElement->pointsAtY());
+ if (attrName == SVGNames::pointsAtZAttr)
+ return lightSource->setPointsAtZ(lightElement->pointsAtZ());
+ if (attrName == SVGNames::specularExponentAttr)
+ return lightSource->setSpecularExponent(lightElement->specularExponent());
+ if (attrName == SVGNames::limitingConeAngleAttr)
+ return lightSource->setLimitingConeAngle(lightElement->limitingConeAngle());
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
void SVGFESpecularLightingElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
- if (attrName == SVGNames::inAttr
- || attrName == SVGNames::surfaceScaleAttr
+ if (attrName == SVGNames::surfaceScaleAttr
|| attrName == SVGNames::specularConstantAttr
|| attrName == SVGNames::specularExponentAttr
|| attrName == SVGNames::kernelUnitLengthAttr)
+ primitiveAttributeChanged(attrName);
+
+ if (attrName == SVGNames::inAttr)
invalidate();
}
+void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
+{
+ if (SVGFELightElement::findLightElement(this) != lightElement)
+ return;
+
+ // The light element has different attribute names so attrName can identify the requested attribute.
+ primitiveAttributeChanged(attrName);
+}
+
void SVGFESpecularLightingElement::synchronizeProperty(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
@@ -147,33 +198,23 @@ void SVGFESpecularLightingElement::fillAttributeToPropertyTypeMap()
attributeToPropertyTypeMap.set(SVGNames::kernelUnitLengthAttr, AnimatedNumberOptionalNumber);
}
-PassRefPtr<LightSource> SVGFESpecularLightingElement::findLights() const
-{
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(SVGNames::feDistantLightTag)
- || node->hasTagName(SVGNames::fePointLightTag)
- || node->hasTagName(SVGNames::feSpotLightTag)) {
- SVGFELightElement* lightNode = static_cast<SVGFELightElement*>(node);
- return lightNode->lightSource();
- }
- }
-
- return 0;
-}
-
PassRefPtr<FilterEffect> SVGFESpecularLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
FilterEffect* input1 = filterBuilder->getEffectById(in1());
-
+
if (!input1)
return 0;
-
- RefPtr<RenderStyle> filterStyle = styleForRenderer();
-
+
+ RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this);
+ if (!lightSource)
+ return 0;
+
+ RefPtr<RenderStyle> filterStyle = styleForRenderer();
+
Color color = filterStyle->svgStyle()->lightingColor();
- RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(),
- specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), findLights());
+ RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(),
+ specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release());
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/Source/WebCore/svg/SVGFESpecularLightingElement.h b/Source/WebCore/svg/SVGFESpecularLightingElement.h
index 9914123..cfceb44 100644
--- a/Source/WebCore/svg/SVGFESpecularLightingElement.h
+++ b/Source/WebCore/svg/SVGFESpecularLightingElement.h
@@ -25,6 +25,7 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "FESpecularLighting.h"
#include "SVGAnimatedNumber.h"
+#include "SVGFELightElement.h"
#include "SVGFilterPrimitiveStandardAttributes.h"
namespace WebCore {
@@ -32,11 +33,13 @@ namespace WebCore {
class SVGFESpecularLightingElement : public SVGFilterPrimitiveStandardAttributes {
public:
static PassRefPtr<SVGFESpecularLightingElement> create(const QualifiedName&, Document*);
+ void lightElementAttributeChanged(const SVGFELightElement*, const QualifiedName&);
private:
SVGFESpecularLightingElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
@@ -53,8 +56,6 @@ private:
DECLARE_ANIMATED_NUMBER(SurfaceScale, surfaceScale)
DECLARE_ANIMATED_NUMBER(KernelUnitLengthX, kernelUnitLengthX)
DECLARE_ANIMATED_NUMBER(KernelUnitLengthY, kernelUnitLengthY)
-
- PassRefPtr<LightSource> findLights() const;
};
} // namespace WebCore
diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.cpp b/Source/WebCore/svg/SVGFETurbulenceElement.cpp
index 2eaf1fc..285b669 100644
--- a/Source/WebCore/svg/SVGFETurbulenceElement.cpp
+++ b/Source/WebCore/svg/SVGFETurbulenceElement.cpp
@@ -89,16 +89,34 @@ void SVGFETurbulenceElement::parseMappedAttribute(Attribute* attr)
SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
}
+bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
+{
+ FETurbulence* turbulence = static_cast<FETurbulence*>(effect);
+ if (attrName == SVGNames::typeAttr)
+ return turbulence->setType(static_cast<TurbulenceType>(type()));
+ if (attrName == SVGNames::stitchTilesAttr)
+ return turbulence->setStitchTiles(stitchTiles());
+ if (attrName == SVGNames::baseFrequencyAttr)
+ return (turbulence->setBaseFrequencyX(baseFrequencyX()) || turbulence->setBaseFrequencyY(baseFrequencyY()));
+ if (attrName == SVGNames::seedAttr)
+ return turbulence->setSeed(seed());
+ if (attrName == SVGNames::numOctavesAttr)
+ return turbulence->setNumOctaves(numOctaves());
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName)
{
SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
-
+
if (attrName == SVGNames::baseFrequencyAttr
|| attrName == SVGNames::numOctavesAttr
|| attrName == SVGNames::seedAttr
|| attrName == SVGNames::stitchTilesAttr
|| attrName == SVGNames::typeAttr)
- invalidate();
+ primitiveAttributeChanged(attrName);
}
void SVGFETurbulenceElement::synchronizeProperty(const QualifiedName& attrName)
@@ -151,7 +169,7 @@ PassRefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*, Filter
if (baseFrequencyX() < 0 || baseFrequencyY() < 0)
return 0;
- return FETurbulence::create(filter, static_cast<TurbulanceType>(type()), baseFrequencyX(),
+ return FETurbulence::create(filter, static_cast<TurbulenceType>(type()), baseFrequencyX(),
baseFrequencyY(), numOctaves(), seed(), stitchTiles() == SVG_STITCHTYPE_STITCH);
}
diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.h b/Source/WebCore/svg/SVGFETurbulenceElement.h
index 5e8a8b6..a2cd4f5 100644
--- a/Source/WebCore/svg/SVGFETurbulenceElement.h
+++ b/Source/WebCore/svg/SVGFETurbulenceElement.h
@@ -44,6 +44,7 @@ private:
SVGFETurbulenceElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
virtual void fillAttributeToPropertyTypeMap();
diff --git a/Source/WebCore/svg/SVGFilterElement.cpp b/Source/WebCore/svg/SVGFilterElement.cpp
index 539d4df..a3b5e7c 100644
--- a/Source/WebCore/svg/SVGFilterElement.cpp
+++ b/Source/WebCore/svg/SVGFilterElement.cpp
@@ -214,7 +214,7 @@ void SVGFilterElement::fillAttributeToPropertyTypeMap()
attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength);
attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength);
attributeToPropertyTypeMap.set(SVGNames::filterResAttr, AnimatedNumberOptionalNumber);
- attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedEnumeration);
+ attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString);
}
void SVGFilterElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
diff --git a/Source/WebCore/svg/SVGFont.cpp b/Source/WebCore/svg/SVGFont.cpp
index a92b9b6..e02fced 100644
--- a/Source/WebCore/svg/SVGFont.cpp
+++ b/Source/WebCore/svg/SVGFont.cpp
@@ -362,7 +362,7 @@ static void floatWidthMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerM
Font font(fontDescription, 0, 0); // spacing handled by SVG text code.
font.update(data.font->fontSelector());
- data.length += font.floatWidth(run);
+ data.length += font.width(run);
}
@@ -573,9 +573,9 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,
font.drawText(context, fallbackCharacterRun, currentPoint);
if (isVerticalText)
- currentPoint.move(0.0f, font.floatWidth(fallbackCharacterRun));
+ currentPoint.move(0.0f, font.width(fallbackCharacterRun));
else
- currentPoint.move(font.floatWidth(fallbackCharacterRun), 0.0f);
+ currentPoint.move(font.width(fallbackCharacterRun), 0.0f);
fallbackCharacterIndex++;
}
diff --git a/Source/WebCore/svg/SVGForeignObjectElement.cpp b/Source/WebCore/svg/SVGForeignObjectElement.cpp
index f2175ac..7c48bf2 100644
--- a/Source/WebCore/svg/SVGForeignObjectElement.cpp
+++ b/Source/WebCore/svg/SVGForeignObjectElement.cpp
@@ -96,12 +96,6 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (isLengthAttribute
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
diff --git a/Source/WebCore/svg/SVGGElement.cpp b/Source/WebCore/svg/SVGGElement.cpp
index 233aa74..f7a48ec 100644
--- a/Source/WebCore/svg/SVGGElement.cpp
+++ b/Source/WebCore/svg/SVGGElement.cpp
@@ -66,12 +66,6 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
@@ -93,6 +87,17 @@ void SVGGElement::synchronizeProperty(const QualifiedName& attrName)
SVGTests::synchronizeProperties(this, attrName);
}
+AttributeToPropertyTypeMap& SVGGElement::attributeToPropertyTypeMap()
+{
+ DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
+ return s_attributeToPropertyTypeMap;
+}
+
+void SVGGElement::fillAttributeToPropertyTypeMap()
+{
+ SVGStyledTransformableElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap());
+}
+
RenderObject* SVGGElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
// SVG 1.1 testsuite explicitely uses constructs like <g display="none"><linearGradient>
diff --git a/Source/WebCore/svg/SVGGElement.h b/Source/WebCore/svg/SVGGElement.h
index 3c00b34..c306f4a 100644
--- a/Source/WebCore/svg/SVGGElement.h
+++ b/Source/WebCore/svg/SVGGElement.h
@@ -50,6 +50,8 @@ private:
virtual void parseMappedAttribute(Attribute*);
virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
+ virtual void fillAttributeToPropertyTypeMap();
+ virtual AttributeToPropertyTypeMap& attributeToPropertyTypeMap();
virtual bool rendererIsNeeded(RenderStyle*);
diff --git a/Source/WebCore/svg/SVGHKernElement.cpp b/Source/WebCore/svg/SVGHKernElement.cpp
index 4632378..df92d34 100644
--- a/Source/WebCore/svg/SVGHKernElement.cpp
+++ b/Source/WebCore/svg/SVGHKernElement.cpp
@@ -52,6 +52,7 @@ void SVGHKernElement::insertedIntoDocument()
if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
element->invalidateGlyphCache();
}
+ SVGElement::insertedIntoDocument();
}
void SVGHKernElement::removedFromDocument()
@@ -61,6 +62,7 @@ void SVGHKernElement::removedFromDocument()
if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
element->invalidateGlyphCache();
}
+ SVGElement::removedFromDocument();
}
void SVGHKernElement::buildHorizontalKerningPair(KerningPairVector& kerningPairs)
diff --git a/Source/WebCore/svg/SVGImageElement.cpp b/Source/WebCore/svg/SVGImageElement.cpp
index 784c1ab..21bb392 100644
--- a/Source/WebCore/svg/SVGImageElement.cpp
+++ b/Source/WebCore/svg/SVGImageElement.cpp
@@ -112,12 +112,6 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (isLengthAttribute) {
renderer->updateFromElement();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
diff --git a/Source/WebCore/svg/SVGImageLoader.cpp b/Source/WebCore/svg/SVGImageLoader.cpp
index 17e9004..7c60191 100644
--- a/Source/WebCore/svg/SVGImageLoader.cpp
+++ b/Source/WebCore/svg/SVGImageLoader.cpp
@@ -49,7 +49,7 @@ void SVGImageLoader::dispatchLoadEvent()
String SVGImageLoader::sourceURI(const AtomicString& attr) const
{
- return KURL(element()->baseURI(), stripLeadingAndTrailingHTMLSpaces(attr)).string();
+ return element()->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attr));
}
}
diff --git a/Source/WebCore/svg/SVGLineElement.cpp b/Source/WebCore/svg/SVGLineElement.cpp
index 2e435c5..c3d5f0b 100644
--- a/Source/WebCore/svg/SVGLineElement.cpp
+++ b/Source/WebCore/svg/SVGLineElement.cpp
@@ -93,12 +93,6 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
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;
}
}
diff --git a/Source/WebCore/svg/SVGPaint.h b/Source/WebCore/svg/SVGPaint.h
index 9b66295..5cacf91 100644
--- a/Source/WebCore/svg/SVGPaint.h
+++ b/Source/WebCore/svg/SVGPaint.h
@@ -2,6 +2,7 @@
* Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmial.com>
+ * Copyright (C) Research In Motion Limited 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
@@ -21,9 +22,10 @@
#ifndef SVGPaint_h
#define SVGPaint_h
+
#if ENABLE(SVG)
-#include "PlatformString.h"
#include "SVGColor.h"
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -42,49 +44,63 @@ public:
SVG_PAINTTYPE_URI = 107
};
- static PassRefPtr<SVGPaint> create()
+ static PassRefPtr<SVGPaint> createUnknown()
{
- return adoptRef(new SVGPaint);
+ return adoptRef(new SVGPaint(SVG_PAINTTYPE_UNKNOWN));
}
- static PassRefPtr<SVGPaint> create(SVGPaintType type)
+
+ static PassRefPtr<SVGPaint> createNone()
{
- return adoptRef(new SVGPaint(type));
+ return adoptRef(new SVGPaint(SVG_PAINTTYPE_NONE));
}
- static PassRefPtr<SVGPaint> create(const Color& color)
+
+ static PassRefPtr<SVGPaint> createCurrentColor()
{
- return adoptRef(new SVGPaint(color));
+ return adoptRef(new SVGPaint(SVG_PAINTTYPE_CURRENTCOLOR));
}
- static PassRefPtr<SVGPaint> create(SVGPaintType type, const String& uri)
+
+ static PassRefPtr<SVGPaint> createColor(const Color& color)
+ {
+ RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_RGBCOLOR));
+ paint->setColor(color);
+ return paint.release();
+ }
+
+ static PassRefPtr<SVGPaint> createURI(const String& uri)
{
- return adoptRef(new SVGPaint(type, uri, String(), String()));
+ RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_URI, uri));
+ return paint.release();
}
- static PassRefPtr<SVGPaint> create(const String& uri, const Color& color)
+
+ static PassRefPtr<SVGPaint> createURIAndColor(const String& uri, const Color& color)
{
- return adoptRef(new SVGPaint(uri, color));
+ RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_URI_RGBCOLOR, uri));
+ paint->setColor(color);
+ return paint.release();
}
- // 'SVGPaint' functions
- SVGPaintType paintType() const { return m_paintType; }
- String uri() const;
+ const SVGPaintType& paintType() const { return m_paintType; }
+ String uri() const { return m_uri; }
void setUri(const String&);
- void setPaint(SVGPaintType, const String& uri, const String& rgbPaint, const String& iccPaint, ExceptionCode&);
-
- static SVGPaint* defaultFill();
- static SVGPaint* defaultStroke();
+ void setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionCode&);
bool matchesTargetURI(const String& referenceId);
private:
- SVGPaint();
- SVGPaint(const String& uri);
- SVGPaint(SVGPaintType);
- SVGPaint(SVGPaintType, const String& uri, const String& rgbPaint, const String& iccPaint);
- SVGPaint(const Color& c);
- SVGPaint(const String& uri, const Color& c);
+ friend class CSSComputedStyleDeclaration;
- virtual bool isSVGPaint() const { return true; }
+ static PassRefPtr<SVGPaint> create(const SVGPaintType& type, const String& uri, const Color& color)
+ {
+ RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(type, uri));
+ paint->setColor(color);
+ return paint.release();
+ }
+private:
+ SVGPaint(const SVGPaintType&, String uri = String());
+
+ virtual bool isSVGPaint() const { return true; }
virtual String cssText() const;
SVGPaintType m_paintType;
diff --git a/Source/WebCore/svg/SVGPaint.idl b/Source/WebCore/svg/SVGPaint.idl
index 426b762..b87fd34 100644
--- a/Source/WebCore/svg/SVGPaint.idl
+++ b/Source/WebCore/svg/SVGPaint.idl
@@ -26,27 +26,23 @@
module svg {
interface [Conditional=SVG] SVGPaint : SVGColor {
- // SVGPaintType
- const unsigned short SVG_PAINTTYPE_UNKNOWN = 0;
- const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1;
- const unsigned short SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2;
- const unsigned short SVG_PAINTTYPE_NONE = 101;
- const unsigned short SVG_PAINTTYPE_CURRENTCOLOR = 102;
- const unsigned short SVG_PAINTTYPE_URI_NONE = 103;
- const unsigned short SVG_PAINTTYPE_URI_CURRENTCOLOR = 104;
- const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR = 105;
+ const unsigned short SVG_PAINTTYPE_UNKNOWN = 0;
+ const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1;
+ const unsigned short SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2;
+ const unsigned short SVG_PAINTTYPE_NONE = 101;
+ const unsigned short SVG_PAINTTYPE_CURRENTCOLOR = 102;
+ const unsigned short SVG_PAINTTYPE_URI_NONE = 103;
+ const unsigned short SVG_PAINTTYPE_URI_CURRENTCOLOR = 104;
+ const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR = 105;
const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106;
- const unsigned short SVG_PAINTTYPE_URI = 107;
+ const unsigned short SVG_PAINTTYPE_URI = 107;
- readonly attribute SVGPaintType paintType;
+ readonly attribute unsigned short paintType;
readonly attribute DOMString uri;
- void setUri(in DOMString uri);
- void setPaint(in SVGPaintType paintType,
- in DOMString uri,
- in DOMString rgbColor,
- in DOMString iccColor)
- raises(SVGException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setUri(in DOMString uri);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setPaint(in unsigned short paintType, in DOMString uri, in DOMString rgbColor, in DOMString iccColor)
+ raises(DOMException, SVGException);
};
}
diff --git a/Source/WebCore/svg/SVGPathElement.cpp b/Source/WebCore/svg/SVGPathElement.cpp
index c56873b..e798eaf 100644
--- a/Source/WebCore/svg/SVGPathElement.cpp
+++ b/Source/WebCore/svg/SVGPathElement.cpp
@@ -230,12 +230,6 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (attrName == SVGNames::pathLengthAttr
|| SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
diff --git a/Source/WebCore/svg/SVGPolyElement.cpp b/Source/WebCore/svg/SVGPolyElement.cpp
index 8a70347..331e5ec 100644
--- a/Source/WebCore/svg/SVGPolyElement.cpp
+++ b/Source/WebCore/svg/SVGPolyElement.cpp
@@ -76,12 +76,6 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (attrName == SVGNames::pointsAttr) {
renderer->setNeedsPathUpdate();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
diff --git a/Source/WebCore/svg/SVGPreserveAspectRatio.cpp b/Source/WebCore/svg/SVGPreserveAspectRatio.cpp
index 3f1172d..2ebcc1f 100644
--- a/Source/WebCore/svg/SVGPreserveAspectRatio.cpp
+++ b/Source/WebCore/svg/SVGPreserveAspectRatio.cpp
@@ -247,15 +247,14 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe
}
}
-// FIXME: We should use floats here, like everywhere else!
-AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY, double logicWidth, double logicHeight, double physWidth, double physHeight) const
+AffineTransform SVGPreserveAspectRatio::getCTM(float logicX, float logicY, float logicWidth, float logicHeight, float physWidth, float physHeight) const
{
AffineTransform transform;
if (m_align == SVG_PRESERVEASPECTRATIO_UNKNOWN)
return transform;
- double logicalRatio = logicWidth / logicHeight;
- double physRatio = physWidth / physHeight;
+ float logicalRatio = logicWidth / logicHeight;
+ float physRatio = physWidth / physHeight;
if (m_align == SVG_PRESERVEASPECTRATIO_NONE) {
transform.scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight);
diff --git a/Source/WebCore/svg/SVGPreserveAspectRatio.h b/Source/WebCore/svg/SVGPreserveAspectRatio.h
index bf00ee4..bdee15c 100644
--- a/Source/WebCore/svg/SVGPreserveAspectRatio.h
+++ b/Source/WebCore/svg/SVGPreserveAspectRatio.h
@@ -62,9 +62,9 @@ public:
void transformRect(FloatRect& destRect, FloatRect& srcRect);
- AffineTransform getCTM(double logicX, double logicY,
- double logicWidth, double logicHeight,
- double physWidth, double physHeight) const;
+ AffineTransform getCTM(float logicX, float logicY,
+ float logicWidth, float logicHeight,
+ float physWidth, float physHeight) const;
template<class Consumer>
static bool parsePreserveAspectRatio(Consumer* consumer, const String& value, bool validate = true)
diff --git a/Source/WebCore/svg/SVGRectElement.cpp b/Source/WebCore/svg/SVGRectElement.cpp
index 10c5743..2c6ee87 100644
--- a/Source/WebCore/svg/SVGRectElement.cpp
+++ b/Source/WebCore/svg/SVGRectElement.cpp
@@ -110,12 +110,6 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- renderer->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
if (isLengthAttribute) {
renderer->setNeedsPathUpdate();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
diff --git a/Source/WebCore/svg/SVGSVGElement.cpp b/Source/WebCore/svg/SVGSVGElement.cpp
index e2540e3..0778bb7 100644
--- a/Source/WebCore/svg/SVGSVGElement.cpp
+++ b/Source/WebCore/svg/SVGSVGElement.cpp
@@ -129,20 +129,12 @@ void SVGSVGElement::setContentStyleType(const AtomicString& type)
FloatRect SVGSVGElement::viewport() const
{
- double x = 0;
- double y = 0;
- if (!isOutermostSVG()) {
- x = this->x().value(this);
- y = this->y().value(this);
- }
- float w = width().value(this);
- float h = height().value(this);
- AffineTransform viewBox = viewBoxToViewTransform(w, h);
- double wDouble = w;
- double hDouble = h;
- viewBox.map(x, y, x, y);
- viewBox.map(w, h, wDouble, hDouble);
- return FloatRect::narrowPrecision(x, y, wDouble, hDouble);
+ FloatRect viewRectangle;
+ if (!isOutermostSVG())
+ viewRectangle.setLocation(FloatPoint(x().value(this), y().value(this)));
+
+ viewRectangle.setSize(FloatSize(width().value(this), height().value(this)));
+ return viewBoxToViewTransform(viewRectangle.width(), viewRectangle.height()).mapRect(viewRectangle);
}
int SVGSVGElement::relativeWidthValue() const
diff --git a/Source/WebCore/svg/SVGScriptElement.cpp b/Source/WebCore/svg/SVGScriptElement.cpp
index babb1e7..00b85a5 100644
--- a/Source/WebCore/svg/SVGScriptElement.cpp
+++ b/Source/WebCore/svg/SVGScriptElement.cpp
@@ -35,9 +35,9 @@ namespace WebCore {
DEFINE_ANIMATED_STRING(SVGScriptElement, XLinkNames::hrefAttr, Href, href)
DEFINE_ANIMATED_BOOLEAN(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool wasAlreadyStarted)
+inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool alreadyStarted)
: SVGElement(tagName, document)
- , ScriptElement(this, wasInsertedByParser, wasAlreadyStarted)
+ , ScriptElement(this, wasInsertedByParser, alreadyStarted)
{
}
@@ -72,7 +72,7 @@ void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
// Handle dynamic updates of the 'externalResourcesRequired' attribute. Only possible case: changing from 'true' to 'false'
// causes an immediate dispatch of the SVGLoad event. If the attribute value was 'false' before inserting the script element
// in the document, the SVGLoad event has already been dispatched.
- if (!externalResourcesRequiredBaseValue() && !haveFiredLoadEvent() && !wasInsertedByParser()) {
+ if (!externalResourcesRequiredBaseValue() && !haveFiredLoadEvent() && !isParserInserted()) {
setHaveFiredLoadEvent(true);
ASSERT(haveLoadedRequiredResources());
@@ -111,9 +111,9 @@ void SVGScriptElement::fillAttributeToPropertyTypeMap()
void SVGScriptElement::insertedIntoDocument()
{
SVGElement::insertedIntoDocument();
- ScriptElement::insertedIntoDocument(sourceAttributeValue());
+ ScriptElement::insertedIntoDocument();
- if (wasInsertedByParser())
+ if (isParserInserted())
return;
// Eventually send SVGLoad event now for the dynamically inserted script element
@@ -142,7 +142,6 @@ bool SVGScriptElement::isURLAttribute(Attribute* attr) const
void SVGScriptElement::finishParsingChildren()
{
- ScriptElement::finishParsingChildren(sourceAttributeValue());
SVGElement::finishParsingChildren();
// A SVGLoad event has been fired by SVGElement::finishParsingChildren.
@@ -212,11 +211,16 @@ bool SVGScriptElement::deferAttributeValue() const
return false;
}
+bool SVGScriptElement::hasSourceAttribute() const
+{
+ return hasAttribute(XLinkNames::hrefAttr);
+}
+
void SVGScriptElement::dispatchLoadEvent()
{
bool externalResourcesRequired = externalResourcesRequiredBaseValue();
- if (wasInsertedByParser())
+ if (isParserInserted())
ASSERT(externalResourcesRequired != haveFiredLoadEvent());
else if (haveFiredLoadEvent()) {
// If we've already fired an load event and externalResourcesRequired is set to 'true'
@@ -247,7 +251,7 @@ void SVGScriptElement::dispatchErrorEvent()
PassRefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren() const
{
- return adoptRef(new SVGScriptElement(tagQName(), document(), false, wasAlreadyStarted()));
+ return adoptRef(new SVGScriptElement(tagQName(), document(), false, alreadyStarted()));
}
}
diff --git a/Source/WebCore/svg/SVGScriptElement.h b/Source/WebCore/svg/SVGScriptElement.h
index dabec79..03cc733 100644
--- a/Source/WebCore/svg/SVGScriptElement.h
+++ b/Source/WebCore/svg/SVGScriptElement.h
@@ -42,7 +42,7 @@ public:
void setType(const String&);
private:
- SVGScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool wasAlreadyStarted);
+ SVGScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool alreadyStarted);
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
@@ -68,6 +68,7 @@ private:
virtual String eventAttributeValue() const;
virtual bool asyncAttributeValue() const;
virtual bool deferAttributeValue() const;
+ virtual bool hasSourceAttribute() const;
virtual void dispatchLoadEvent();
virtual void dispatchErrorEvent();
diff --git a/Source/WebCore/svg/SVGStyledElement.cpp b/Source/WebCore/svg/SVGStyledElement.cpp
index 7f3b041..5740b05 100644
--- a/Source/WebCore/svg/SVGStyledElement.cpp
+++ b/Source/WebCore/svg/SVGStyledElement.cpp
@@ -273,6 +273,11 @@ AnimatedAttributeType SVGStyledElement::animatedPropertyTypeForCSSProperty(const
return AnimatedUnknown;
}
+bool SVGStyledElement::isAnimatableCSSProperty(const QualifiedName& attrName)
+{
+ return cssPropertyToTypeMap().contains(attrName);
+}
+
void SVGStyledElement::fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap& attributeToPropertyTypeMap)
{
attributeToPropertyTypeMap.set(HTMLNames::classAttr, AnimatedString);
diff --git a/Source/WebCore/svg/SVGStyledElement.h b/Source/WebCore/svg/SVGStyledElement.h
index 85a2b5a..b6c0b96 100644
--- a/Source/WebCore/svg/SVGStyledElement.h
+++ b/Source/WebCore/svg/SVGStyledElement.h
@@ -53,6 +53,7 @@ public:
void setInstanceUpdatesBlocked(bool);
AnimatedAttributeType animatedPropertyTypeForCSSProperty(const QualifiedName&);
+ static bool isAnimatableCSSProperty(const QualifiedName&);
virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const;
diff --git a/Source/WebCore/svg/SVGStyledTransformableElement.cpp b/Source/WebCore/svg/SVGStyledTransformableElement.cpp
index ce1c5fd..1e32f9a 100644
--- a/Source/WebCore/svg/SVGStyledTransformableElement.cpp
+++ b/Source/WebCore/svg/SVGStyledTransformableElement.cpp
@@ -26,6 +26,7 @@
#include "AffineTransform.h"
#include "Attribute.h"
#include "RenderSVGPath.h"
+#include "RenderSVGResource.h"
#include "SVGNames.h"
namespace WebCore {
@@ -80,6 +81,21 @@ void SVGStyledTransformableElement::parseMappedAttribute(Attribute* attr)
SVGStyledLocatableElement::parseMappedAttribute(attr);
}
+void SVGStyledTransformableElement::svgAttributeChanged(const QualifiedName& attrName)
+{
+ SVGStyledLocatableElement::svgAttributeChanged(attrName);
+
+ if (!SVGStyledTransformableElement::isKnownAttribute(attrName))
+ return;
+
+ RenderObject* object = renderer();
+ if (!object)
+ return;
+
+ object->setNeedsTransformUpdate();
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
+}
+
void SVGStyledTransformableElement::synchronizeProperty(const QualifiedName& attrName)
{
SVGStyledLocatableElement::synchronizeProperty(attrName);
diff --git a/Source/WebCore/svg/SVGStyledTransformableElement.h b/Source/WebCore/svg/SVGStyledTransformableElement.h
index cbd70ed..9d6834a 100644
--- a/Source/WebCore/svg/SVGStyledTransformableElement.h
+++ b/Source/WebCore/svg/SVGStyledTransformableElement.h
@@ -58,6 +58,7 @@ protected:
SVGStyledTransformableElement(const QualifiedName&, Document*);
virtual void parseMappedAttribute(Attribute*);
+ virtual void svgAttributeChanged(const QualifiedName&);
virtual void synchronizeProperty(const QualifiedName&);
void fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap&);
diff --git a/Source/WebCore/svg/SVGTextContentElement.cpp b/Source/WebCore/svg/SVGTextContentElement.cpp
index 0bb8b3b..a719c28 100644
--- a/Source/WebCore/svg/SVGTextContentElement.cpp
+++ b/Source/WebCore/svg/SVGTextContentElement.cpp
@@ -145,7 +145,7 @@ void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, E
return;
// Find selection start
- VisiblePosition start(const_cast<SVGTextContentElement*>(this), 0, SEL_DEFAULT_AFFINITY);
+ VisiblePosition start(firstPositionInNode(const_cast<SVGTextContentElement*>(this)));
for (unsigned i = 0; i < charnum; ++i)
start = start.next();
diff --git a/Source/WebCore/svg/SVGTransformable.cpp b/Source/WebCore/svg/SVGTransformable.cpp
index e637e7c..a3107d1 100644
--- a/Source/WebCore/svg/SVGTransformable.cpp
+++ b/Source/WebCore/svg/SVGTransformable.cpp
@@ -89,6 +89,11 @@ static int parseTransformParamList(const UChar*& ptr, const UChar* end, float* v
static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1};
static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0};
+// This destructor is needed in order to link correctly with Intel ICC.
+SVGTransformable::~SVGTransformable()
+{
+}
+
bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& transform)
{
if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN)
diff --git a/Source/WebCore/svg/SVGTransformable.h b/Source/WebCore/svg/SVGTransformable.h
index 1cd2881..c713366 100644
--- a/Source/WebCore/svg/SVGTransformable.h
+++ b/Source/WebCore/svg/SVGTransformable.h
@@ -40,6 +40,8 @@ public:
DoNotClearList
};
+ virtual ~SVGTransformable();
+
static bool parseTransformAttribute(SVGTransformList&, const AtomicString& transform);
static bool parseTransformAttribute(SVGTransformList&, const UChar*& ptr, const UChar* end, TransformParsingMode mode = ClearList);
static bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform&);
diff --git a/Source/WebCore/svg/SVGUseElement.cpp b/Source/WebCore/svg/SVGUseElement.cpp
index cc53bda..4239f66 100644
--- a/Source/WebCore/svg/SVGUseElement.cpp
+++ b/Source/WebCore/svg/SVGUseElement.cpp
@@ -185,12 +185,6 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (SVGStyledTransformableElement::isKnownAttribute(attrName)) {
- object->setNeedsTransformUpdate();
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
- return;
- }
-
if (SVGLangSpace::isKnownAttribute(attrName)
|| SVGExternalResourcesRequired::isKnownAttribute(attrName))
invalidateShadowTree();
@@ -242,7 +236,7 @@ void SVGUseElement::fillAttributeToPropertyTypeMap()
attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedLength);
attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength);
attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength);
- attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedLength);
+ attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString);
}
static void updateContainerSize(SVGUseElement* useElement, SVGElementInstance* targetInstance)
diff --git a/Source/WebCore/svg/SVGVKernElement.cpp b/Source/WebCore/svg/SVGVKernElement.cpp
index eed13d2..498a28f 100644
--- a/Source/WebCore/svg/SVGVKernElement.cpp
+++ b/Source/WebCore/svg/SVGVKernElement.cpp
@@ -50,6 +50,7 @@ void SVGVKernElement::insertedIntoDocument()
if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
element->invalidateGlyphCache();
}
+ SVGElement::insertedIntoDocument();
}
void SVGVKernElement::removedFromDocument()
@@ -59,6 +60,7 @@ void SVGVKernElement::removedFromDocument()
if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode))
element->invalidateGlyphCache();
}
+ SVGElement::removedFromDocument();
}
void SVGVKernElement::buildVerticalKerningPair(KerningPairVector& kerningPairs)
diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.cpp b/Source/WebCore/svg/animation/SMILTimeContainer.cpp
index 3251d5b..0bacdb3 100644
--- a/Source/WebCore/svg/animation/SMILTimeContainer.cpp
+++ b/Source/WebCore/svg/animation/SMILTimeContainer.cpp
@@ -196,15 +196,15 @@ String SMILTimeContainer::baseValueFor(ElementAttributePair key)
if (it != m_savedBaseValues.end())
return it->second;
- SVGElement* target = key.first;
- String attributeName = key.second;
- ASSERT(target);
- ASSERT(!attributeName.isEmpty());
+ SVGElement* targetElement = key.first;
+ QualifiedName attributeName = key.second;
+ ASSERT(targetElement);
+ ASSERT(attributeName != anyQName());
String baseValue;
- if (SVGAnimationElement::attributeIsCSS(attributeName))
- baseValue = computedStyle(target)->getPropertyValue(cssPropertyID(attributeName));
+ if (SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName))
+ baseValue = computedStyle(targetElement)->getPropertyValue(cssPropertyID(attributeName.localName()));
else
- baseValue = target->getAttribute(attributeName);
+ baseValue = targetElement->getAttribute(attributeName);
m_savedBaseValues.add(key, baseValue);
return baseValue;
}
@@ -264,10 +264,11 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed)
SVGElement* targetElement = animation->targetElement();
if (!targetElement)
continue;
- String attributeName = animation->attributeName();
- if (attributeName.isEmpty()) {
+
+ QualifiedName attributeName = animation->attributeName();
+ if (attributeName == anyQName()) {
if (animation->hasTagName(SVGNames::animateMotionTag))
- attributeName = SVGNames::animateMotionTag.localName();
+ attributeName = SVGNames::animateMotionTag;
else
continue;
}
@@ -276,6 +277,8 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed)
ElementAttributePair key(targetElement, attributeName);
SVGSMILElement* resultElement = resultsElements.get(key).get();
if (!resultElement) {
+ if (!animation->hasValidAttributeType())
+ continue;
resultElement = animation;
resultElement->resetToBaseValue(baseValueFor(key));
resultsElements.add(key, resultElement);
diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.h b/Source/WebCore/svg/animation/SMILTimeContainer.h
index bf734d3..2b46ff3 100644
--- a/Source/WebCore/svg/animation/SMILTimeContainer.h
+++ b/Source/WebCore/svg/animation/SMILTimeContainer.h
@@ -28,6 +28,7 @@
#if ENABLE(SVG)
+#include "QualifiedName.h"
#include "PlatformString.h"
#include "SMILTime.h"
#include "Timer.h"
@@ -74,7 +75,7 @@ private:
void updateDocumentOrderIndexes();
void sortByPriority(Vector<SVGSMILElement*>& smilElements, SMILTime elapsed);
- typedef pair<SVGElement*, String> ElementAttributePair;
+ typedef pair<SVGElement*, QualifiedName> ElementAttributePair;
String baseValueFor(ElementAttributePair);
double m_beginTime;
diff --git a/Source/WebCore/svg/animation/SVGSMILElement.cpp b/Source/WebCore/svg/animation/SVGSMILElement.cpp
index 2364c6a..3bb5880 100644
--- a/Source/WebCore/svg/animation/SVGSMILElement.cpp
+++ b/Source/WebCore/svg/animation/SVGSMILElement.cpp
@@ -37,12 +37,12 @@
#include "FrameView.h"
#include "HTMLNames.h"
#include "SMILTimeContainer.h"
+#include "SVGDocumentExtensions.h"
#include "SVGNames.h"
#include "SVGParserUtilities.h"
#include "SVGSVGElement.h"
#include "SVGURIReference.h"
#include "XLinkNames.h"
-#include <math.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
@@ -115,6 +115,8 @@ SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str
SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document* doc)
: SVGElement(tagName, doc)
+ , m_attributeName(anyQName())
+ , m_targetElement(0)
, m_conditionsConnected(false)
, m_hasEndEventConditions(false)
, m_intervalBegin(SMILTime::unresolved())
@@ -140,6 +142,28 @@ SVGSMILElement::~SVGSMILElement()
if (m_timeContainer)
m_timeContainer->unschedule(this);
}
+
+static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const String& attributeName)
+{
+ ASSERT(svgElement);
+ if (attributeName.isEmpty())
+ return anyQName();
+ if (!attributeName.contains(':'))
+ return QualifiedName(nullAtom, attributeName, nullAtom);
+
+ String prefix;
+ String localName;
+ ExceptionCode ec = 0;
+ if (!Document::parseQualifiedName(attributeName, prefix, localName, ec))
+ return anyQName();
+ ASSERT(!ec);
+
+ String namespaceURI = svgElement->lookupNamespaceURI(prefix);
+ if (namespaceURI.isEmpty())
+ return anyQName();
+
+ return QualifiedName(nullAtom, localName, namespaceURI);
+}
void SVGSMILElement::insertedIntoDocument()
{
@@ -149,6 +173,7 @@ void SVGSMILElement::insertedIntoDocument()
for (ContainerNode* n = this; n; n = n->parentNode())
ASSERT(!n->isShadowRoot());
#endif
+ m_attributeName = constructQualifiedName(this, getAttribute(SVGNames::attributeNameAttr));
SVGSVGElement* owner = ownerSVGElement();
if (!owner)
return;
@@ -160,10 +185,15 @@ void SVGSMILElement::insertedIntoDocument()
void SVGSMILElement::removedFromDocument()
{
+ m_attributeName = anyQName();
if (m_timeContainer) {
m_timeContainer->unschedule(this);
m_timeContainer = 0;
}
+ if (m_targetElement) {
+ document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_targetElement);
+ m_targetElement = 0;
+ }
// Calling disconnectConditions() may kill us if there are syncbase conditions.
// OK, but we don't want to die inside the call.
RefPtr<SVGSMILElement> keepAlive(this);
@@ -380,7 +410,11 @@ void SVGSMILElement::attributeChanged(Attribute* attr, bool preserveDecls)
m_cachedMin = invalidCachedTime;
else if (attrName == SVGNames::maxAttr)
m_cachedMax = invalidCachedTime;
-
+ else if (attrName == SVGNames::attributeNameAttr) {
+ if (inDocument())
+ m_attributeName = constructQualifiedName(this, attr->value());
+ }
+
if (inDocument()) {
if (attrName == SVGNames::beginAttr)
beginListChanged();
@@ -461,18 +495,19 @@ void SVGSMILElement::reschedule()
SVGElement* SVGSMILElement::targetElement() const
{
+ if (m_targetElement)
+ return m_targetElement;
+
String href = xlinkHref();
ContainerNode* target = href.isEmpty() ? parentNode() : document()->getElementById(SVGURIReference::getTarget(href));
- if (target && target->isSVGElement())
- return static_cast<SVGElement*>(target);
- return 0;
-}
+ if (!target || !target->isSVGElement())
+ return 0;
-String SVGSMILElement::attributeName() const
-{
- return getAttribute(SVGNames::attributeNameAttr).string().stripWhiteSpace();
+ m_targetElement = static_cast<SVGElement*>(target);
+ document()->accessSVGExtensions()->addAnimationElementToTarget(const_cast<SVGSMILElement*>(this), m_targetElement);
+ return m_targetElement;
}
-
+
SMILTime SVGSMILElement::elapsed() const
{
return m_timeContainer ? m_timeContainer->elapsed() : 0;
diff --git a/Source/WebCore/svg/animation/SVGSMILElement.h b/Source/WebCore/svg/animation/SVGSMILElement.h
index 2135642..0f26f26 100644
--- a/Source/WebCore/svg/animation/SVGSMILElement.h
+++ b/Source/WebCore/svg/animation/SVGSMILElement.h
@@ -49,11 +49,14 @@ public:
virtual void insertedIntoDocument();
virtual void removedFromDocument();
virtual void finishParsingChildren();
+
+ virtual bool hasValidAttributeType() const = 0;
SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
SVGElement* targetElement() const;
- String attributeName() const;
+ void resetTargetElement() { m_targetElement = 0; }
+ const QualifiedName& attributeName() const { return m_attributeName; }
void beginByLinkActivation();
@@ -175,10 +178,14 @@ private:
Frozen
};
+ QualifiedName m_attributeName;
+
ActiveState determineActiveState(SMILTime elapsed) const;
float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
SMILTime calculateNextProgressTime(SMILTime elapsed) const;
+ mutable SVGElement* m_targetElement;
+
Vector<Condition> m_conditions;
bool m_conditionsConnected;
bool m_hasEndEventConditions;
diff --git a/Source/WebCore/svg/graphics/SVGImage.cpp b/Source/WebCore/svg/graphics/SVGImage.cpp
index 2d400a4..85c00f3 100644
--- a/Source/WebCore/svg/graphics/SVGImage.cpp
+++ b/Source/WebCore/svg/graphics/SVGImage.cpp
@@ -263,8 +263,11 @@ bool SVGImage::dataChanged(bool allDataReceived)
#endif
// FIXME: If this SVG ends up loading itself, we might leak the world.
- // The comment said that the Cache code does not know about CachedImages
- // holding Frames and won't know to break the cycle. But
+ // The Cache code does not know about CachedImages holding Frames and
+ // won't know to break the cycle.
+ // This will become an issue when SVGImage will be able to load other
+ // SVGImage objects, but we're safe now, because SVGImage can only be
+ // loaded by a top-level document.
m_page.set(new Page(pageClients));
m_page->settings()->setMediaEnabled(false);
m_page->settings()->setJavaScriptEnabled(false);
@@ -273,12 +276,9 @@ bool SVGImage::dataChanged(bool allDataReceived)
RefPtr<Frame> frame = Frame::create(m_page.get(), 0, dummyFrameLoaderClient);
frame->setView(FrameView::create(frame.get()));
frame->init();
- ResourceRequest fakeRequest(KURL(ParsedURLString, ""));
FrameLoader* loader = frame->loader();
loader->setForcedSandboxFlags(SandboxAll);
- loader->load(fakeRequest, false); // Make sure the DocumentLoader is created
- loader->policyChecker()->cancelCheck(); // cancel any policy checks
- loader->commitProvisionalLoad();
+ ASSERT(loader->activeDocumentLoader()); // DocumentLoader should have been created by frame->init().
loader->activeDocumentLoader()->writer()->setMIMEType("image/svg+xml");
loader->activeDocumentLoader()->writer()->begin(KURL()); // create the empty document
loader->activeDocumentLoader()->writer()->addData(data()->data(), data()->size());