File indexing completed on 2024-05-12 15:39:12

0001 /*
0002  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  * 1. Redistributions of source code must retain the above copyright
0008  *    notice, this list of conditions and the following disclaimer.
0009  * 2. Redistributions in binary form must reproduce the above copyright
0010  *    notice, this list of conditions and the following disclaimer in the
0011  *    documentation and/or other materials provided with the distribution.
0012  *
0013  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
0014  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0015  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0016  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
0017  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0018  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0019  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0020  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
0021  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0023  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #ifndef SVGSMILElement_h
0027 #define SVGSMILElement_h
0028 #if ENABLE(SVG_ANIMATION)
0029 
0030 #include "SVGElement.h"
0031 #include "SMILTime.h"
0032 #include <wtf/HashMap.h>
0033 
0034 namespace WebCore
0035 {
0036 
0037 class ConditionEventListener;
0038 class SMILTimeContainer;
0039 
0040 // This class implements SMIL interval timing model as needed for SVG animation.
0041 class SVGSMILElement : public SVGElement
0042 {
0043 public:
0044     SVGSMILElement(const QualifiedName &, Document *);
0045     virtual ~SVGSMILElement();
0046 
0047     static bool isSMILElement(Node *node);
0048 
0049     virtual void parseMappedAttribute(MappedAttribute *);
0050     virtual void attributeChanged(Attribute *, bool preserveDecls);
0051     virtual void insertedIntoDocument();
0052     virtual void removedFromDocument();
0053     virtual void finishParsingChildren();
0054 
0055     SMILTimeContainer *timeContainer() const
0056     {
0057         return m_timeContainer.get();
0058     }
0059 
0060     SVGElement *targetElement() const;
0061     String attributeName() const;
0062 
0063     void beginByLinkActivation();
0064 
0065     enum Restart { RestartAlways, RestartWhenNotActive, RestartNever };
0066     Restart restart() const;
0067 
0068     enum FillMode { FillRemove, FillFreeze };
0069     FillMode fill() const;
0070 
0071     String xlinkHref() const;
0072 
0073     SMILTime dur() const;
0074     SMILTime repeatDur() const;
0075     SMILTime repeatCount() const;
0076     SMILTime maxValue() const;
0077     SMILTime minValue() const;
0078 
0079     SMILTime elapsed() const;
0080 
0081     SMILTime intervalBegin() const
0082     {
0083         return m_intervalBegin;
0084     }
0085     SMILTime intervalEnd() const
0086     {
0087         return m_intervalEnd;
0088     }
0089     SMILTime previousIntervalBegin() const
0090     {
0091         return m_previousIntervalBegin;
0092     }
0093     SMILTime simpleDuration() const;
0094 
0095     void progress(SMILTime elapsed, SVGSMILElement *resultsElement);
0096     SMILTime nextProgressTime() const;
0097 
0098     static SMILTime parseClockValue(const String &);
0099     static SMILTime parseOffsetValue(const String &);
0100 
0101     bool isContributing(SMILTime elapsed) const;
0102     bool isInactive() const;
0103     bool isFrozen() const;
0104 
0105     unsigned documentOrderIndex() const
0106     {
0107         return m_documentOrderIndex;
0108     }
0109     void setDocumentOrderIndex(unsigned index)
0110     {
0111         m_documentOrderIndex = index;
0112     }
0113 
0114     virtual bool isAdditive() const = 0;
0115     virtual void resetToBaseValue(const String &) = 0;
0116     virtual void applyResultsToTarget() = 0;
0117 
0118 protected:
0119     void addBeginTime(SMILTime time);
0120     void addEndTime(SMILTime time);
0121 
0122 private:
0123     virtual void startedActiveInterval() = 0;
0124     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement *resultElement) = 0;
0125     virtual void endedActiveInterval() = 0;
0126 
0127     enum BeginOrEnd { Begin, End };
0128     SMILTime findInstanceTime(BeginOrEnd beginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
0129     void resolveFirstInterval();
0130     void resolveNextInterval();
0131     void resolveInterval(bool first, SMILTime &beginResult, SMILTime &endResult) const;
0132     SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
0133     SMILTime repeatingDuration() const;
0134     void checkRestart(SMILTime elapsed);
0135     void beginListChanged();
0136     void endListChanged();
0137     void reschedule();
0138 
0139     // This represents conditions on elements begin or end list that need to be resolved on runtime
0140     // for example <animate begin="otherElement.begin + 8s; button.click" ... />
0141     struct Condition {
0142         enum Type { EventBase, Syncbase, AccessKey };
0143         Condition(Type, BeginOrEnd beginOrEnd, const String &baseID, const String &name, SMILTime offset, int repeats = -1);
0144         Type m_type;
0145         BeginOrEnd m_beginOrEnd;
0146         String m_baseID;
0147         String m_name;
0148         SMILTime m_offset;
0149         int m_repeats;
0150         RefPtr<Element> m_syncbase;
0151         RefPtr<ConditionEventListener> m_eventListener;
0152     };
0153     bool parseCondition(const String &, BeginOrEnd beginOrEnd);
0154     void parseBeginOrEnd(const String &, BeginOrEnd beginOrEnd);
0155 
0156     void connectConditions();
0157     void disconnectConditions();
0158 
0159     // Event base timing
0160     void handleConditionEvent(Event *, Condition *);
0161 
0162     // Syncbase timing
0163     enum NewOrExistingInterval { NewInterval, ExistingInterval };
0164     void notifyDependentsIntervalChanged(NewOrExistingInterval);
0165     void createInstanceTimesFromSyncbase(SVGSMILElement *syncbase, NewOrExistingInterval);
0166     void addTimeDependent(SVGSMILElement *);
0167     void removeTimeDependent(SVGSMILElement *);
0168 
0169     enum ActiveState { Inactive, Active, Frozen };
0170     ActiveState determineActiveState(SMILTime elapsed) const;
0171     float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned &repeat) const;
0172     SMILTime calculateNextProgressTime(SMILTime elapsed) const;
0173 
0174     Vector<Condition> m_conditions;
0175     bool m_conditionsConnected;
0176     bool m_hasEndEventConditions;
0177 
0178     typedef HashSet<SVGSMILElement *> TimeDependentSet;
0179     TimeDependentSet m_timeDependents;
0180 
0181     // Instance time lists
0182     Vector<SMILTime> m_beginTimes;
0183     Vector<SMILTime> m_endTimes;
0184 
0185     // This is the upcoming or current interval
0186     SMILTime m_intervalBegin;
0187     SMILTime m_intervalEnd;
0188 
0189     SMILTime m_previousIntervalBegin;
0190 
0191     bool m_isWaitingForFirstInterval;
0192 
0193     ActiveState m_activeState;
0194     float m_lastPercent;
0195     unsigned m_lastRepeat;
0196 
0197     SMILTime m_nextProgressTime;
0198 
0199     RefPtr<SMILTimeContainer> m_timeContainer;
0200     unsigned m_documentOrderIndex;
0201 
0202     mutable SMILTime m_cachedDur;
0203     mutable SMILTime m_cachedRepeatDur;
0204     mutable SMILTime m_cachedRepeatCount;
0205     mutable SMILTime m_cachedMin;
0206     mutable SMILTime m_cachedMax;
0207 
0208     friend class ConditionEventListener;
0209 };
0210 
0211 }
0212 
0213 #endif
0214 #endif
0215