Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis (at) kde.org>
      4  * Copyright (C) 2007 Eric Seidel <eric (at) webkit.org>
      5  * Copyright (C) 2008 Apple Inc. All rights reserved.
      6  * Copyright (C) 2008 Cameron McCormack <cam (at) mcc.id.au>
      7  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
      8  *
      9  * This library is free software; you can redistribute it and/or
     10  * modify it under the terms of the GNU Library General Public
     11  * License as published by the Free Software Foundation; either
     12  * version 2 of the License, or (at your option) any later version.
     13  *
     14  * This library is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17  * Library General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU Library General Public License
     20  * along with this library; see the file COPYING.LIB.  If not, write to
     21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     22  * Boston, MA 02110-1301, USA.
     23  */
     24 
     25 #ifndef SVGAnimationElement_h
     26 #define SVGAnimationElement_h
     27 
     28 #include "core/svg/SVGAnimatedBoolean.h"
     29 #include "core/svg/SVGTests.h"
     30 #include "core/svg/animation/SVGSMILElement.h"
     31 #include "platform/animation/UnitBezier.h"
     32 #include "wtf/Functional.h"
     33 
     34 namespace WebCore {
     35 
     36 enum AnimationMode {
     37     NoAnimation,
     38     FromToAnimation,
     39     FromByAnimation,
     40     ToAnimation,
     41     ByAnimation,
     42     ValuesAnimation,
     43     PathAnimation // Used by AnimateMotion.
     44 };
     45 
     46 // If we have 'inherit' as animation value, we need to grab the value
     47 // during the animation since the value can be animated itself.
     48 enum AnimatedPropertyValueType {
     49     RegularPropertyValue,
     50     InheritValue
     51 };
     52 
     53 enum CalcMode {
     54     CalcModeDiscrete,
     55     CalcModeLinear,
     56     CalcModePaced,
     57     CalcModeSpline
     58 };
     59 
     60 class SVGAnimationElement : public SVGSMILElement,
     61                             public SVGTests {
     62 public:
     63     // SVGAnimationElement
     64     float getStartTime() const;
     65     float getCurrentTime() const;
     66     float getSimpleDuration() const;
     67 
     68     void beginElement();
     69     void beginElementAt(float offset);
     70     void endElement();
     71     void endElementAt(float offset);
     72 
     73     DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(begin, beginEvent);
     74     DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(end, endEvent);
     75     DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(repeat, repeatEvent);
     76 
     77     static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&);
     78 
     79     virtual bool isAdditive();
     80     bool isAccumulated() const;
     81     AnimationMode animationMode() const { return m_animationMode; }
     82     CalcMode calcMode() const { return m_calcMode; }
     83 
     84     enum ShouldApplyAnimation {
     85         DontApplyAnimation,
     86         ApplyCSSAnimation,
     87         ApplyXMLAnimation
     88     };
     89 
     90     ShouldApplyAnimation shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName);
     91 
     92     AnimatedPropertyValueType fromPropertyValueType() const { return m_fromPropertyValueType; }
     93     AnimatedPropertyValueType toPropertyValueType() const { return m_toPropertyValueType; }
     94 
     95     template<typename AnimatedType, typename ParseTypeFromStringType>
     96     void adjustForInheritance(ParseTypeFromStringType parseTypeFromString, AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement)
     97     {
     98         if (valueType != InheritValue)
     99             return;
    100         // Replace 'inherit' by its computed property value.
    101         String typeString;
    102         adjustForInheritance(contextElement, attributeName(), typeString);
    103         animatedType = parseTypeFromString(this, typeString);
    104     }
    105 
    106     template<typename AnimatedType>
    107     void animateDiscreteType(float percentage, const AnimatedType& fromType, const AnimatedType& toType, AnimatedType& animatedType)
    108     {
    109         if ((animationMode() == FromToAnimation && percentage > 0.5) || animationMode() == ToAnimation || percentage == 1) {
    110             animatedType = AnimatedType(toType);
    111             return;
    112         }
    113         animatedType = AnimatedType(fromType);
    114     }
    115 
    116     void animateAdditiveNumber(float percentage, unsigned repeatCount, float fromNumber, float toNumber, float toAtEndOfDurationNumber, float& animatedNumber)
    117     {
    118         float number;
    119         if (calcMode() == CalcModeDiscrete)
    120             number = percentage < 0.5 ? fromNumber : toNumber;
    121         else
    122             number = (toNumber - fromNumber) * percentage + fromNumber;
    123 
    124         if (isAccumulated() && repeatCount)
    125             number += toAtEndOfDurationNumber * repeatCount;
    126 
    127         if (isAdditive() && animationMode() != ToAnimation)
    128             animatedNumber += number;
    129         else
    130             animatedNumber = number;
    131     }
    132 
    133 protected:
    134     SVGAnimationElement(const QualifiedName&, Document&);
    135 
    136     void computeCSSPropertyValue(SVGElement*, CSSPropertyID, String& value);
    137     void determinePropertyValueTypes(const String& from, const String& to);
    138 
    139     bool isSupportedAttribute(const QualifiedName&);
    140     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
    141     virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
    142 
    143     enum AttributeType {
    144         AttributeTypeCSS,
    145         AttributeTypeXML,
    146         AttributeTypeAuto
    147     };
    148     AttributeType attributeType() const { return m_attributeType; }
    149 
    150     String toValue() const;
    151     String byValue() const;
    152     String fromValue() const;
    153 
    154     // from SVGSMILElement
    155     virtual void startedActiveInterval() OVERRIDE;
    156     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) OVERRIDE;
    157 
    158     AnimatedPropertyValueType m_fromPropertyValueType;
    159     AnimatedPropertyValueType m_toPropertyValueType;
    160 
    161     virtual void setTargetElement(SVGElement*) OVERRIDE;
    162     virtual void setAttributeName(const QualifiedName&) OVERRIDE;
    163 
    164     bool hasInvalidCSSAttributeType() const { return m_hasInvalidCSSAttributeType; }
    165 
    166     virtual void updateAnimationMode();
    167     void setAnimationMode(AnimationMode animationMode) { m_animationMode = animationMode; }
    168     void setCalcMode(CalcMode calcMode) { m_calcMode = calcMode; }
    169 
    170 private:
    171     virtual void animationAttributeChanged() OVERRIDE;
    172     void setAttributeType(const AtomicString&);
    173 
    174     void checkInvalidCSSAttributeType(SVGElement*);
    175 
    176     virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) = 0;
    177     virtual bool calculateFromAndToValues(const String& fromString, const String& toString) = 0;
    178     virtual bool calculateFromAndByValues(const String& fromString, const String& byString) = 0;
    179     virtual void calculateAnimatedValue(float percent, unsigned repeatCount, SVGSMILElement* resultElement) = 0;
    180     virtual float calculateDistance(const String& /*fromString*/, const String& /*toString*/) { return -1.f; }
    181 
    182     void currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to);
    183     void calculateKeyTimesForCalcModePaced();
    184     float calculatePercentFromKeyPoints(float percent) const;
    185     void currentValuesFromKeyPoints(float percent, float& effectivePercent, String& from, String& to) const;
    186     float calculatePercentForSpline(float percent, unsigned splineIndex) const;
    187     float calculatePercentForFromTo(float percent) const;
    188     unsigned calculateKeyTimesIndex(float percent) const;
    189 
    190     void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String&);
    191 
    192     void setCalcMode(const AtomicString&);
    193 
    194     bool m_animationValid;
    195 
    196     AttributeType m_attributeType;
    197     Vector<String> m_values;
    198     // FIXME: We should probably use doubles for this, but there's no point
    199     // making such a change unless all SVG logic for sampling animations is
    200     // changed to use doubles.
    201     Vector<float> m_keyTimes;
    202     Vector<float> m_keyPoints;
    203     Vector<UnitBezier> m_keySplines;
    204     String m_lastValuesAnimationFrom;
    205     String m_lastValuesAnimationTo;
    206     bool m_hasInvalidCSSAttributeType;
    207     CalcMode m_calcMode;
    208     AnimationMode m_animationMode;
    209 };
    210 
    211 } // namespace WebCore
    212 
    213 #endif // SVGAnimationElement_h
    214