2011-05-26 Rob Buis <rbuis@rim.com>
[WebKit-https.git] / Source / WebCore / svg / animation / SVGSMILElement.h
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef SVGSMILElement_h
27 #define SVGSMILElement_h
28 #if ENABLE(SVG_ANIMATION)
29 #include "SMILTime.h"
30 #include "SVGElement.h"
31
32 #include <wtf/HashMap.h>
33
34 namespace WebCore {
35     
36 class ConditionEventListener;
37 class SMILTimeContainer;
38
39 // This class implements SMIL interval timing model as needed for SVG animation.
40 class SVGSMILElement : public SVGElement {
41 public:
42     SVGSMILElement(const QualifiedName&, Document*);
43     virtual ~SVGSMILElement();
44
45     static bool isSMILElement(Node*);
46
47     virtual void parseMappedAttribute(Attribute*);
48     virtual void attributeChanged(Attribute*, bool preserveDecls);
49     virtual void insertedIntoDocument();
50     virtual void removedFromDocument();
51     
52     virtual bool hasValidAttributeType() const = 0;
53
54     SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
55
56     SVGElement* targetElement() const;
57     void resetTargetElement() { m_targetElement = 0; }
58     const QualifiedName& attributeName() const { return m_attributeName; }
59
60     void beginByLinkActivation();
61
62     enum Restart {
63         RestartAlways,
64         RestartWhenNotActive,
65         RestartNever
66     };
67
68     Restart restart() const;
69
70     enum FillMode {
71         FillRemove,
72         FillFreeze
73     };
74
75     FillMode fill() const;
76
77     String xlinkHref() const;
78
79     SMILTime dur() const;
80     SMILTime repeatDur() const;
81     SMILTime repeatCount() const;
82     SMILTime maxValue() const;
83     SMILTime minValue() const;
84
85     SMILTime elapsed() const; 
86
87     SMILTime intervalBegin() const { return m_intervalBegin; }
88     SMILTime intervalEnd() const { return m_intervalEnd; }
89     SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; }
90     SMILTime simpleDuration() const;
91
92     void progress(SMILTime elapsed, SVGSMILElement* resultsElement);
93     SMILTime nextProgressTime() const;
94
95     static SMILTime parseClockValue(const String&);
96     static SMILTime parseOffsetValue(const String&);
97
98     bool isContributing(SMILTime elapsed) const;
99     bool isInactive() const;
100     bool isFrozen() const;
101
102     unsigned documentOrderIndex() const { return m_documentOrderIndex; }
103     void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; }
104
105     virtual bool isAdditive() const = 0;
106     virtual void resetToBaseValue(const String&) = 0;
107     virtual void applyResultsToTarget() = 0;
108
109 protected:
110     void addBeginTime(SMILTime);
111     void addEndTime(SMILTime);
112
113     void setInactive() { m_activeState = Inactive; }
114
115 private:
116     virtual void startedActiveInterval() = 0;
117     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0;
118     virtual void endedActiveInterval() = 0;
119
120     enum BeginOrEnd {
121         Begin,
122         End
123     };
124     
125     SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
126     void resolveFirstInterval();
127     void resolveNextInterval();
128     void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
129     SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
130     SMILTime repeatingDuration() const;
131     void checkRestart(SMILTime elapsed);
132     void beginListChanged();
133     void endListChanged();
134     void reschedule();
135
136     // This represents conditions on elements begin or end list that need to be resolved on runtime
137     // for example <animate begin="otherElement.begin + 8s; button.click" ... />
138     struct Condition {
139         enum Type {
140             EventBase,
141             Syncbase,
142             AccessKey
143         };
144
145         Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1);
146         Type m_type;
147         BeginOrEnd m_beginOrEnd;
148         String m_baseID;
149         String m_name;
150         SMILTime m_offset;
151         int m_repeats;
152         RefPtr<Element> m_syncbase;
153         RefPtr<ConditionEventListener> m_eventListener;
154     };
155     bool parseCondition(const String&, BeginOrEnd beginOrEnd);
156     void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd);
157     Element* eventBaseFor(const Condition&) const;
158
159     void connectConditions();
160     void disconnectConditions();
161
162     // Event base timing
163     void handleConditionEvent(Event*, Condition*);
164
165     // Syncbase timing
166     enum NewOrExistingInterval {
167         NewInterval,
168         ExistingInterval
169     };
170
171     void notifyDependentsIntervalChanged(NewOrExistingInterval);
172     void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval);
173     void addTimeDependent(SVGSMILElement*);
174     void removeTimeDependent(SVGSMILElement*);
175
176     enum ActiveState {
177         Inactive,
178         Active,
179         Frozen
180     };
181
182     QualifiedName m_attributeName;
183
184     ActiveState determineActiveState(SMILTime elapsed) const;
185     float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
186     SMILTime calculateNextProgressTime(SMILTime elapsed) const;
187
188     mutable SVGElement* m_targetElement;
189
190     Vector<Condition> m_conditions;
191     bool m_conditionsConnected;
192     bool m_hasEndEventConditions;     
193
194     typedef HashSet<SVGSMILElement*> TimeDependentSet;
195     TimeDependentSet m_timeDependents;
196
197     // Instance time lists
198     Vector<SMILTime> m_beginTimes;
199     Vector<SMILTime> m_endTimes;
200
201     // This is the upcoming or current interval
202     SMILTime m_intervalBegin;
203     SMILTime m_intervalEnd;
204
205     SMILTime m_previousIntervalBegin;
206
207     bool m_isWaitingForFirstInterval;
208
209     ActiveState m_activeState;
210     float m_lastPercent;
211     unsigned m_lastRepeat;
212
213     SMILTime m_nextProgressTime;
214
215     RefPtr<SMILTimeContainer> m_timeContainer;
216     unsigned m_documentOrderIndex;
217
218     mutable SMILTime m_cachedDur;
219     mutable SMILTime m_cachedRepeatDur;
220     mutable SMILTime m_cachedRepeatCount;
221     mutable SMILTime m_cachedMin;
222     mutable SMILTime m_cachedMax;
223
224     friend class ConditionEventListener;
225 };
226
227 }
228
229 #endif // ENABLE(SVG)
230 #endif // SVGSMILElement_h
231