af6dbffa468136fbf36613151091d0a33d87109c
[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     virtual void finishParsingChildren();
52     
53     virtual bool hasValidAttributeType() const = 0;
54
55     SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
56
57     SVGElement* targetElement() const;
58     void resetTargetElement() { m_targetElement = 0; }
59     const QualifiedName& attributeName() const { return m_attributeName; }
60
61     void beginByLinkActivation();
62
63     enum Restart {
64         RestartAlways,
65         RestartWhenNotActive,
66         RestartNever
67     };
68
69     Restart restart() const;
70
71     enum FillMode {
72         FillRemove,
73         FillFreeze
74     };
75
76     FillMode fill() const;
77
78     String xlinkHref() const;
79
80     SMILTime dur() const;
81     SMILTime repeatDur() const;
82     SMILTime repeatCount() const;
83     SMILTime maxValue() const;
84     SMILTime minValue() const;
85
86     SMILTime elapsed() const; 
87
88     SMILTime intervalBegin() const { return m_intervalBegin; }
89     SMILTime intervalEnd() const { return m_intervalEnd; }
90     SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; }
91     SMILTime simpleDuration() const;
92
93     void progress(SMILTime elapsed, SVGSMILElement* resultsElement);
94     SMILTime nextProgressTime() const;
95
96     static SMILTime parseClockValue(const String&);
97     static SMILTime parseOffsetValue(const String&);
98
99     bool isContributing(SMILTime elapsed) const;
100     bool isInactive() const;
101     bool isFrozen() const;
102
103     unsigned documentOrderIndex() const { return m_documentOrderIndex; }
104     void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; }
105
106     virtual bool isAdditive() const = 0;
107     virtual void resetToBaseValue(const String&) = 0;
108     virtual void applyResultsToTarget() = 0;
109
110 protected:
111     void addBeginTime(SMILTime);
112     void addEndTime(SMILTime);
113
114     void setInactive() { m_activeState = Inactive; }
115
116 private:
117     virtual void startedActiveInterval() = 0;
118     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0;
119     virtual void endedActiveInterval() = 0;
120
121     enum BeginOrEnd {
122         Begin,
123         End
124     };
125     
126     SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
127     void resolveFirstInterval();
128     void resolveNextInterval();
129     void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
130     SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
131     SMILTime repeatingDuration() const;
132     void checkRestart(SMILTime elapsed);
133     void beginListChanged();
134     void endListChanged();
135     void reschedule();
136
137     // This represents conditions on elements begin or end list that need to be resolved on runtime
138     // for example <animate begin="otherElement.begin + 8s; button.click" ... />
139     struct Condition {
140         enum Type {
141             EventBase,
142             Syncbase,
143             AccessKey
144         };
145
146         Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1);
147         Type m_type;
148         BeginOrEnd m_beginOrEnd;
149         String m_baseID;
150         String m_name;
151         SMILTime m_offset;
152         int m_repeats;
153         RefPtr<Element> m_syncbase;
154         RefPtr<ConditionEventListener> m_eventListener;
155     };
156     bool parseCondition(const String&, BeginOrEnd beginOrEnd);
157     void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd);
158     Element* eventBaseFor(const Condition&) const;
159
160     void connectConditions();
161     void disconnectConditions();
162
163     // Event base timing
164     void handleConditionEvent(Event*, Condition*);
165
166     // Syncbase timing
167     enum NewOrExistingInterval {
168         NewInterval,
169         ExistingInterval
170     };
171
172     void notifyDependentsIntervalChanged(NewOrExistingInterval);
173     void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval);
174     void addTimeDependent(SVGSMILElement*);
175     void removeTimeDependent(SVGSMILElement*);
176
177     enum ActiveState {
178         Inactive,
179         Active,
180         Frozen
181     };
182
183     QualifiedName m_attributeName;
184
185     ActiveState determineActiveState(SMILTime elapsed) const;
186     float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
187     SMILTime calculateNextProgressTime(SMILTime elapsed) const;
188
189     mutable SVGElement* m_targetElement;
190
191     Vector<Condition> m_conditions;
192     bool m_conditionsConnected;
193     bool m_hasEndEventConditions;     
194
195     typedef HashSet<SVGSMILElement*> TimeDependentSet;
196     TimeDependentSet m_timeDependents;
197
198     // Instance time lists
199     Vector<SMILTime> m_beginTimes;
200     Vector<SMILTime> m_endTimes;
201
202     // This is the upcoming or current interval
203     SMILTime m_intervalBegin;
204     SMILTime m_intervalEnd;
205
206     SMILTime m_previousIntervalBegin;
207
208     bool m_isWaitingForFirstInterval;
209
210     ActiveState m_activeState;
211     float m_lastPercent;
212     unsigned m_lastRepeat;
213
214     SMILTime m_nextProgressTime;
215
216     RefPtr<SMILTimeContainer> m_timeContainer;
217     unsigned m_documentOrderIndex;
218
219     mutable SMILTime m_cachedDur;
220     mutable SMILTime m_cachedRepeatDur;
221     mutable SMILTime m_cachedRepeatCount;
222     mutable SMILTime m_cachedMin;
223     mutable SMILTime m_cachedMax;
224
225     friend class ConditionEventListener;
226 };
227
228 }
229
230 #endif // ENABLE(SVG)
231 #endif // SVGSMILElement_h
232