Home | History | Annotate | Download | only in animation
      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 
     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 
     77         SMILTime intervalBegin() const { return m_intervalBegin; }
     78         SMILTime intervalEnd() const { return m_intervalEnd; }
     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 
     92         unsigned documentOrderIndex() const { return m_documentOrderIndex; }
     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