Home | History | Annotate | Download | only in svg
      1 /*
      2     Copyright (C) 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3     Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Library General Public
      7     License as published by the Free Software Foundation; either
      8     version 2 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Library General Public License for more details.
     14 
     15     You should have received a copy of the GNU Library General Public License
     16     along with this library; see the file COPYING.LIB.  If not, write to
     17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18     Boston, MA 02110-1301, USA.
     19 */
     20 
     21 #ifndef SVGAnimatedProperty_h
     22 #define SVGAnimatedProperty_h
     23 
     24 #if ENABLE(SVG)
     25 #include "SVGAnimatedPropertySynchronizer.h"
     26 #include "SVGAnimatedPropertyTraits.h"
     27 #include "SVGAnimatedTemplate.h"
     28 
     29 namespace WebCore {
     30 
     31 template<typename AnimatedType>
     32 class SVGAnimatedProperty;
     33 
     34 template<typename AnimatedType>
     35 class SVGAnimatedPropertyTearOff : public SVGAnimatedTemplate<AnimatedType> {
     36 public:
     37     typedef typename SVGAnimatedPropertyTraits<AnimatedType>::PassType PassType;
     38     typedef typename SVGAnimatedPropertyTraits<AnimatedType>::ReturnType ReturnType;
     39 
     40     typedef SVGAnimatedPropertyTearOff<AnimatedType> Self;
     41     typedef SVGAnimatedProperty<AnimatedType> Creator;
     42 
     43     static PassRefPtr<Self> create(Creator& creator, SVGElement* contextElement)
     44     {
     45         return adoptRef(new Self(creator, contextElement));
     46     }
     47 
     48     virtual void setBaseVal(PassType type)
     49     {
     50         m_creator.setBaseValue(type);
     51         m_contextElement->setSynchronizedSVGAttributes(false);
     52     }
     53 
     54     virtual void setAnimVal(PassType type)
     55     {
     56         m_creator.setValue(type);
     57         m_contextElement->setSynchronizedSVGAttributes(false);
     58     }
     59 
     60     virtual ReturnType baseVal() const { return m_creator.baseValue(); }
     61     virtual ReturnType animVal() const { return m_creator.value(); }
     62     virtual const QualifiedName& associatedAttributeName() const { return m_creator.associatedAttributeName(); }
     63 
     64 private:
     65     SVGAnimatedPropertyTearOff(Creator& creator, SVGElement* contextElement)
     66         : m_creator(creator)
     67         , m_contextElement(contextElement)
     68     {
     69         m_creator.setShouldSynchronize(true);
     70     }
     71 
     72     virtual ~SVGAnimatedPropertyTearOff()
     73     {
     74         m_creator.setShouldSynchronize(false);
     75     }
     76 
     77     Creator& m_creator;
     78     RefPtr<SVGElement> m_contextElement;
     79 };
     80 
     81 template<typename AnimatedType>
     82 class SVGAnimatedProperty {
     83 public:
     84     virtual ~SVGAnimatedProperty() { }
     85 
     86     typedef typename SVGAnimatedPropertyTraits<AnimatedType>::PassType PassType;
     87     typedef typename SVGAnimatedPropertyTraits<AnimatedType>::ReturnType ReturnType;
     88     typedef typename SVGAnimatedPropertyTraits<AnimatedType>::StoredType StoredType;
     89 
     90     SVGAnimatedProperty()
     91         : m_value(SVGAnimatedPropertyTraits<AnimatedType>::null())
     92         , m_shouldSynchronize(false)
     93     {
     94     }
     95 
     96     template<typename ConstructorParameterOne>
     97     SVGAnimatedProperty(const ConstructorParameterOne& value1)
     98         : m_value(value1)
     99         , m_shouldSynchronize(false)
    100     {
    101     }
    102 
    103     template<typename ConstructorParameterOne, typename ConstructorParameterTwo>
    104     SVGAnimatedProperty(const ConstructorParameterOne& value1, const ConstructorParameterTwo& value2)
    105         : m_value(value1, value2)
    106         , m_shouldSynchronize(false)
    107     {
    108     }
    109 
    110     ReturnType value() const { return SVGAnimatedPropertyTraits<AnimatedType>::toReturnType(m_value); }
    111     ReturnType baseValue() const { return SVGAnimatedPropertyTraits<AnimatedType>::toReturnType(m_value); }
    112 
    113     void setValue(PassType type) { m_value = type; }
    114     void setBaseValue(PassType type) { m_value = type; }
    115 
    116     bool shouldSynchronize() const { return m_shouldSynchronize; }
    117     void setShouldSynchronize(bool value) { m_shouldSynchronize = value; }
    118 
    119     virtual const QualifiedName& associatedAttributeName() const = 0;
    120 
    121 protected:
    122     StoredType m_value;
    123     bool m_shouldSynchronize;
    124 };
    125 
    126 };
    127 
    128 // Helper macro used within DECLARE_ANIMATED_PROPERTY below
    129 #define DEFINE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, AnimatedType, UpperProperty) \
    130 class SVGAnimatedProperty##UpperProperty : public SVGAnimatedProperty<AnimatedType> { \
    131 public: \
    132     SVGAnimatedProperty##UpperProperty() \
    133         : SVGAnimatedProperty<AnimatedType>() \
    134     { \
    135     } \
    136     \
    137     template<typename ConstructorParameterOne> \
    138     SVGAnimatedProperty##UpperProperty(const ConstructorParameterOne& value1) \
    139         : SVGAnimatedProperty<AnimatedType>(value1) \
    140     { \
    141     } \
    142     \
    143     template<typename ConstructorParameterOne, typename ConstructorParameterTwo> \
    144     SVGAnimatedProperty##UpperProperty(const ConstructorParameterOne& value1, const ConstructorParameterTwo& value2) \
    145         : SVGAnimatedProperty<AnimatedType>(value1, value2) \
    146     { \
    147     } \
    148     \
    149     void synchronize(SVGElement* contextElement) \
    150     { \
    151         ASSERT(m_shouldSynchronize); \
    152         AtomicString value(SVGAnimatedPropertyTraits<AnimatedType>::toString(baseValue())); \
    153         SVGAnimatedPropertySynchronizer<IsDerivedFromSVGElement<OwnerType>::value>::synchronize(contextElement, DOMAttribute, value); \
    154     } \
    155     \
    156     virtual const QualifiedName& associatedAttributeName() const \
    157     { \
    158         return DOMAttribute; \
    159     } \
    160 }
    161 
    162 // Helper macro shared by DECLARE_ANIMATED_PROPERTY / DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS
    163 #define DECLARE_ANIMATED_PROPERTY_SHARED(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, AnimatedType, UpperProperty, LowerProperty) \
    164 private: \
    165     typedef SVGAnimatedPropertyTearOff<AnimatedType> SVGAnimatedPropertyTearOff##UpperProperty; \
    166     DEFINE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, AnimatedType, UpperProperty); \
    167     SVGAnimatedProperty##UpperProperty m_##LowerProperty; \
    168     \
    169 public: \
    170     SVGAnimatedPropertyTraits<AnimatedType>::ReturnType LowerProperty() const \
    171     { \
    172         return m_##LowerProperty.value(); \
    173     } \
    174     \
    175     SVGAnimatedPropertyTraits<AnimatedType>::ReturnType LowerProperty##BaseValue() const \
    176     { \
    177         return m_##LowerProperty.baseValue(); \
    178     } \
    179     \
    180     void set##UpperProperty(SVGAnimatedPropertyTraits<AnimatedType>::PassType type) \
    181     { \
    182         m_##LowerProperty.setValue(type); \
    183         SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
    184         contextElement->setSynchronizedSVGAttributes(false); \
    185     } \
    186     \
    187     void set##UpperProperty##BaseValue(SVGAnimatedPropertyTraits<AnimatedType>::PassType type) \
    188     { \
    189         m_##LowerProperty.setBaseValue(type); \
    190         SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
    191         contextElement->setSynchronizedSVGAttributes(false); \
    192     } \
    193     \
    194     void synchronize##UpperProperty() \
    195     { \
    196         if (!m_##LowerProperty.shouldSynchronize()) \
    197             return; \
    198         SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
    199         m_##LowerProperty.synchronize(contextElement); \
    200     } \
    201     \
    202     PassRefPtr<SVGAnimatedPropertyTearOff##UpperProperty> LowerProperty##Animated() \
    203     { \
    204         SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
    205         return lookupOrCreateWrapper<AnimatedType, SVGAnimatedPropertyTearOff##UpperProperty>(contextElement, m_##LowerProperty, DOMAttribute); \
    206     }
    207 
    208 // Used for SVG DOM properties that map exactly to one XML DOM attribute
    209 #define DECLARE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, AnimatedType, UpperProperty, LowerProperty) \
    210 DECLARE_ANIMATED_PROPERTY_SHARED(OwnerType, DOMAttribute, DOMAttribute.localName(), AnimatedType, UpperProperty, LowerProperty)
    211 
    212 // Used for the rare case multiple SVG DOM properties that map to the same XML dom attribute
    213 #define DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, AnimatedType, UpperProperty, LowerProperty) \
    214 DECLARE_ANIMATED_PROPERTY_SHARED(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, AnimatedType, UpperProperty, LowerProperty)
    215 
    216 #endif
    217 #endif
    218