Improve use of NeverDestroyed
[WebKit-https.git] / Source / WebCore / svg / SVGAnimatedLength.cpp
index c2f0d68..25cf3f3 100644 (file)
  */
 
 #include "config.h"
-
-#if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
 #include "SVGAnimatedLength.h"
 
-#include "SVGAnimateElement.h"
+#include "SVGAnimateElementBase.h"
+#include "SVGAnimatedNumber.h"
 
 namespace WebCore {
 
 SVGAnimatedLengthAnimator::SVGAnimatedLengthAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
     : SVGAnimatedTypeAnimator(AnimatedLength, animationElement, contextElement)
-    , m_lengthMode(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()))
+    , m_lengthMode(SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()))
 {
 }
 
-static inline SVGLength& sharedSVGLength(SVGLengthMode mode, const String& valueAsString)
+std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthAnimator::constructFromString(const String& string)
 {
-    DEFINE_STATIC_LOCAL(SVGLength, sharedLength, ());
-    ExceptionCode ec = 0;
-    sharedLength.setValueAsString(valueAsString, mode, ec);
-    ASSERT(!ec);
-    return sharedLength;
+    return SVGAnimatedType::createLength(std::make_unique<SVGLengthValue>(m_lengthMode, string));
 }
 
-PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthAnimator::constructFromString(const String& string)
+std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
 {
-    return SVGAnimatedType::createLength(new SVGLength(m_lengthMode, string));
+    return SVGAnimatedType::createLength(constructFromBaseValue<SVGAnimatedLength>(animatedTypes));
 }
 
-void SVGAnimatedLengthAnimator::calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString)
+void SVGAnimatedLengthAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
 {
-    ASSERT(m_contextElement);
-    ASSERT(m_animationElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    animationElement->determinePropertyValueTypes(fromString, toString);
-    
-    from = constructFromString(fromString);
-    to = constructFromString(toString);
+    stopAnimValAnimationForType<SVGAnimatedLength>(animatedTypes);
 }
 
-void SVGAnimatedLengthAnimator::calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString)
+void SVGAnimatedLengthAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type)
 {
-    ASSERT(m_contextElement);
-    ASSERT(m_animationElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);
-    animationElement->determinePropertyValueTypes(fromString, byString);
-    
-    from = constructFromString(fromString);
-    to = constructFromString(byString);
-    
-    SVGLength& fromLength = from->length();
-    SVGLength& toLength = to->length();
-    ExceptionCode ec = 0;
-    toLength.setValue(toLength.value(m_contextElement) + fromLength.value(m_contextElement), m_contextElement, ec);
-    ASSERT(!ec);
+    resetFromBaseValue<SVGAnimatedLength>(animatedTypes, type, &SVGAnimatedType::length);
+}
+
+void SVGAnimatedLengthAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
+{
+    animValWillChangeForType<SVGAnimatedLength>(animatedTypes);
+}
+
+void SVGAnimatedLengthAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
+{
+    animValDidChangeForType<SVGAnimatedLength>(animatedTypes);
+}
+
+void SVGAnimatedLengthAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
+{
+    ASSERT(from->type() == AnimatedLength);
+    ASSERT(from->type() == to->type());
+
+    SVGLengthContext lengthContext(m_contextElement);
+    const auto& fromLength = from->length();
+    auto& toLength = to->length();
+
+    toLength.setValue(toLength.value(lengthContext) + fromLength.value(lengthContext), lengthContext);
+}
+
+static SVGLengthValue parseLengthFromString(SVGAnimationElement* animationElement, const String& string)
+{
+    SVGLengthValue length;
+    length.setValueAsString(string, SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
+    return length;
 }
 
-void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount,
-                                                       OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, OwnPtr<SVGAnimatedType>& animated)
+void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, 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.
-    // FIXME: Avoid string parsing.
-    if (animationMode == ToAnimation)
-        from = constructFromString(animated->length().valueAsString());
-    
-    // Replace 'inherit' by their computed property values.
-    float number;
-    float fromLength = from->length().value(m_contextElement);
-    float toLength = to->length().value(m_contextElement);
-    
-    if (animationElement->fromPropertyValueType() == InheritValue) {
-        String fromLengthString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), fromLengthString);
-        fromLength = sharedSVGLength(m_lengthMode, fromLengthString).value(m_contextElement);
-    }
-    if (animationElement->toPropertyValueType() == InheritValue) {
-        String toLengthString;
-        animationElement->adjustForInheritance(m_contextElement, animationElement->attributeName(), toLengthString);
-        toLength = sharedSVGLength(m_lengthMode, toLengthString).value(m_contextElement); 
-    }
-    
-    if (animationElement->calcMode() == CalcModeDiscrete)
-        number = percentage < 0.5f ? fromLength : toLength;
-    else
-        number = (toLength - fromLength) * percentage + fromLength;
-    
-    // FIXME: This is not correct for values animation.
-    if (animationElement->isAccumulated() && repeatCount)
-        number += toLength * repeatCount;
-    ExceptionCode ec = 0;
-    SVGLength& animatedSVGLength = animated->length();
-    if (animationElement->isAdditive() && animationMode != ToAnimation) {
-        float animatedSVGLengthValue = animatedSVGLength.value(m_contextElement);
-        animatedSVGLengthValue += number;
-        animatedSVGLength.setValue(animatedSVGLengthValue, m_contextElement, ec);
-    } else
-        animatedSVGLength.setValue(number, m_contextElement, ec);
-    ASSERT(!ec);
+
+    auto fromSVGLength = m_animationElement->animationMode() == ToAnimation ? animated->length() : from->length();
+    auto toSVGLength = to->length();
+    const auto& toAtEndOfDurationSVGLength = toAtEndOfDuration->length();
+    auto& animatedSVGLength = animated->length();
+
+    // Apply CSS inheritance rules.
+    m_animationElement->adjustForInheritance<SVGLengthValue>(parseLengthFromString, m_animationElement->fromPropertyValueType(), fromSVGLength, m_contextElement);
+    m_animationElement->adjustForInheritance<SVGLengthValue>(parseLengthFromString, m_animationElement->toPropertyValueType(), toSVGLength, m_contextElement);
+
+    SVGLengthContext lengthContext(m_contextElement);
+    float animatedNumber = animatedSVGLength.value(lengthContext);
+    SVGLengthType unitType = percentage < 0.5 ? fromSVGLength.unitType() : toSVGLength.unitType();
+    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromSVGLength.value(lengthContext), toSVGLength.value(lengthContext), toAtEndOfDurationSVGLength.value(lengthContext), animatedNumber);
+
+    animatedSVGLength.setValue(lengthContext, animatedNumber, m_lengthMode, unitType);
 }
 
 float SVGAnimatedLengthAnimator::calculateDistance(const String& fromString, const String& toString)
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
-    SVGAnimateElement* animationElement = static_cast<SVGAnimateElement*>(m_animationElement);    
-    SVGLengthMode lengthMode = SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName());
-    SVGLength from = SVGLength(lengthMode, fromString);
-    SVGLength to = SVGLength(lengthMode, toString);
-    return fabsf(to.value(m_contextElement) - from.value(m_contextElement));
+    auto lengthMode = SVGLengthValue::lengthModeForAnimatedLengthAttribute(m_animationElement->attributeName());
+    auto from = SVGLengthValue(lengthMode, fromString);
+    auto to = SVGLengthValue(lengthMode, toString);
+    SVGLengthContext lengthContext(m_contextElement);
+    return fabsf(to.value(lengthContext) - from.value(lengthContext));
 }
 
 }
-
-#endif // ENABLE(SVG) && ENABLE(SVG_ANIMATION)