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