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 27 #ifndef SVGSMILElement_h 28 #define SVGSMILElement_h 29 #if ENABLE(SVG_ANIMATION) 30 31 #include "SVGElement.h" 32 #include "SMILTime.h" 33 #include <wtf/HashMap.h> 34 35 namespace WebCore { 36 37 class ConditionEventListener; 38 class SMILTimeContainer; 39 40 // This class implements SMIL interval timing model as needed for SVG animation. 41 class SVGSMILElement : public SVGElement { 42 public: 43 SVGSMILElement(const QualifiedName&, Document*); 44 virtual ~SVGSMILElement(); 45 46 static bool isSMILElement(Node* node); 47 48 virtual void parseMappedAttribute(MappedAttribute*); 49 virtual void attributeChanged(Attribute*, bool preserveDecls); 50 virtual void insertedIntoDocument(); 51 virtual void removedFromDocument(); 52 virtual void finishParsingChildren(); 53 timeContainer()54 SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } 55 56 SVGElement* targetElement() const; 57 String attributeName() const; 58 59 void beginByLinkActivation(); 60 61 enum Restart { RestartAlways, RestartWhenNotActive, RestartNever }; 62 Restart restart() const; 63 64 enum FillMode { FillRemove, FillFreeze }; 65 FillMode fill() const; 66 67 String xlinkHref() const; 68 69 SMILTime dur() const; 70 SMILTime repeatDur() const; 71 SMILTime repeatCount() const; 72 SMILTime maxValue() const; 73 SMILTime minValue() const; 74 75 SMILTime elapsed() const; 76 intervalBegin()77 SMILTime intervalBegin() const { return m_intervalBegin; } intervalEnd()78 SMILTime intervalEnd() const { return m_intervalEnd; } previousIntervalBegin()79 SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; } 80 SMILTime simpleDuration() const; 81 82 void progress(SMILTime elapsed, SVGSMILElement* resultsElement); 83 SMILTime nextProgressTime() const; 84 85 static SMILTime parseClockValue(const String&); 86 static SMILTime parseOffsetValue(const String&); 87 88 bool isContributing(SMILTime elapsed) const; 89 bool isInactive() const; 90 bool isFrozen() const; 91 documentOrderIndex()92 unsigned documentOrderIndex() const { return m_documentOrderIndex; } setDocumentOrderIndex(unsigned index)93 void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; } 94 95 virtual bool isAdditive() const = 0; 96 virtual void resetToBaseValue(const String&) = 0; 97 virtual void applyResultsToTarget() = 0; 98 99 protected: 100 void addBeginTime(SMILTime time); 101 void addEndTime(SMILTime time); 102 103 private: 104 virtual void startedActiveInterval() = 0; 105 virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0; 106 virtual void endedActiveInterval() = 0; 107 108 enum BeginOrEnd { Begin, End }; 109 SMILTime findInstanceTime(BeginOrEnd beginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const; 110 void resolveFirstInterval(); 111 void resolveNextInterval(); 112 void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const; 113 SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const; 114 SMILTime repeatingDuration() const; 115 void checkRestart(SMILTime elapsed); 116 void beginListChanged(); 117 void endListChanged(); 118 void reschedule(); 119 120 // This represents conditions on elements begin or end list that need to be resolved on runtime 121 // for example <animate begin="otherElement.begin + 8s; button.click" ... /> 122 struct Condition { 123 enum Type { EventBase, Syncbase, AccessKey }; 124 Condition(Type, BeginOrEnd beginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1); 125 Type m_type; 126 BeginOrEnd m_beginOrEnd; 127 String m_baseID; 128 String m_name; 129 SMILTime m_offset; 130 int m_repeats; 131 RefPtr<Element> m_syncbase; 132 RefPtr<ConditionEventListener> m_eventListener; 133 }; 134 bool parseCondition(const String&, BeginOrEnd beginOrEnd); 135 void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd); 136 137 void connectConditions(); 138 void disconnectConditions(); 139 140 // Event base timing 141 void handleConditionEvent(Event*, Condition*); 142 143 // Syncbase timing 144 enum NewOrExistingInterval { NewInterval, ExistingInterval }; 145 void notifyDependentsIntervalChanged(NewOrExistingInterval); 146 void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval); 147 void addTimeDependent(SVGSMILElement*); 148 void removeTimeDependent(SVGSMILElement*); 149 150 enum ActiveState { Inactive, Active, Frozen }; 151 ActiveState determineActiveState(SMILTime elapsed) const; 152 float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const; 153 SMILTime calculateNextProgressTime(SMILTime elapsed) const; 154 155 Vector<Condition> m_conditions; 156 bool m_conditionsConnected; 157 bool m_hasEndEventConditions; 158 159 typedef HashSet<SVGSMILElement*> TimeDependentSet; 160 TimeDependentSet m_timeDependents; 161 162 // Instance time lists 163 Vector<SMILTime> m_beginTimes; 164 Vector<SMILTime> m_endTimes; 165 166 // This is the upcoming or current interval 167 SMILTime m_intervalBegin; 168 SMILTime m_intervalEnd; 169 170 SMILTime m_previousIntervalBegin; 171 172 bool m_isWaitingForFirstInterval; 173 174 ActiveState m_activeState; 175 float m_lastPercent; 176 unsigned m_lastRepeat; 177 178 SMILTime m_nextProgressTime; 179 180 RefPtr<SMILTimeContainer> m_timeContainer; 181 unsigned m_documentOrderIndex; 182 183 mutable SMILTime m_cachedDur; 184 mutable SMILTime m_cachedRepeatDur; 185 mutable SMILTime m_cachedRepeatCount; 186 mutable SMILTime m_cachedMin; 187 mutable SMILTime m_cachedMax; 188 189 friend class ConditionEventListener; 190 }; 191 192 } 193 194 #endif 195 #endif 196 197