• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved.
3  * Copyright (C) 2013 Samsung Electronics. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifndef SVGAnimatedTypeAnimator_h
22 #define SVGAnimatedTypeAnimator_h
23 
24 #include "core/svg/SVGAnimatedType.h"
25 #include "core/svg/SVGElementInstance.h"
26 #include "core/svg/properties/SVGAnimatedProperty.h"
27 #include "wtf/PassOwnPtr.h"
28 
29 namespace WebCore {
30 
31 struct SVGElementAnimatedProperties {
32     SVGElementAnimatedProperties();
33 
34     SVGElementAnimatedProperties(SVGElement*, Vector<RefPtr<SVGAnimatedProperty> >&);
35 
36     SVGElement* element;
37     Vector<RefPtr<SVGAnimatedProperty> > properties;
38 };
39 typedef Vector<SVGElementAnimatedProperties> SVGElementAnimatedPropertyList;
40 
41 class SVGAnimationElement;
42 
43 class SVGAnimatedTypeAnimator {
44     WTF_MAKE_FAST_ALLOCATED;
45 public:
46     virtual ~SVGAnimatedTypeAnimator();
47     virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) = 0;
48 
49     virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0;
50     virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0;
51     virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) = 0;
52     virtual void animValWillChange(const SVGElementAnimatedPropertyList&) = 0;
53     virtual void animValDidChange(const SVGElementAnimatedPropertyList&) = 0;
54     virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) = 0;
55 
56     virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) = 0;
57     virtual float calculateDistance(const String& fromString, const String& toString) = 0;
58 
59     void calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString);
60     void calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString);
61 
setContextElement(SVGElement * contextElement)62     void setContextElement(SVGElement* contextElement) { m_contextElement = contextElement; }
type()63     AnimatedPropertyType type() const { return m_type; }
64 
65     SVGElementAnimatedPropertyList findAnimatedPropertiesForAttributeName(SVGElement*, const QualifiedName&);
66 
67 protected:
68     SVGAnimatedTypeAnimator(AnimatedPropertyType, SVGAnimationElement*, SVGElement*);
69 
70     // Helpers for animators that operate on single types, eg. just one SVGAnimatedInteger.
71     template<typename AnimValType>
constructFromBaseValue(const SVGElementAnimatedPropertyList & animatedTypes)72     typename AnimValType::ContentType* constructFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes)
73     {
74         ASSERT(animatedTypes[0].properties.size() == 1);
75         const typename AnimValType::ContentType& animatedType = castAnimatedPropertyToActualType<AnimValType>(animatedTypes[0].properties[0].get())->currentBaseValue();
76 
77         typename AnimValType::ContentType* copy = new typename AnimValType::ContentType(animatedType);
78         executeAction<AnimValType>(StartAnimationAction, animatedTypes, 0, copy);
79         return copy;
80     }
81 
82     template<typename AnimValType>
resetFromBaseValue(const SVGElementAnimatedPropertyList & animatedTypes,SVGAnimatedType * type,typename AnimValType::ContentType & (SVGAnimatedType::* getter)())83     void resetFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, typename AnimValType::ContentType& (SVGAnimatedType::*getter)())
84     {
85         ASSERT(animatedTypes[0].properties.size() == 1);
86         ASSERT(type);
87         ASSERT(type->type() == m_type);
88         typename AnimValType::ContentType& animatedTypeValue = (type->*getter)();
89         animatedTypeValue = castAnimatedPropertyToActualType<AnimValType>(animatedTypes[0].properties[0].get())->currentBaseValue();
90 
91         executeAction<AnimValType>(StartAnimationAction, animatedTypes, 0, &animatedTypeValue);
92     }
93 
94     template<typename AnimValType>
stopAnimValAnimationForType(const SVGElementAnimatedPropertyList & animatedTypes)95     void stopAnimValAnimationForType(const SVGElementAnimatedPropertyList& animatedTypes)
96     {
97         ASSERT(animatedTypes[0].properties.size() == 1);
98         executeAction<AnimValType>(StopAnimationAction, animatedTypes, 0);
99     }
100 
101     template<typename AnimValType>
animValDidChangeForType(const SVGElementAnimatedPropertyList & animatedTypes)102     void animValDidChangeForType(const SVGElementAnimatedPropertyList& animatedTypes)
103     {
104         ASSERT(animatedTypes[0].properties.size() == 1);
105         executeAction<AnimValType>(AnimValDidChangeAction, animatedTypes, 0);
106     }
107 
108     template<typename AnimValType>
animValWillChangeForType(const SVGElementAnimatedPropertyList & animatedTypes)109     void animValWillChangeForType(const SVGElementAnimatedPropertyList& animatedTypes)
110     {
111         ASSERT(animatedTypes[0].properties.size() == 1);
112         executeAction<AnimValType>(AnimValWillChangeAction, animatedTypes, 0);
113     }
114 
115     // Helpers for animators that operate on pair types, eg. a pair of SVGAnimatedIntegers.
116     template<typename AnimValType1, typename AnimValType2>
constructFromBaseValues(const SVGElementAnimatedPropertyList & animatedTypes)117     pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>* constructFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes)
118     {
119         ASSERT(animatedTypes[0].properties.size() == 2);
120         const typename AnimValType1::ContentType& firstType = castAnimatedPropertyToActualType<AnimValType1>(animatedTypes[0].properties[0].get())->currentBaseValue();
121         const typename AnimValType2::ContentType& secondType = castAnimatedPropertyToActualType<AnimValType2>(animatedTypes[0].properties[1].get())->currentBaseValue();
122 
123         pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>* copy = new pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>(firstType, secondType);
124         executeAction<AnimValType1>(StartAnimationAction, animatedTypes, 0, &copy->first);
125         executeAction<AnimValType2>(StartAnimationAction, animatedTypes, 1, &copy->second);
126         return copy;
127     }
128 
129     template<typename AnimValType1, typename AnimValType2>
resetFromBaseValues(const SVGElementAnimatedPropertyList & animatedTypes,SVGAnimatedType * type,pair<typename AnimValType1::ContentType,typename AnimValType2::ContentType> & (SVGAnimatedType::* getter)())130     void resetFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& (SVGAnimatedType::*getter)())
131     {
132         ASSERT(animatedTypes[0].properties.size() == 2);
133         ASSERT(type);
134         ASSERT(type->type() == m_type);
135 
136         pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& animatedTypeValue = (type->*getter)();
137         animatedTypeValue.first = castAnimatedPropertyToActualType<AnimValType1>(animatedTypes[0].properties[0].get())->currentBaseValue();
138         animatedTypeValue.second = castAnimatedPropertyToActualType<AnimValType2>(animatedTypes[0].properties[1].get())->currentBaseValue();
139 
140         executeAction<AnimValType1>(StartAnimationAction, animatedTypes, 0, &animatedTypeValue.first);
141         executeAction<AnimValType2>(StartAnimationAction, animatedTypes, 1, &animatedTypeValue.second);
142     }
143 
144     template<typename AnimValType1, typename AnimValType2>
stopAnimValAnimationForTypes(const SVGElementAnimatedPropertyList & animatedTypes)145     void stopAnimValAnimationForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
146     {
147         ASSERT(animatedTypes[0].properties.size() == 2);
148         executeAction<AnimValType1>(StopAnimationAction, animatedTypes, 0);
149         executeAction<AnimValType2>(StopAnimationAction, animatedTypes, 1);
150     }
151 
152     template<typename AnimValType1, typename AnimValType2>
animValDidChangeForTypes(const SVGElementAnimatedPropertyList & animatedTypes)153     void animValDidChangeForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
154     {
155         ASSERT(animatedTypes[0].properties.size() == 2);
156         executeAction<AnimValType1>(AnimValDidChangeAction, animatedTypes, 0);
157         executeAction<AnimValType2>(AnimValDidChangeAction, animatedTypes, 1);
158     }
159 
160     template<typename AnimValType1, typename AnimValType2>
animValWillChangeForTypes(const SVGElementAnimatedPropertyList & animatedTypes)161     void animValWillChangeForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
162     {
163         ASSERT(animatedTypes[0].properties.size() == 2);
164         executeAction<AnimValType1>(AnimValWillChangeAction, animatedTypes, 0);
165         executeAction<AnimValType2>(AnimValWillChangeAction, animatedTypes, 1);
166     }
167 
168     template<typename AnimValType>
castAnimatedPropertyToActualType(SVGAnimatedProperty * property)169     AnimValType* castAnimatedPropertyToActualType(SVGAnimatedProperty* property)
170     {
171         ASSERT(property);
172         ASSERT(property->contextElement());
173         // We can't assert property->animatedPropertyType() == m_type, as there's an exception for SVGMarkerElements orient attribute.
174         if (property->animatedPropertyType() != m_type) {
175             ASSERT(m_type == AnimatedAngle);
176             ASSERT(property->animatedPropertyType() == AnimatedEnumeration);
177         }
178         return static_cast<AnimValType*>(property);
179     }
180 
181     AnimatedPropertyType m_type;
182     SVGAnimationElement* m_animationElement;
183     SVGElement* m_contextElement;
184 
185 private:
186     enum AnimationAction {
187         StartAnimationAction,
188         StopAnimationAction,
189         AnimValWillChangeAction,
190         AnimValDidChangeAction
191     };
192 
193     template<typename AnimValType>
194     void executeAction(AnimationAction action, const SVGElementAnimatedPropertyList& animatedTypes, unsigned whichProperty, typename AnimValType::ContentType* type = 0)
195     {
196         SVGElementInstance::InstanceUpdateBlocker blocker(animatedTypes[0].element);
197 
198         SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
199         for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) {
200             ASSERT_WITH_SECURITY_IMPLICATION(whichProperty < it->properties.size());
201             AnimValType* property = castAnimatedPropertyToActualType<AnimValType>(it->properties[whichProperty].get());
202 
203             switch (action) {
204             case StartAnimationAction:
205                 ASSERT(type);
206                 if (!property->isAnimating())
207                     property->animationStarted(type);
208                 break;
209             case StopAnimationAction:
210                 ASSERT(!type);
211                 property->animationEnded();
212                 break;
213             case AnimValWillChangeAction:
214                 ASSERT(!type);
215                 property->animValWillChange();
216                 break;
217             case AnimValDidChangeAction:
218                 ASSERT(!type);
219                 property->animValDidChange();
220                 break;
221             }
222         }
223     }
224 };
225 
226 } // namespace WebCore
227 
228 #endif // SVGAnimatedTypeAnimator_h
229