Home | History | Annotate | Download | only in properties
      1 /*
      2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005 Rob Buis <buis (at) kde.org>
      4  * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Library General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Library General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Library General Public License
     17  * along with this library; see the file COPYING.LIB.  If not, write to
     18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  * Boston, MA 02110-1301, USA.
     20  */
     21 
     22 #ifndef SVGAnimatedPropertyMacros_h
     23 #define SVGAnimatedPropertyMacros_h
     24 
     25 #include "core/dom/Element.h"
     26 #include "core/svg/properties/SVGAnimatedProperty.h"
     27 #include "core/svg/properties/SVGAttributeToPropertyMap.h"
     28 #include "core/svg/properties/SVGPropertyTraits.h"
     29 #include "wtf/StdLibExtras.h"
     30 
     31 namespace WebCore {
     32 
     33 // SVGSynchronizableAnimatedProperty implementation
     34 template<typename PropertyType>
     35 struct SVGSynchronizableAnimatedProperty {
     36     SVGSynchronizableAnimatedProperty()
     37         : value(SVGPropertyTraits<PropertyType>::initialValue())
     38         , shouldSynchronize(false)
     39         , isValid(false)
     40     {
     41     }
     42 
     43     template<typename ConstructorParameter1>
     44     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
     45         : value(value1)
     46         , shouldSynchronize(false)
     47         , isValid(false)
     48     {
     49     }
     50 
     51     template<typename ConstructorParameter1, typename ConstructorParameter2>
     52     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
     53         : value(value1, value2)
     54         , shouldSynchronize(false)
     55         , isValid(false)
     56     {
     57     }
     58 
     59     void synchronize(Element* ownerElement, const QualifiedName& attrName, const AtomicString& value)
     60     {
     61         ownerElement->setSynchronizedLazyAttribute(attrName, value);
     62     }
     63 
     64     PropertyType value;
     65     bool shouldSynchronize : 1;
     66     bool isValid : 1;
     67 };
     68 
     69 // Property registration helpers
     70 #define BEGIN_REGISTER_ANIMATED_PROPERTIES(OwnerType) \
     71 SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \
     72 { \
     73     DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, s_attributeToPropertyMap, ()); \
     74     return s_attributeToPropertyMap; \
     75 } \
     76 \
     77 SVGAttributeToPropertyMap& OwnerType::localAttributeToPropertyMap() const \
     78 { \
     79     return attributeToPropertyMap(); \
     80 } \
     81 \
     82 static void registerAnimatedPropertiesFor##OwnerType() \
     83 { \
     84     SVGAttributeToPropertyMap& map = OwnerType::attributeToPropertyMap(); \
     85     if (!map.isEmpty()) \
     86         return; \
     87     typedef OwnerType UseOwnerType;
     88 
     89 #define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) \
     90      map.addProperty(UseOwnerType::LowerProperty##PropertyInfo());
     91 
     92 #define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) \
     93      map.addProperties(ClassName::attributeToPropertyMap()); \
     94 
     95 #define END_REGISTER_ANIMATED_PROPERTIES }
     96 
     97 // Property definition helpers (used in SVG*.cpp files)
     98 #define DEFINE_ANIMATED_PROPERTY(AnimatedPropertyTypeEnum, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, TearOffType, PropertyType) \
     99 const SVGPropertyInfo* OwnerType::LowerProperty##PropertyInfo() { \
    100     DEFINE_STATIC_LOCAL(const SVGPropertyInfo, s_propertyInfo, \
    101                         (AnimatedPropertyTypeEnum, \
    102                          PropertyIsReadWrite, \
    103                          DOMAttribute, \
    104                          SVGDOMAttributeIdentifier, \
    105                          &OwnerType::synchronize##UpperProperty, \
    106                          &OwnerType::lookupOrCreate##UpperProperty##Wrapper)); \
    107     return &s_propertyInfo; \
    108 } \
    109 PropertyType& OwnerType::LowerProperty##CurrentValue() const \
    110 { \
    111     if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \
    112         if (wrapper->isAnimating()) \
    113             return wrapper->currentAnimatedValue(); \
    114     } \
    115     return m_##LowerProperty.value; \
    116 } \
    117 \
    118 PropertyType& OwnerType::LowerProperty##BaseValue() const \
    119 { \
    120     return m_##LowerProperty.value; \
    121 } \
    122 \
    123 void OwnerType::set##UpperProperty##BaseValue(const PropertyType& type, const bool validValue) \
    124 { \
    125     m_##LowerProperty.value = type; \
    126     m_##LowerProperty.isValid = validValue; \
    127 } \
    128 \
    129 PassRefPtr<TearOffType> OwnerType::LowerProperty() \
    130 { \
    131     m_##LowerProperty.shouldSynchronize = true; \
    132     return static_pointer_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \
    133 } \
    134 \
    135 bool OwnerType::LowerProperty##IsValid() const \
    136 { \
    137     return m_##LowerProperty.isValid; \
    138 } \
    139 \
    140 void OwnerType::synchronize##UpperProperty() \
    141 { \
    142     if (!m_##LowerProperty.shouldSynchronize) \
    143         return; \
    144     AtomicString value(SVGPropertyTraits<PropertyType>::toString(m_##LowerProperty.value)); \
    145     m_##LowerProperty.synchronize(this, LowerProperty##PropertyInfo()->attributeName, value); \
    146 } \
    147 \
    148 PassRefPtr<SVGAnimatedProperty> OwnerType::lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType) \
    149 { \
    150     ASSERT(maskedOwnerType); \
    151     UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
    152     return SVGAnimatedProperty::lookupOrCreateWrapper<UseOwnerType, TearOffType, PropertyType>(ownerType, LowerProperty##PropertyInfo(), ownerType->m_##LowerProperty.value); \
    153 } \
    154 \
    155 void OwnerType::synchronize##UpperProperty(SVGElement* maskedOwnerType) \
    156 { \
    157     ASSERT(maskedOwnerType); \
    158     UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
    159     ownerType->synchronize##UpperProperty(); \
    160 }
    161 
    162 // Property declaration helpers (used in SVG*.h files)
    163 #define BEGIN_DECLARE_ANIMATED_PROPERTIES(OwnerType) \
    164 public: \
    165     static SVGAttributeToPropertyMap& attributeToPropertyMap(); \
    166     virtual SVGAttributeToPropertyMap& localAttributeToPropertyMap() const; \
    167     typedef OwnerType UseOwnerType;
    168 
    169 #define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
    170 public: \
    171     static const SVGPropertyInfo* LowerProperty##PropertyInfo(); \
    172     PropertyType& LowerProperty##CurrentValue() const; \
    173     PropertyType& LowerProperty##BaseValue() const; \
    174     void set##UpperProperty##BaseValue(const PropertyType& type, const bool = true); \
    175     PassRefPtr<TearOffType> LowerProperty(); \
    176     bool LowerProperty##IsValid() const; \
    177 \
    178 private: \
    179     void synchronize##UpperProperty(); \
    180     static PassRefPtr<SVGAnimatedProperty> lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType); \
    181     static void synchronize##UpperProperty(SVGElement* maskedOwnerType); \
    182 \
    183     mutable SVGSynchronizableAnimatedProperty<PropertyType> m_##LowerProperty;
    184 
    185 #define END_DECLARE_ANIMATED_PROPERTIES
    186 
    187 // List specific definition/declaration helpers
    188 #define DECLARE_ANIMATED_LIST_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
    189 DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
    190 void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \
    191 { \
    192     if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) \
    193         wrapper->detachListWrappers(newListSize); \
    194 }
    195 
    196 }
    197 
    198 #endif // SVGAnimatedPropertyMacros_h
    199