Refactor to/from/animatedType creation, to share more code between animators
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2012 11:57:39 +0000 (11:57 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Apr 2012 11:57:39 +0000 (11:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=84846

Reviewed by Antti Koivisto.

Source/WebCore:

Share more code bewteen animators, doesn't change functionality yet, except for one bug in SVGAnimatedString.
SVGAnimatedString used to mutate the from/to values during animation, leading to problems in animate-element-31-t.svg.
It now needs a rebaseline, now that this bug is fixed as side-effect.

* svg/SVGAnimateColorElement.cpp:
(WebCore::attributeValueIsCurrentColor):
(WebCore::SVGAnimateColorElement::determinePropertyValueTypes):
(WebCore):
* svg/SVGAnimateColorElement.h:
(SVGAnimateColorElement):
* svg/SVGAnimateElement.cpp:
(WebCore::SVGAnimateElement::SVGAnimateElement):
* svg/SVGAnimateElement.h:
(SVGAnimateElement):
* svg/SVGAnimatedAngle.cpp:
(WebCore::SVGAnimatedAngleAnimator::calculateAnimatedValue):
* svg/SVGAnimatedBoolean.cpp:
(WebCore::SVGAnimatedBooleanAnimator::calculateAnimatedValue):
* svg/SVGAnimatedColor.cpp:
(WebCore::adjustForCurrentColor):
(WebCore):
(WebCore::parseColorFromString):
(WebCore::SVGAnimatedColorAnimator::calculateAnimatedValue):
* svg/SVGAnimatedEnumeration.cpp:
(WebCore::SVGAnimatedEnumerationAnimator::calculateAnimatedValue):
* svg/SVGAnimatedInteger.cpp:
(WebCore::SVGAnimatedIntegerAnimator::calculateAnimatedInteger):
(WebCore::SVGAnimatedIntegerAnimator::calculateAnimatedValue):
* svg/SVGAnimatedIntegerOptionalInteger.cpp:
(WebCore::SVGAnimatedIntegerOptionalIntegerAnimator::calculateAnimatedValue):
* svg/SVGAnimatedLength.cpp:
(WebCore::parseLengthFromString):
(WebCore):
(WebCore::SVGAnimatedLengthAnimator::calculateAnimatedValue):
* svg/SVGAnimatedLengthList.cpp:
(WebCore::parseLengthListFromString):
(WebCore):
(WebCore::SVGAnimatedLengthListAnimator::calculateAnimatedValue):
* svg/SVGAnimatedNumber.cpp:
(WebCore::parseNumberFromString):
(WebCore):
(WebCore::SVGAnimatedNumberAnimator::calculateAnimatedValue):
* svg/SVGAnimatedNumberList.cpp:
(WebCore::SVGAnimatedNumberListAnimator::calculateAnimatedValue):
* svg/SVGAnimatedNumberOptionalNumber.cpp:
(WebCore::SVGAnimatedNumberOptionalNumberAnimator::calculateAnimatedValue):
* svg/SVGAnimatedPointList.cpp:
(WebCore::SVGAnimatedPointListAnimator::calculateAnimatedValue):
* svg/SVGAnimatedPreserveAspectRatio.cpp:
(WebCore::SVGAnimatedPreserveAspectRatioAnimator::calculateAnimatedValue):
* svg/SVGAnimatedRect.cpp:
(WebCore::SVGAnimatedRectAnimator::calculateAnimatedValue):
* svg/SVGAnimatedString.cpp:
(WebCore::parseStringFromString):
(WebCore):
(WebCore::SVGAnimatedStringAnimator::calculateAnimatedValue):
* svg/SVGAnimatedTransformList.cpp:
(WebCore::SVGAnimatedTransformListAnimator::calculateAnimatedValue):
* svg/SVGAnimationElement.cpp:
(WebCore::SVGAnimationElement::SVGAnimationElement):
(WebCore::SVGAnimationElement::adjustForInheritance):
(WebCore):
(WebCore::inheritsFromProperty):
(WebCore::SVGAnimationElement::determinePropertyValueTypes):
* svg/SVGAnimationElement.h:
(WebCore::SVGAnimationElement::fromPropertyValueType):
(WebCore::SVGAnimationElement::toPropertyValueType):
(SVGAnimationElement):
(WebCore::SVGAnimationElement::adjustForInheritance):
(WebCore::SVGAnimationElement::adjustFromToValues):
(WebCore::SVGAnimationElement::adjustFromToListValues):

LayoutTests:

Rebaseline one test result, which shows a progression.
(At the initial time when we capture the result, only two circles should be visible.)

* platform/chromium/test_expectations.txt:
* platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.png:
* platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.txt:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@115187 268f45cc-cd09-0410-ab3c-d52691b4dbfc

27 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.png
LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/svg/SVGAnimateColorElement.cpp
Source/WebCore/svg/SVGAnimateColorElement.h
Source/WebCore/svg/SVGAnimateElement.cpp
Source/WebCore/svg/SVGAnimateElement.h
Source/WebCore/svg/SVGAnimatedAngle.cpp
Source/WebCore/svg/SVGAnimatedBoolean.cpp
Source/WebCore/svg/SVGAnimatedColor.cpp
Source/WebCore/svg/SVGAnimatedEnumeration.cpp
Source/WebCore/svg/SVGAnimatedInteger.cpp
Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.cpp
Source/WebCore/svg/SVGAnimatedLength.cpp
Source/WebCore/svg/SVGAnimatedLengthList.cpp
Source/WebCore/svg/SVGAnimatedNumber.cpp
Source/WebCore/svg/SVGAnimatedNumberList.cpp
Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.cpp
Source/WebCore/svg/SVGAnimatedPointList.cpp
Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.cpp
Source/WebCore/svg/SVGAnimatedRect.cpp
Source/WebCore/svg/SVGAnimatedString.cpp
Source/WebCore/svg/SVGAnimatedTransformList.cpp
Source/WebCore/svg/SVGAnimationElement.cpp
Source/WebCore/svg/SVGAnimationElement.h

index 4b1da8a..60f4c95 100644 (file)
@@ -1,3 +1,17 @@
+2012-04-25  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Refactor to/from/animatedType creation, to share more code between animators
+        https://bugs.webkit.org/show_bug.cgi?id=84846
+
+        Reviewed by Antti Koivisto.
+
+        Rebaseline one test result, which shows a progression.
+        (At the initial time when we capture the result, only two circles should be visible.)
+
+        * platform/chromium/test_expectations.txt:
+        * platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.png:
+        * platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.txt:
+
 2012-04-25  Mikhail Naganov  <mnaganov@chromium.org>
 
         [Chromium] Unreviewed test expectations update
index 603fcc4..6f67f92 100644 (file)
@@ -1150,6 +1150,9 @@ BUGCR62433 WIN : fast/images/gif-loop-count.html = IMAGE
 // SVG TESTS
 // -----------------------------------------------------------------
 
+// Needs a rebaseline, only two circles should be visible now.
+BUGWK84846 : svg/W3C-SVG-1.1/animate-elem-31-t.svg = IMAGE+TEXT IMAGE TEXT PASS
+
 // New in WebKit r52559
 BUGCR18116 : svg/custom/global-constructors.html = TEXT
 
index 78a8fa6..217df56 100644 (file)
Binary files a/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.png and b/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-31-t-expected.png differ
index 49239fa..307c609 100644 (file)
@@ -19,8 +19,7 @@ layer at (0,0) size 480x360
         RenderSVGHiddenContainer {g} at (0,0) size 0x0
           RenderSVGEllipse {circle} at (236,11) size 68x68 [stroke={[type=SOLID] [color=#000000] [stroke width=5.00]}] [fill={[type=SOLID] [color=#FFFF00]}] [cx=180.00] [cy=30.00] [r=20.00]
       RenderSVGEllipse {circle} at (236,116) size 68x68 [stroke={[type=SOLID] [color=#000000] [stroke width=5.00]}] [fill={[type=SOLID] [color=#FFFF00]}] [cx=180.00] [cy=100.00] [r=20.00]
-      RenderSVGContainer {g} at (311,11) size 68x68
-        RenderSVGEllipse {circle} at (311,11) size 68x68 [stroke={[type=SOLID] [color=#000000] [stroke width=5.00]}] [fill={[type=SOLID] [color=#00FFFF]}] [cx=230.00] [cy=30.00] [r=20.00]
+      RenderSVGContainer {g} at (0,0) size 0x0
       RenderSVGContainer {g} at (311,116) size 68x68
         RenderSVGEllipse {circle} at (311,116) size 68x68 [stroke={[type=SOLID] [color=#000000] [stroke width=5.00]}] [fill={[type=SOLID] [color=#00FFFF]}] [cx=230.00] [cy=100.00] [r=20.00]
     RenderSVGText {text} at (385,26) size 45x18 contains 1 chunk(s)
index 4dbb5ea..464a3b2 100644 (file)
@@ -1,5 +1,84 @@
 2012-04-25  Nikolas Zimmermann  <nzimmermann@rim.com>
 
+        Refactor to/from/animatedType creation, to share more code between animators
+        https://bugs.webkit.org/show_bug.cgi?id=84846
+
+        Reviewed by Antti Koivisto.
+
+        Share more code bewteen animators, doesn't change functionality yet, except for one bug in SVGAnimatedString.
+        SVGAnimatedString used to mutate the from/to values during animation, leading to problems in animate-element-31-t.svg.
+        It now needs a rebaseline, now that this bug is fixed as side-effect.
+
+        * svg/SVGAnimateColorElement.cpp:
+        (WebCore::attributeValueIsCurrentColor):
+        (WebCore::SVGAnimateColorElement::determinePropertyValueTypes):
+        (WebCore):
+        * svg/SVGAnimateColorElement.h:
+        (SVGAnimateColorElement):
+        * svg/SVGAnimateElement.cpp:
+        (WebCore::SVGAnimateElement::SVGAnimateElement):
+        * svg/SVGAnimateElement.h:
+        (SVGAnimateElement):
+        * svg/SVGAnimatedAngle.cpp:
+        (WebCore::SVGAnimatedAngleAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedBoolean.cpp:
+        (WebCore::SVGAnimatedBooleanAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedColor.cpp:
+        (WebCore::adjustForCurrentColor):
+        (WebCore):
+        (WebCore::parseColorFromString):
+        (WebCore::SVGAnimatedColorAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedEnumeration.cpp:
+        (WebCore::SVGAnimatedEnumerationAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedInteger.cpp:
+        (WebCore::SVGAnimatedIntegerAnimator::calculateAnimatedInteger):
+        (WebCore::SVGAnimatedIntegerAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedIntegerOptionalInteger.cpp:
+        (WebCore::SVGAnimatedIntegerOptionalIntegerAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedLength.cpp:
+        (WebCore::parseLengthFromString):
+        (WebCore):
+        (WebCore::SVGAnimatedLengthAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedLengthList.cpp:
+        (WebCore::parseLengthListFromString):
+        (WebCore):
+        (WebCore::SVGAnimatedLengthListAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedNumber.cpp:
+        (WebCore::parseNumberFromString):
+        (WebCore):
+        (WebCore::SVGAnimatedNumberAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedNumberList.cpp:
+        (WebCore::SVGAnimatedNumberListAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedNumberOptionalNumber.cpp:
+        (WebCore::SVGAnimatedNumberOptionalNumberAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedPointList.cpp:
+        (WebCore::SVGAnimatedPointListAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedPreserveAspectRatio.cpp:
+        (WebCore::SVGAnimatedPreserveAspectRatioAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedRect.cpp:
+        (WebCore::SVGAnimatedRectAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedString.cpp:
+        (WebCore::parseStringFromString):
+        (WebCore):
+        (WebCore::SVGAnimatedStringAnimator::calculateAnimatedValue):
+        * svg/SVGAnimatedTransformList.cpp:
+        (WebCore::SVGAnimatedTransformListAnimator::calculateAnimatedValue):
+        * svg/SVGAnimationElement.cpp:
+        (WebCore::SVGAnimationElement::SVGAnimationElement):
+        (WebCore::SVGAnimationElement::adjustForInheritance):
+        (WebCore):
+        (WebCore::inheritsFromProperty):
+        (WebCore::SVGAnimationElement::determinePropertyValueTypes):
+        * svg/SVGAnimationElement.h:
+        (WebCore::SVGAnimationElement::fromPropertyValueType):
+        (WebCore::SVGAnimationElement::toPropertyValueType):
+        (SVGAnimationElement):
+        (WebCore::SVGAnimationElement::adjustForInheritance):
+        (WebCore::SVGAnimationElement::adjustFromToValues):
+        (WebCore::SVGAnimationElement::adjustFromToListValues):
+
+2012-04-25  Nikolas Zimmermann  <nzimmermann@rim.com>
+
         Share single calculateFromToValues/calculateFromByValues between all SVGAnimatedTypeAnimators
         https://bugs.webkit.org/show_bug.cgi?id=84832
 
index 4d0ef82..ddaa10e 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "config.h"
+
 #if ENABLE(SVG)
 #include "SVGAnimateColorElement.h"
 #include "SVGNames.h"
@@ -37,8 +38,21 @@ PassRefPtr<SVGAnimateColorElement> SVGAnimateColorElement::create(const Qualifie
     return adoptRef(new SVGAnimateColorElement(tagName, document));
 }
 
+static bool attributeValueIsCurrentColor(const String& value)
+{
+    DEFINE_STATIC_LOCAL(const AtomicString, currentColor, ("currentColor"));
+    return value == currentColor;
 }
 
-// vim:ts=4:noet
-#endif // ENABLE(SVG)
+void SVGAnimateColorElement::determinePropertyValueTypes(const String& from, const String& to)
+{
+    SVGAnimateElement::determinePropertyValueTypes(from, to);
+    if (attributeValueIsCurrentColor(from))
+        m_fromPropertyValueType = CurrentColorValue;
+    if (attributeValueIsCurrentColor(to))
+        m_toPropertyValueType = CurrentColorValue;
+}
+
+}
 
+#endif // ENABLE(SVG)
index 2860a67..3b029c5 100644 (file)
 
 #ifndef SVGAnimateColorElement_h
 #define SVGAnimateColorElement_h
-#if ENABLE(SVG)
 
+#if ENABLE(SVG)
 #include "SVGAnimateElement.h"
 
 namespace WebCore {
 
-// SVGAnimateElement implements superset of the functionality.
 class SVGAnimateColorElement : public SVGAnimateElement {
 public:
     static PassRefPtr<SVGAnimateColorElement> create(const QualifiedName&, Document*);
 
 private:
     SVGAnimateColorElement(const QualifiedName&, Document*);
+    virtual void determinePropertyValueTypes(const String& from, const String& to);
 };
 
 } // namespace WebCore
 
 #endif // ENABLE(SVG)
 #endif // SVGAnimateColorElement_h
-
-// vim:ts=4:noet
index d85b40f..4c4d7d3 100644 (file)
@@ -39,8 +39,6 @@ namespace WebCore {
 SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document* document)
     : SVGAnimationElement(tagName, document)
     , m_animatedPropertyType(AnimatedString)
-    , m_fromPropertyValueType(RegularPropertyValue)
-    , m_toPropertyValueType(RegularPropertyValue)
 {
     ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateColorTag) || hasTagName(SVGNames::animateTransformTag));
 }
@@ -54,53 +52,6 @@ SVGAnimateElement::~SVGAnimateElement()
 {
 }
 
-static inline void getPropertyValue(SVGElement* svgParent, const QualifiedName& attributeName, String& value)
-{
-    ASSERT(svgParent->isStyled());
-    value = CSSComputedStyleDeclaration::create(svgParent)->getPropertyValue(cssPropertyID(attributeName.localName()));
-}
-
-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;
-}
-
-void SVGAnimateElement::adjustForCurrentColor(SVGElement* targetElement, Color& color)
-{
-    ASSERT(targetElement);
-
-    if (RenderObject* targetRenderer = targetElement->renderer())
-        color = targetRenderer->style()->visitedDependentColor(CSSPropertyColor);
-    else
-        color = Color();
-}
-
-void SVGAnimateElement::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())
-        getPropertyValue(svgParent, attributeName, value);
-}
-
 bool SVGAnimateElement::hasValidAttributeType()
 {
     SVGElement* targetElement = this->targetElement();
@@ -142,25 +93,6 @@ AnimatedPropertyType SVGAnimateElement::determineAnimatedPropertyType(SVGElement
     return type;
 }
 
-void SVGAnimateElement::determinePropertyValueTypes(const String& from, const String& to)
-{
-    SVGElement* targetElement = this->targetElement();
-    ASSERT(targetElement);
-
-    if (inheritsFromProperty(targetElement, attributeName(), from))
-        m_fromPropertyValueType = InheritValue;
-    if (inheritsFromProperty(targetElement, attributeName(), to))
-        m_toPropertyValueType = InheritValue;
-
-    if (m_animatedPropertyType != AnimatedColor)
-        return;
-    
-    if (attributeValueIsCurrentColor(from))
-        m_fromPropertyValueType = CurrentColorValue;
-    if (attributeValueIsCurrentColor(to))
-        m_toPropertyValueType = CurrentColorValue;
-}
-
 void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement)
 {
     ASSERT(resultElement);
index 2489b73..447b550 100644 (file)
@@ -24,7 +24,6 @@
 #define SVGAnimateElement_h
 
 #if ENABLE(SVG)
-
 #include "SVGAnimatedType.h"
 #include "SVGAnimatedTypeAnimator.h"
 #include "SVGAnimationElement.h"
 
 namespace WebCore {
     
-// 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
-};
-
 class SVGAnimatedProperty;
 
 class SVGAnimateElement : public SVGAnimationElement {
 public:
     static PassRefPtr<SVGAnimateElement> create(const QualifiedName&, Document*);
-
     virtual ~SVGAnimateElement();
 
-    static void adjustForCurrentColor(SVGElement* targetElement, Color&);
-    void adjustForInheritance(SVGElement* targetElement, const QualifiedName&, String& value);
-    
     AnimatedPropertyType determineAnimatedPropertyType(SVGElement*) const;
-    void determinePropertyValueTypes(const String&, const String&);
     
-    AnimatedPropertyValueType fromPropertyValueType() { return m_fromPropertyValueType; }
-    AnimatedPropertyValueType toPropertyValueType() { return m_toPropertyValueType; }
-
 protected:
     SVGAnimateElement(const QualifiedName&, Document*);
 
@@ -75,9 +58,6 @@ private:
     virtual bool hasValidAttributeType();
     AnimatedPropertyType m_animatedPropertyType;
 
-    AnimatedPropertyValueType m_fromPropertyValueType;
-    AnimatedPropertyValueType m_toPropertyValueType;
-
     OwnPtr<SVGAnimatedType> m_fromType;
     OwnPtr<SVGAnimatedType> m_toType;
     OwnPtr<SVGAnimatedType> m_animatedType;
index f848124..5b72b84 100644 (file)
@@ -94,22 +94,16 @@ void SVGAnimatedAngleAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimat
     toAngle.setValue(toAngle.value() + fromAngle.value());
 }
 
-void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                      OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
     
-    AnimationMode animationMode = animationElement->animationMode();
-
-    // To animation uses contributions from the lower priority animations as the base value.
-    pair<SVGAngle, unsigned>& animatedAngleAndEnumeration = animated->angleAndEnumeration();
     pair<SVGAngle, unsigned>& fromAngleAndEnumeration = from->angleAndEnumeration();
-    if (animationMode == ToAnimation)
-        fromAngleAndEnumeration.first = animatedAngleAndEnumeration.first;
-
     pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
+    pair<SVGAngle, unsigned>& animatedAngleAndEnumeration = animated->angleAndEnumeration();
+    m_animationElement->adjustFromToValues<pair<SVGAngle, unsigned> >(0, fromAngleAndEnumeration, toAngleAndEnumeration, animatedAngleAndEnumeration, percentage, m_contextElement);
+
     if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second) {
         // Animating from eg. auto to 90deg, or auto to 90deg.
         if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) {
@@ -152,28 +146,17 @@ void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned
 
     float fromAngle = fromAngleAndEnumeration.first.value();
     float toAngle = toAngleAndEnumeration.first.value();
-    
-    if (animationElement->fromPropertyValueType() == InheritValue) {
-        String fromAngleString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromAngleString);
-        fromAngle = sharedSVGAngle(fromAngleString).value();
-    }
-    if (animationElement->toPropertyValueType() == InheritValue) {
-        String toAngleString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toAngleString);
-        toAngle = sharedSVGAngle(toAngleString).value(); 
-    }
-    
-    if (animationElement->calcMode() == CalcModeDiscrete)
+
+    if (m_animationElement->calcMode() == CalcModeDiscrete)
         number = percentage < 0.5f ? fromAngle : toAngle;
     else
         number = (toAngle - fromAngle) * percentage + fromAngle;
     
     // FIXME: This is not correct for values animation.
-    if (animationElement->isAccumulated() && repeatCount)
+    if (m_animationElement->isAccumulated() && repeatCount)
         number += toAngle * repeatCount;
     SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first;
-    if (animationElement->isAdditive() && animationMode != ToAnimation) {
+    if (m_animationElement->isAdditive() && m_animationElement->animationMode() != ToAnimation) {
         float animatedSVGAngleValue = animatedSVGAngle.value();
         animatedSVGAngleValue += number;
         animatedSVGAngle.setValue(animatedSVGAngleValue);
index 5139ace..58fcf1e 100644 (file)
@@ -70,19 +70,21 @@ void SVGAnimatedBooleanAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnim
     ASSERT_UNUSED(to, from->type() == to->type());
 }
 
-void SVGAnimatedBooleanAnimator::calculateAnimatedValue(float percentage, unsigned,
-                                                        OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedBooleanAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    
-    AnimationMode animationMode = animationElement->animationMode();
-    bool& animateString = animated->boolean();
+
+    bool& fromBoolean = from->boolean();
+    bool& toBoolean = to->boolean();
+    bool& animatedBoolean = animated->boolean();
+    m_animationElement->adjustFromToValues<bool>(0, fromBoolean, toBoolean, animatedBoolean, percentage, m_contextElement);
+
+    AnimationMode animationMode = m_animationElement->animationMode();
     if ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation || percentage == 1)
-        animateString = to->boolean();
+        animatedBoolean = bool(toBoolean);
     else
-        animateString = from->boolean();
+        animatedBoolean = bool(fromBoolean);
 }
 
 float SVGAnimatedBooleanAnimator::calculateDistance(const String&, const String&)
index 3ccc27a..e992e58 100644 (file)
@@ -23,6 +23,7 @@
 #include "SVGAnimatedColor.h"
 
 #include "ColorDistance.h"
+#include "RenderObject.h"
 #include "SVGAnimateElement.h"
 #include "SVGColor.h"
 
@@ -49,51 +50,48 @@ void SVGAnimatedColorAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimat
     to->color() = ColorDistance::addColorsAndClamp(from->color(), to->color());
 }
 
-void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned,
-                                                      OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+static inline void adjustForCurrentColor(SVGElement* targetElement, Color& color)
+{
+    ASSERT(targetElement);
+
+    if (RenderObject* targetRenderer = targetElement->renderer())
+        color = targetRenderer->style()->visitedDependentColor(CSSPropertyColor);
+    else
+        color = Color();
+}
+
+static Color parseColorFromString(SVGAnimationElement*, const String& string)
+{
+    return SVGColor::colorFromRGBColorString(string);
+}
+
+void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
     
-    AnimationMode animationMode = animationElement->animationMode();
     Color& fromColor = from->color();
     Color& toColor = to->color();
     Color& animatedColor = animated->color();
-    // To animation uses contributions from the lower priority animations as the base value.
-    if (animationMode == ToAnimation)
-        fromColor = animatedColor;
-    
-    // Replace 'currentColor' / 'inherit' by their computed property values.
-    AnimatedPropertyValueType fromPropertyValueType = animationElement->fromPropertyValueType();
-    if (fromPropertyValueType == CurrentColorValue)
-        animationElement->adjustForCurrentColor(m_contextElement, fromColor);
-    else if (fromPropertyValueType == InheritValue) {
-        String fromColorString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromColorString);
-        fromColor = SVGColor::colorFromRGBColorString(fromColorString);
-    }
-    AnimatedPropertyValueType toPropertyValueType = animationElement->toPropertyValueType();
-    if (toPropertyValueType == CurrentColorValue)
-        animationElement->adjustForCurrentColor(m_contextElement, toColor);
-    else if (toPropertyValueType == InheritValue) {
-        String toColorString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toColorString);
-        toColor = SVGColor::colorFromRGBColorString(toColorString);
-    }
-    
+    m_animationElement->adjustFromToValues<Color>(parseColorFromString, fromColor, toColor, animatedColor, percentage, m_contextElement);
+
+    // Apply <animateColor> rules.
+    if (m_animationElement->fromPropertyValueType() == CurrentColorValue)
+        adjustForCurrentColor(m_contextElement, fromColor);
+    if (m_animationElement->toPropertyValueType() == CurrentColorValue)
+        adjustForCurrentColor(m_contextElement, toColor);
+
     Color color;
-    if (animationElement->calcMode() == CalcModeDiscrete)
+    if (m_animationElement->calcMode() == CalcModeDiscrete)
         color = percentage < 0.5 ? fromColor : toColor;
     else
         color = ColorDistance(fromColor, toColor).scaledDistance(percentage).addToColorAndClamp(fromColor);
     
     // FIXME: Accumulate colors.
-    if (animationElement->isAdditive() && animationMode != ToAnimation)
+    if (m_animationElement->isAdditive() && m_animationElement->animationMode() != ToAnimation)
         animatedColor = ColorDistance::addColorsAndClamp(animatedColor, color);
     else
         animatedColor = color;
-    return;
 }
 
 float SVGAnimatedColorAnimator::calculateDistance(const String& fromString, const String& toString)
index 16d9a28..0c57bb2 100644 (file)
@@ -146,18 +146,21 @@ void SVGAnimatedEnumerationAnimator::addAnimatedTypes(SVGAnimatedType* from, SVG
     ASSERT_UNUSED(to, from->type() == to->type());
 }
 
-void SVGAnimatedEnumerationAnimator::calculateAnimatedValue(float percentage, unsigned,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedEnumerationAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
+    unsigned& fromEnumeration = from->enumeration();
+    unsigned& toEnumeration = to->enumeration();
+    unsigned& animatedEnumeration = animated->enumeration();
+    m_animationElement->adjustFromToValues<unsigned>(0, fromEnumeration, toEnumeration, animatedEnumeration, percentage, m_contextElement);
+
     AnimationMode animationMode = m_animationElement->animationMode();
-    unsigned& animateEnumeration = animated->enumeration();
     if ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation || percentage == 1)
-        animateEnumeration = to->enumeration();
+        animatedEnumeration = unsigned(toEnumeration);
     else
-        animateEnumeration = from->enumeration();
+        animatedEnumeration = unsigned(fromEnumeration);
 }
 
 float SVGAnimatedEnumerationAnimator::calculateDistance(const String&, const String&)
index 1e156a5..ecc6aaa 100644 (file)
@@ -73,28 +73,24 @@ void SVGAnimatedIntegerAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnim
     to->integer() += from->integer();
 }
 
-void SVGAnimatedIntegerAnimator::calculateAnimatedInteger(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, int& animatedNumber, int fromNumber, int toNumber)
+void SVGAnimatedIntegerAnimator::calculateAnimatedInteger(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, int& animatedInteger, int fromInteger, int toInteger)
 {
-    float animatedFloat = animatedNumber;
-    SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedFloat, fromNumber, toNumber);
-    animatedNumber = static_cast<int>(roundf(animatedFloat));
+    float animatedNumber = animatedInteger;
+    SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumber, fromInteger, toInteger);
+    animatedInteger = static_cast<int>(roundf(animatedNumber));
 }
 
-void SVGAnimatedIntegerAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                        OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedIntegerAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);    
-    AnimationMode animationMode = animationElement->animationMode();
+    int& fromInteger = from->integer();
+    int& toInteger = to->integer();
+    int& animatedInteger = animated->integer();
+    m_animationElement->adjustFromToValues<int>(0, fromInteger, toInteger, animatedInteger, percentage, m_contextElement);
 
-    // To animation uses contributions from the lower priority animations as the base value.
-    int& animatedInt = animated->integer();
-    if (animationMode == ToAnimation)
-        from->integer() = animatedInt;
-
-    calculateAnimatedInteger(animationElement, percentage, repeatCount, animatedInt, from->integer(), to->integer());
+    calculateAnimatedInteger(m_animationElement, percentage, repeatCount, animatedInteger, fromInteger, toInteger);
 }
 
 float SVGAnimatedIntegerAnimator::calculateDistance(const String& fromString, const String& toString)
index 070548a..6c58ef1 100644 (file)
@@ -86,24 +86,18 @@ void SVGAnimatedIntegerOptionalIntegerAnimator::addAnimatedTypes(SVGAnimatedType
     toNumberPair.second += fromNumberPair.second;
 }
 
-void SVGAnimatedIntegerOptionalIntegerAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedIntegerOptionalIntegerAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    AnimationMode animationMode = animationElement->animationMode();
+    pair<int, int>& fromIntegerPair = from->integerOptionalInteger();
+    pair<int, int>& toIntegerPair = to->integerOptionalInteger();
+    pair<int, int>& animatedIntegerPair = animated->integerOptionalInteger();
+    m_animationElement->adjustFromToValues<pair<int, int> >(0, fromIntegerPair, toIntegerPair, animatedIntegerPair, percentage, m_contextElement);
 
-    // To animation uses contributions from the lower priority animations as the base value.
-    pair<int, int>& fromNumberPair = from->integerOptionalInteger();
-    pair<int, int>& animatedNumberPair = animated->integerOptionalInteger();
-    if (animationMode == ToAnimation)
-        fromNumberPair = animatedNumberPair;
-
-    pair<int, int>& toNumberPair = to->integerOptionalInteger();
-    SVGAnimatedIntegerAnimator::calculateAnimatedInteger(animationElement, percentage, repeatCount, animatedNumberPair.first, fromNumberPair.first, toNumberPair.first);
-    SVGAnimatedIntegerAnimator::calculateAnimatedInteger(animationElement, percentage, repeatCount, animatedNumberPair.second, fromNumberPair.second, toNumberPair.second);
+    SVGAnimatedIntegerAnimator::calculateAnimatedInteger(m_animationElement, percentage, repeatCount, animatedIntegerPair.first, fromIntegerPair.first, toIntegerPair.first);
+    SVGAnimatedIntegerAnimator::calculateAnimatedInteger(m_animationElement, percentage, repeatCount, animatedIntegerPair.second, fromIntegerPair.second, toIntegerPair.second);
 }
 
 float SVGAnimatedIntegerOptionalIntegerAnimator::calculateDistance(const String&, const String&)
index 7a97f4e..2745c5f 100644 (file)
@@ -86,38 +86,25 @@ void SVGAnimatedLengthAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnima
     ASSERT(!ec);
 }
 
-void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+static SVGLength parseLengthFromString(SVGAnimationElement* animationElement, const String& string)
+{
+    return sharedSVGLength(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()), string);
+}
+
+void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    AnimationMode animationMode = animationElement->animationMode();
-
-    // To animation uses contributions from the lower priority animations as the base value.
-    SVGLength& animatedSVGLength = animated->length();
     SVGLength& fromSVGLength = from->length();
-    if (animationMode == ToAnimation)
-        fromSVGLength = animatedSVGLength;
-    
-    // Replace 'inherit' by their computed property values.
     SVGLength& toSVGLength = to->length();
-    if (animationElement->fromPropertyValueType() == InheritValue) {
-        String fromLengthString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromLengthString);
-        fromSVGLength = sharedSVGLength(m_lengthMode, fromLengthString);
-    }
-    if (animationElement->toPropertyValueType() == InheritValue) {
-        String toLengthString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toLengthString);
-        toSVGLength = sharedSVGLength(m_lengthMode, toLengthString); 
-    }
-    
+    SVGLength& animatedSVGLength = animated->length();
+    m_animationElement->adjustFromToValues<SVGLength>(parseLengthFromString, fromSVGLength, toSVGLength, animatedSVGLength, percentage, m_contextElement);
+
     SVGLengthContext lengthContext(m_contextElement);
     float result = animatedSVGLength.value(lengthContext);
     SVGLengthType unitType = percentage < 0.5 ? fromSVGLength.unitType() : toSVGLength.unitType();
-    SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, result, fromSVGLength.value(lengthContext), toSVGLength.value(lengthContext));
+    SVGAnimatedNumberAnimator::calculateAnimatedNumber(m_animationElement, percentage, repeatCount, result, fromSVGLength.value(lengthContext), toSVGLength.value(lengthContext));
 
     ExceptionCode ec = 0;
     animatedSVGLength.setValue(lengthContext, result, m_lengthMode, unitType, ec);
index 3f87a95..e14e9c8 100644 (file)
@@ -83,44 +83,25 @@ void SVGAnimatedLengthListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGA
     }
 }
 
-void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+static SVGLengthList parseLengthListFromString(SVGAnimationElement* animationElement, const String& string)
+{
+    SVGLengthList lengthList;
+    lengthList.parse(string, SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
+    return lengthList;
+}
+
+void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    AnimationMode animationMode = animationElement->animationMode();
-
-    // To animation uses contributions from the lower priority animations as the base value.
     SVGLengthList& fromLengthList = from->lengthList();
-    SVGLengthList& animatedLengthList = animated->lengthList();
-    if (animationMode == ToAnimation)
-        fromLengthList = animatedLengthList;
-    
-    // Replace 'inherit' by their computed property values.    
     SVGLengthList& toLengthList = to->lengthList();
-    if (animationElement->fromPropertyValueType() == InheritValue) {
-        String fromLengthString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromLengthString);
-        fromLengthList.parse(fromLengthString, m_lengthMode);
-    }
-    if (animationElement->toPropertyValueType() == InheritValue) {
-        String toLengthString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toLengthString);
-        toLengthList.parse(toLengthString, m_lengthMode);
-    }
+    SVGLengthList& animatedLengthList = animated->lengthList();
+    if (!m_animationElement->adjustFromToListValues<SVGLengthList>(parseLengthListFromString, fromLengthList, toLengthList, animatedLengthList, percentage, m_contextElement))
+        return;
 
     unsigned itemsCount = fromLengthList.size();
-    if (itemsCount != toLengthList.size()) {
-        if (percentage < 0.5) {
-            if (animationMode != ToAnimation)
-                animatedLengthList = fromLengthList;
-        } else
-            animatedLengthList = toLengthList;
-        return;
-    }
-    
     bool animatedListSizeEqual = itemsCount == animatedLengthList.size();
     if (!animatedListSizeEqual)
         animatedLengthList.clear();
@@ -129,7 +110,7 @@ void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, uns
     for (unsigned i = 0; i < itemsCount; ++i) {
         float result = animatedListSizeEqual ? animatedLengthList[i].value(lengthContext) : 0;
         SVGLengthType unitType = percentage < 0.5 ? fromLengthList[i].unitType() : toLengthList[i].unitType();
-        SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, result, fromLengthList[i].value(lengthContext), toLengthList[i].value(lengthContext));
+        SVGAnimatedNumberAnimator::calculateAnimatedNumber(m_animationElement, percentage, repeatCount, result, fromLengthList[i].value(lengthContext), toLengthList[i].value(lengthContext));
         if (!animatedListSizeEqual)
             animatedLengthList.append(SVGLength(lengthContext, result, m_lengthMode, unitType));
         else {
index 01bb2b7..f36e094 100644 (file)
@@ -95,34 +95,24 @@ void SVGAnimatedNumberAnimator::calculateAnimatedNumber(SVGAnimationElement* ani
         animatedNumber = number;
 }
 
-void SVGAnimatedNumberAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+static float parseNumberFromString(SVGAnimationElement*, const String& string)
+{
+    float number = 0;
+    parseNumberFromString(string, number);
+    return number;
+}
+
+void SVGAnimatedNumberAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    
-    AnimationMode animationMode = animationElement->animationMode();
-    // To animation uses contributions from the lower priority animations as the base value.
-    float& animatedNumber = animated->number();
-    if (animationMode == ToAnimation)
-        from->number() = animatedNumber;
-    
-    // Replace 'inherit' by their computed property values.
+
     float& fromNumber = from->number();
     float& toNumber = to->number();
-    if (animationElement->fromPropertyValueType() == InheritValue) {
-        String fromNumberString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromNumberString);
-        parseNumberFromString(fromNumberString, fromNumber); 
-    }
-    if (animationElement->toPropertyValueType() == InheritValue) {
-        String toNumberString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toNumberString);
-        parseNumberFromString(toNumberString, toNumber); 
-    }
-    
-    calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumber, fromNumber, toNumber);
+    float& animatedNumber = animated->number();
+    m_animationElement->adjustFromToValues<float>(parseNumberFromString, fromNumber, toNumber, animatedNumber, percentage, m_contextElement);
+
+    calculateAnimatedNumber(m_animationElement, percentage, repeatCount, animatedNumber, fromNumber, toNumber);
 }
 
 float SVGAnimatedNumberAnimator::calculateDistance(const String& fromString, const String& toString)
index 8ab3cb7..934f718 100644 (file)
@@ -80,37 +80,23 @@ void SVGAnimatedNumberListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGA
         toNumberList[i] += fromNumberList[i];
 }
 
-void SVGAnimatedNumberListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                           OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedNumberListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);    
-    AnimationMode animationMode = animationElement->animationMode();
-
-    // To animation uses contributions from the lower priority animations as the base value.
     SVGNumberList& fromNumberList = from->numberList();
-    SVGNumberList& animatedNumberList = animated->numberList();
-    if (animationMode == ToAnimation)
-        fromNumberList = animatedNumberList;
-
     SVGNumberList& toNumberList = to->numberList();
-    unsigned itemsCount = fromNumberList.size();
-    if (itemsCount != toNumberList.size()) {
-        if (percentage < 0.5) {
-            if (animationMode != ToAnimation)
-                animatedNumberList = fromNumberList;
-        } else
-            animatedNumberList = toNumberList;
+    SVGNumberList& animatedNumberList = animated->numberList();
+    if (!m_animationElement->adjustFromToListValues<SVGNumberList>(0, fromNumberList, toNumberList, animatedNumberList, percentage, m_contextElement))
         return;
-    }
 
+    unsigned itemsCount = fromNumberList.size();
     if (itemsCount != animatedNumberList.size())
         animatedNumberList.resize(itemsCount);
 
     for (unsigned i = 0; i < itemsCount; ++i)
-        SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumberList[i], fromNumberList[i], toNumberList[i]);
+        SVGAnimatedNumberAnimator::calculateAnimatedNumber(m_animationElement, percentage, repeatCount, animatedNumberList[i], fromNumberList[i], toNumberList[i]);
 }
 
 float SVGAnimatedNumberListAnimator::calculateDistance(const String&, const String&)
index 46975b1..bdc41c4 100644 (file)
@@ -83,24 +83,18 @@ void SVGAnimatedNumberOptionalNumberAnimator::addAnimatedTypes(SVGAnimatedType*
     toNumberPair.second += fromNumberPair.second;
 }
 
-void SVGAnimatedNumberOptionalNumberAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedNumberOptionalNumberAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    AnimationMode animationMode = animationElement->animationMode();
-
-    // To animation uses contributions from the lower priority animations as the base value.
     pair<float, float>& fromNumberPair = from->numberOptionalNumber();
+    pair<float, float>& toNumberPair = to->numberOptionalNumber();
     pair<float, float>& animatedNumberPair = animated->numberOptionalNumber();
-    if (animationMode == ToAnimation)
-        fromNumberPair = animatedNumberPair;
+    m_animationElement->adjustFromToValues<pair<float, float> >(0, fromNumberPair, toNumberPair, animatedNumberPair, percentage, m_contextElement);
 
-    pair<float, float>& toNumberPair = to->numberOptionalNumber();
-    SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumberPair.first, fromNumberPair.first, toNumberPair.first);
-    SVGAnimatedNumberAnimator::calculateAnimatedNumber(animationElement, percentage, repeatCount, animatedNumberPair.second, fromNumberPair.second, toNumberPair.second);
+    SVGAnimatedNumberAnimator::calculateAnimatedNumber(m_animationElement, percentage, repeatCount, animatedNumberPair.first, fromNumberPair.first, toNumberPair.first);
+    SVGAnimatedNumberAnimator::calculateAnimatedNumber(m_animationElement, percentage, repeatCount, animatedNumberPair.second, fromNumberPair.second, toNumberPair.second);
 }
 
 float SVGAnimatedNumberOptionalNumberAnimator::calculateDistance(const String&, const String&)
index 0b2d332..ad5da84 100644 (file)
@@ -81,15 +81,17 @@ void SVGAnimatedPointListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAn
     }
 }
 
-void SVGAnimatedPointListAnimator::calculateAnimatedValue(float percentage, unsigned,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedPointListAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
     
-    SVGPointList& animatedPointList = animated->pointList();
     SVGPointList& fromPointList = from->pointList();
     SVGPointList& toPointList = to->pointList();
+    SVGPointList& animatedPointList = animated->pointList();
+    if (!m_animationElement->adjustFromToListValues<SVGPointList>(0, fromPointList, toPointList, animatedPointList, percentage, m_contextElement))
+        return;
+
     if (!percentage)
         animatedPointList = fromPointList;
     else if (percentage == 1)
@@ -100,12 +102,11 @@ void SVGAnimatedPointListAnimator::calculateAnimatedValue(float percentage, unsi
             SVGPointList::createAnimated(fromPointList, toPointList, animatedPointList, percentage);
             
         // Fall back to discrete animation if the points are not compatible
-        AnimationMode animationMode = static_cast<SVGAnimateElement*>(m_animationElement)->animationMode();
+        AnimationMode animationMode = m_animationElement->animationMode();
         if (animatedPointList.isEmpty())
             animatedPointList = ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation || percentage == 1) 
             ? toPointList : fromPointList;
     }
-    return;
 }
 
 float SVGAnimatedPointListAnimator::calculateDistance(const String&, const String&)
index 4dcf18d..b515dfc 100644 (file)
@@ -69,19 +69,21 @@ void SVGAnimatedPreserveAspectRatioAnimator::addAnimatedTypes(SVGAnimatedType* f
     ASSERT_UNUSED(to, from->type() == to->type());
 }
 
-void SVGAnimatedPreserveAspectRatioAnimator::calculateAnimatedValue(float percentage, unsigned,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedPreserveAspectRatioAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    
-    AnimationMode animationMode = animationElement->animationMode();
-    SVGPreserveAspectRatio& animateString = animated->preserveAspectRatio();
+
+    SVGPreserveAspectRatio& fromPreserveAspectRatio = from->preserveAspectRatio();
+    SVGPreserveAspectRatio& toPreserveAspectRatio = to->preserveAspectRatio();
+    SVGPreserveAspectRatio& animatedPreserveAspectRatio = animated->preserveAspectRatio();
+    m_animationElement->adjustFromToValues<SVGPreserveAspectRatio>(0, fromPreserveAspectRatio, toPreserveAspectRatio, animatedPreserveAspectRatio, percentage, m_contextElement);
+
+    AnimationMode animationMode = m_animationElement->animationMode();
     if ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation || percentage == 1)
-        animateString = to->preserveAspectRatio();
+        animatedPreserveAspectRatio = SVGPreserveAspectRatio(toPreserveAspectRatio);
     else
-        animateString = from->preserveAspectRatio();
+        animatedPreserveAspectRatio = SVGPreserveAspectRatio(fromPreserveAspectRatio);
 }
 
 float SVGAnimatedPreserveAspectRatioAnimator::calculateDistance(const String&, const String&)
index f9baeb5..c2fbc12 100644 (file)
@@ -72,39 +72,34 @@ void SVGAnimatedRectAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimate
     to->rect() += from->rect();
 }
 
-void SVGAnimatedRectAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedRectAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
 
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    AnimationMode animationMode = animationElement->animationMode();
-    // To animation uses contributions from the lower priority animations as the base value.
+    FloatRect& fromRect = from->rect();
+    FloatRect& toRect = to->rect();
     FloatRect& animatedRect = animated->rect();
-    if (animationMode == ToAnimation)
-        from->rect() = animatedRect;
-    
-    const FloatRect& fromRect = from->rect();
-    const FloatRect& toRect = to->rect();
+    m_animationElement->adjustFromToValues<FloatRect>(0, fromRect, toRect, animatedRect, percentage, m_contextElement);
+
     FloatRect newRect;    
-    if (animationElement->calcMode() == CalcModeDiscrete)
+    if (m_animationElement->calcMode() == CalcModeDiscrete)
         newRect = percentage < 0.5 ? fromRect : toRect;
     else
         newRect = FloatRect((toRect.x() - fromRect.x()) * percentage + fromRect.x(),
                             (toRect.y() - fromRect.y()) * percentage + fromRect.y(),
                             (toRect.width() - fromRect.width()) * percentage + fromRect.width(),
                             (toRect.height() - fromRect.height()) * percentage + fromRect.height());
-    
+
     // FIXME: This is not correct for values animation. Right now we transform values-animation to multiple from-to-animations and
     // accumulate every single value to the previous one. But accumulation should just take into account after a complete cycle
     // of values-animaiton. See example at: http://www.w3.org/TR/2001/REC-smil-animation-20010904/#RepeatingAnim
-    if (animationElement->isAccumulated() && repeatCount) {
+    if (m_animationElement->isAccumulated() && repeatCount) {
         newRect += toRect;
         newRect.scale(repeatCount);
     }
     
-    if (animationElement->isAdditive() && animationMode != ToAnimation)
+    if (m_animationElement->isAdditive() && m_animationElement->animationMode() != ToAnimation)
         animatedRect += newRect;
     else
         animatedRect = newRect;
index 1be6d11..14146b0 100644 (file)
@@ -69,19 +69,26 @@ void SVGAnimatedStringAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnima
     ASSERT_UNUSED(to, from->type() == to->type());
 }
 
-void SVGAnimatedStringAnimator::calculateAnimatedValue(float percentage, unsigned,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+static String parseStringFromString(SVGAnimationElement*, const String& string)
+{
+    return string;
+}
+
+void SVGAnimatedStringAnimator::calculateAnimatedValue(float percentage, unsigned, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    
-    AnimationMode animationMode = animationElement->animationMode();
-    String& animateString = animated->string();
+
+    String& fromString = from->string();
+    String& toString = to->string();
+    String& animatedString = animated->string();
+    m_animationElement->adjustFromToValues<String>(parseStringFromString, fromString, toString, animatedString, percentage, m_contextElement);
+
+    AnimationMode animationMode = m_animationElement->animationMode();
     if ((animationMode == FromToAnimation && percentage > 0.5) || animationMode == ToAnimation || percentage == 1)
-        animateString = to->string();
+        animatedString = String(toString);
     else
-        animateString = from->string();
+        animatedString = String(fromString);
 }
 
 float SVGAnimatedStringAnimator::calculateDistance(const String&, const String&)
index e97b716..cc46f9b 100644 (file)
@@ -89,8 +89,7 @@ void SVGAnimatedTransformListAnimator::addAnimatedTypes(SVGAnimatedType* from, S
     toTransformList[0] = SVGTransformDistance::addSVGTransforms(fromTransformList[0], toTransformList[0]);
 }
 
-void SVGAnimatedTransformListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedTransformListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
 {
     ASSERT(m_animationElement);
 
index 93768fc..d57654e 100644 (file)
@@ -62,6 +62,8 @@ END_REGISTER_ANIMATED_PROPERTIES
 
 SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document* document)
     : SVGSMILElement(tagName, document)
+    , m_fromPropertyValueType(RegularPropertyValue)
+    , m_toPropertyValueType(RegularPropertyValue)
     , m_animationValid(false)
 {
     registerAnimatedPropertiesForSVGAnimationElement();
@@ -652,6 +654,43 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeat, SVGSMI
     calculateAnimatedValue(effectivePercent, repeat, resultElement);
 }
 
+void SVGAnimationElement::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 = CSSComputedStyleDeclaration::create(svgParent)->getPropertyValue(cssPropertyID(attributeName.localName()));
+}
+
+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);
+}
+
+void SVGAnimationElement::determinePropertyValueTypes(const String& from, const String& to)
+{
+    SVGElement* targetElement = this->targetElement();
+    ASSERT(targetElement);
+
+    const QualifiedName& attributeName = this->attributeName();
+    if (inheritsFromProperty(targetElement, attributeName, from))
+        m_fromPropertyValueType = InheritValue;
+    if (inheritsFromProperty(targetElement, attributeName, to))
+        m_toPropertyValueType = InheritValue;
+}
+
 }
 
 #endif // ENABLE(SVG)
index d21a8f8..bebd063 100644 (file)
@@ -48,6 +48,14 @@ enum AnimationMode {
     PathAnimation // Used by AnimateMotion.
 };
 
+// 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
+};
+
 enum CalcMode {
     CalcModeDiscrete,
     CalcModeLinear,
@@ -90,9 +98,68 @@ public:
 
     ShouldApplyAnimation shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName);
 
+    AnimatedPropertyValueType fromPropertyValueType() const { return m_fromPropertyValueType; }
+    AnimatedPropertyValueType toPropertyValueType() const { return m_toPropertyValueType; }
+
+    template<typename AnimatedType>
+    void adjustForInheritance(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&),
+                              AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement)
+    {
+        if (valueType != InheritValue)
+            return;
+        // Replace 'inherit' by its computed property value.
+        ASSERT(parseTypeFromString);
+        String typeString;
+        adjustForInheritance(contextElement, attributeName(), typeString);
+        animatedType = (*parseTypeFromString)(this, typeString);
+    }
+
+    template<typename AnimatedType>
+    void adjustFromToValues(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&),
+                            AnimatedType& fromType, AnimatedType& toType, AnimatedType& animatedType,
+                            float& percentage, SVGElement* contextElement)
+    {
+        // To-animation uses contributions from the lower priority animations as the base value.
+        if (animationMode() == ToAnimation)
+            fromType = AnimatedType(animatedType);
+
+        adjustForInheritance<AnimatedType>(parseTypeFromString, m_fromPropertyValueType, fromType, contextElement);
+        adjustForInheritance<AnimatedType>(parseTypeFromString, m_toPropertyValueType, toType, contextElement);
+
+        if (calcMode() == CalcModeDiscrete)
+            percentage = percentage < 0.5 ? 0 : 1;
+    }
+
+    template<typename AnimatedType>
+    bool adjustFromToListValues(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&), 
+                                AnimatedType& fromList, AnimatedType& toList, AnimatedType& animatedList,
+                                float& percentage, SVGElement* contextElement)
+    {
+        adjustFromToValues(parseTypeFromString, fromList, toList, animatedList, percentage, contextElement);
+
+        // If no to value is given, nothing to animate.
+        if (!toList.size())
+            return false;
+
+        // If the from value is given and doesn't match the to value, fallback to a discrete animation.
+        if (fromList.size() != toList.size() && fromList.size()) {
+            if (percentage < 0.5) {
+                if (animationMode() != ToAnimation)
+                    animatedList = fromList;
+            } else
+                animatedList = toList;
+
+            return false;
+        }
+
+        return true;
+    }
+
 protected:
     SVGAnimationElement(const QualifiedName&, Document*);
 
+    virtual void determinePropertyValueTypes(const String& from, const String& to);
+
     bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(Attribute*) OVERRIDE;
     virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
@@ -115,6 +182,9 @@ protected:
     virtual void startedActiveInterval();
     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement);
 
+    AnimatedPropertyValueType m_fromPropertyValueType;
+    AnimatedPropertyValueType m_toPropertyValueType;
+
 private:
     virtual void animationAttributeChanged() OVERRIDE;
 
@@ -133,6 +203,7 @@ private:
     unsigned calculateKeyTimesIndex(float percent) const;
 
     void applyAnimatedValue(ShouldApplyAnimation, SVGElement* targetElement, const QualifiedName& attributeName, SVGAnimatedType*);
+    void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String&);
 
     BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAnimationElement)
         DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)