• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
timeContainer()55     SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
56 
57     SVGElement* targetElement() const;
resetTargetElement()58     void resetTargetElement() { m_targetElement = 0; }
attributeName()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 
intervalBegin()88     SMILTime intervalBegin() const { return m_intervalBegin; }
intervalEnd()89     SMILTime intervalEnd() const { return m_intervalEnd; }
previousIntervalBegin()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 
documentOrderIndex()103     unsigned documentOrderIndex() const { return m_documentOrderIndex; }
setDocumentOrderIndex(unsigned index)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 private:
115     virtual void startedActiveInterval() = 0;
116     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0;
117     virtual void endedActiveInterval() = 0;
118 
119     enum BeginOrEnd {
120         Begin,
121         End
122     };
123 
124     SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
125     void resolveFirstInterval();
126     void resolveNextInterval();
127     void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
128     SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
129     SMILTime repeatingDuration() const;
130     void checkRestart(SMILTime elapsed);
131     void beginListChanged();
132     void endListChanged();
133     void reschedule();
134 
135     // This represents conditions on elements begin or end list that need to be resolved on runtime
136     // for example <animate begin="otherElement.begin + 8s; button.click" ... />
137     struct Condition {
138         enum Type {
139             EventBase,
140             Syncbase,
141             AccessKey
142         };
143 
144         Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1);
145         Type m_type;
146         BeginOrEnd m_beginOrEnd;
147         String m_baseID;
148         String m_name;
149         SMILTime m_offset;
150         int m_repeats;
151         RefPtr<Element> m_syncbase;
152         RefPtr<ConditionEventListener> m_eventListener;
153     };
154     bool parseCondition(const String&, BeginOrEnd beginOrEnd);
155     void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd);
156     Element* eventBaseFor(const Condition&) const;
157 
158     void connectConditions();
159     void disconnectConditions();
160 
161     // Event base timing
162     void handleConditionEvent(Event*, Condition*);
163 
164     // Syncbase timing
165     enum NewOrExistingInterval {
166         NewInterval,
167         ExistingInterval
168     };
169 
170     void notifyDependentsIntervalChanged(NewOrExistingInterval);
171     void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval);
172     void addTimeDependent(SVGSMILElement*);
173     void removeTimeDependent(SVGSMILElement*);
174 
175     enum ActiveState {
176         Inactive,
177         Active,
178         Frozen
179     };
180 
181     QualifiedName m_attributeName;
182 
183     ActiveState determineActiveState(SMILTime elapsed) const;
184     float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
185     SMILTime calculateNextProgressTime(SMILTime elapsed) const;
186 
187     mutable SVGElement* m_targetElement;
188 
189     Vector<Condition> m_conditions;
190     bool m_conditionsConnected;
191     bool m_hasEndEventConditions;
192 
193     typedef HashSet<SVGSMILElement*> TimeDependentSet;
194     TimeDependentSet m_timeDependents;
195 
196     // Instance time lists
197     Vector<SMILTime> m_beginTimes;
198     Vector<SMILTime> m_endTimes;
199 
200     // This is the upcoming or current interval
201     SMILTime m_intervalBegin;
202     SMILTime m_intervalEnd;
203 
204     SMILTime m_previousIntervalBegin;
205 
206     bool m_isWaitingForFirstInterval;
207 
208     ActiveState m_activeState;
209     float m_lastPercent;
210     unsigned m_lastRepeat;
211 
212     SMILTime m_nextProgressTime;
213 
214     RefPtr<SMILTimeContainer> m_timeContainer;
215     unsigned m_documentOrderIndex;
216 
217     mutable SMILTime m_cachedDur;
218     mutable SMILTime m_cachedRepeatDur;
219     mutable SMILTime m_cachedRepeatCount;
220     mutable SMILTime m_cachedMin;
221     mutable SMILTime m_cachedMax;
222 
223     friend class ConditionEventListener;
224 };
225 
226 }
227 
228 #endif // ENABLE(SVG)
229 #endif // SVGSMILElement_h
230 
231