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/platform/graphics/UnitBezier.h" 29 #include "core/svg/SVGAnimatedBoolean.h" 30 #include "core/svg/SVGExternalResourcesRequired.h" 31 #include "core/svg/SVGTests.h" 32 #include "core/svg/animation/SVGSMILElement.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 'currentColor' or 'inherit' as animation value, we need to grab 47 // the value during the animation since the value can be animated itself. 48 enum AnimatedPropertyValueType { 49 RegularPropertyValue, 50 CurrentColorValue, 51 InheritValue 52 }; 53 54 enum CalcMode { 55 CalcModeDiscrete, 56 CalcModeLinear, 57 CalcModePaced, 58 CalcModeSpline 59 }; 60 61 class ConditionEventListener; 62 class TimeContainer; 63 class SVGAnimatedType; 64 65 class SVGAnimationElement : public SVGSMILElement, 66 public SVGTests, 67 public SVGExternalResourcesRequired { 68 public: 69 // SVGAnimationElement 70 float getStartTime() const; 71 float getCurrentTime() const; 72 float getSimpleDuration() const; 73 74 void beginElement(); 75 void beginElementAt(float offset); 76 void endElement(); 77 void endElementAt(float offset); 78 79 static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&); 80 81 virtual bool isAdditive() const; 82 bool isAccumulated() const; 83 AnimationMode animationMode() const { return m_animationMode; } 84 CalcMode calcMode() const { return m_calcMode; } 85 86 enum ShouldApplyAnimation { 87 DontApplyAnimation, 88 ApplyCSSAnimation, 89 ApplyXMLAnimation 90 }; 91 92 ShouldApplyAnimation shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName); 93 94 AnimatedPropertyValueType fromPropertyValueType() const { return m_fromPropertyValueType; } 95 AnimatedPropertyValueType toPropertyValueType() const { return m_toPropertyValueType; } 96 97 template<typename AnimatedType> 98 void adjustForInheritance(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&), 99 AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement) 100 { 101 if (valueType != InheritValue) 102 return; 103 // Replace 'inherit' by its computed property value. 104 ASSERT(parseTypeFromString); 105 String typeString; 106 adjustForInheritance(contextElement, attributeName(), typeString); 107 animatedType = (*parseTypeFromString)(this, typeString); 108 } 109 110 template<typename AnimatedType> 111 bool adjustFromToListValues(const AnimatedType& fromList, const AnimatedType& toList, AnimatedType& animatedList, float percentage, bool resizeAnimatedListIfNeeded = true) 112 { 113 // If no 'to' value is given, nothing to animate. 114 unsigned toListSize = toList.size(); 115 if (!toListSize) 116 return false; 117 118 // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation. 119 unsigned fromListSize = fromList.size(); 120 if (fromListSize != toListSize && fromListSize) { 121 if (percentage < 0.5) { 122 if (animationMode() != ToAnimation) 123 animatedList = AnimatedType(fromList); 124 } else 125 animatedList = AnimatedType(toList); 126 127 return false; 128 } 129 130 ASSERT(!fromListSize || fromListSize == toListSize); 131 if (resizeAnimatedListIfNeeded && animatedList.size() < toListSize) 132 animatedList.resize(toListSize); 133 134 return true; 135 } 136 137 template<typename AnimatedType> 138 void animateDiscreteType(float percentage, const AnimatedType& fromType, const AnimatedType& toType, AnimatedType& animatedType) 139 { 140 if ((animationMode() == FromToAnimation && percentage > 0.5) || animationMode() == ToAnimation || percentage == 1) { 141 animatedType = AnimatedType(toType); 142 return; 143 } 144 animatedType = AnimatedType(fromType); 145 } 146 147 void animateAdditiveNumber(float percentage, unsigned repeatCount, float fromNumber, float toNumber, float toAtEndOfDurationNumber, float& animatedNumber) 148 { 149 float number; 150 if (calcMode() == CalcModeDiscrete) 151 number = percentage < 0.5 ? fromNumber : toNumber; 152 else 153 number = (toNumber - fromNumber) * percentage + fromNumber; 154 155 if (isAccumulated() && repeatCount) 156 number += toAtEndOfDurationNumber * repeatCount; 157 158 if (isAdditive() && animationMode() != ToAnimation) 159 animatedNumber += number; 160 else 161 animatedNumber = number; 162 } 163 164 protected: 165 SVGAnimationElement(const QualifiedName&, Document*); 166 167 void computeCSSPropertyValue(SVGElement*, CSSPropertyID, String& value); 168 virtual void determinePropertyValueTypes(const String& from, const String& to); 169 170 bool isSupportedAttribute(const QualifiedName&); 171 virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE; 172 virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE; 173 174 enum AttributeType { 175 AttributeTypeCSS, 176 AttributeTypeXML, 177 AttributeTypeAuto 178 }; 179 AttributeType attributeType() const { return m_attributeType; } 180 181 String toValue() const; 182 String byValue() const; 183 String fromValue() const; 184 185 String targetAttributeBaseValue(); 186 187 // from SVGSMILElement 188 virtual void startedActiveInterval() OVERRIDE; 189 virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) OVERRIDE; 190 191 AnimatedPropertyValueType m_fromPropertyValueType; 192 AnimatedPropertyValueType m_toPropertyValueType; 193 194 virtual void setTargetElement(SVGElement*) OVERRIDE; 195 virtual void setAttributeName(const QualifiedName&) OVERRIDE; 196 bool hasInvalidCSSAttributeType() const { return m_hasInvalidCSSAttributeType; } 197 198 virtual void updateAnimationMode(); 199 void setAnimationMode(AnimationMode animationMode) { m_animationMode = animationMode; } 200 void setCalcMode(CalcMode calcMode) { m_calcMode = calcMode; } 201 202 private: 203 virtual void animationAttributeChanged() OVERRIDE; 204 void setAttributeType(const AtomicString&); 205 206 void checkInvalidCSSAttributeType(SVGElement*); 207 208 virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) = 0; 209 virtual bool calculateFromAndToValues(const String& fromString, const String& toString) = 0; 210 virtual bool calculateFromAndByValues(const String& fromString, const String& byString) = 0; 211 virtual void calculateAnimatedValue(float percent, unsigned repeatCount, SVGSMILElement* resultElement) = 0; 212 virtual float calculateDistance(const String& /*fromString*/, const String& /*toString*/) { return -1.f; } 213 214 void currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to); 215 void calculateKeyTimesForCalcModePaced(); 216 float calculatePercentFromKeyPoints(float percent) const; 217 void currentValuesFromKeyPoints(float percent, float& effectivePercent, String& from, String& to) const; 218 float calculatePercentForSpline(float percent, unsigned splineIndex) const; 219 float calculatePercentForFromTo(float percent) const; 220 unsigned calculateKeyTimesIndex(float percent) const; 221 222 void applyAnimatedValue(ShouldApplyAnimation, SVGElement* targetElement, const QualifiedName& attributeName, SVGAnimatedType*); 223 void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String&); 224 225 BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAnimationElement) 226 DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) 227 END_DECLARE_ANIMATED_PROPERTIES 228 229 // SVGTests 230 virtual void synchronizeRequiredFeatures() { SVGTests::synchronizeRequiredFeatures(this); } 231 virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); } 232 virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); } 233 234 void setCalcMode(const AtomicString&); 235 236 bool m_animationValid; 237 238 AttributeType m_attributeType; 239 Vector<String> m_values; 240 Vector<float> m_keyTimes; 241 Vector<float> m_keyPoints; 242 Vector<UnitBezier> m_keySplines; 243 String m_lastValuesAnimationFrom; 244 String m_lastValuesAnimationTo; 245 bool m_hasInvalidCSSAttributeType; 246 CalcMode m_calcMode; 247 AnimationMode m_animationMode; 248 }; 249 250 } // namespace WebCore 251 252 #endif // SVGAnimationElement_h 253