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