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     {
     40     }
     41 
     42     template<typename ConstructorParameter1>
     43     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
     44         : value(value1)
     45         , shouldSynchronize(false)
     46     {
     47     }
     48 
     49     template<typename ConstructorParameter1, typename ConstructorParameter2>
     50     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
     51         : value(value1, value2)
     52         , shouldSynchronize(false)
     53     {
     54     }
     55 
     56     void synchronize(Element* ownerElement, const QualifiedName& attrName, const AtomicString& value)
     57     {
     58         ownerElement->setSynchronizedLazyAttribute(attrName, value);
     59     }
     60 
     61     PropertyType value;
     62     bool shouldSynchronize : 1;
     63 };
     64 
     65 // Property registration helpers
     66 #define BEGIN_REGISTER_ANIMATED_PROPERTIES(OwnerType) \
     67 SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \
     68 { \
     69     DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, s_attributeToPropertyMap, ()); \
     70     return s_attributeToPropertyMap; \
     71 } \
     72 \
     73 SVGAttributeToPropertyMap& OwnerType::localAttributeToPropertyMap() const \
     74 { \
     75     return attributeToPropertyMap(); \
     76 } \
     77 \
     78 void OwnerType::registerAnimatedPropertiesFor##OwnerType() \
     79 { \
     80     OwnerType::m_cleanupAnimatedPropertiesCaller.setOwner(this); \
     81     SVGAttributeToPropertyMap& map = OwnerType::attributeToPropertyMap(); \
     82     if (!map.isEmpty()) \
     83         return; \
     84     typedef OwnerType UseOwnerType;
     85 
     86 #define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) \
     87      map.addProperty(UseOwnerType::LowerProperty##PropertyInfo());
     88 
     89 #define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) \
     90      map.addProperties(ClassName::attributeToPropertyMap()); \
     91 
     92 #define END_REGISTER_ANIMATED_PROPERTIES }
     93 
     94 // Property definition helpers (used in SVG*.cpp files)
     95 #define DEFINE_ANIMATED_PROPERTY(AnimatedPropertyTypeEnum, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, TearOffType, PropertyType) \
     96 const SVGPropertyInfo* OwnerType::LowerProperty##PropertyInfo() { \
     97     DEFINE_STATIC_LOCAL(const SVGPropertyInfo, s_propertyInfo, \
     98                         (AnimatedPropertyTypeEnum, \
     99                          PropertyIsReadWrite, \
    100                          DOMAttribute, \
    101                          SVGDOMAttributeIdentifier, \
    102                          &OwnerType::synchronize##UpperProperty, \
    103                          &OwnerType::lookupOrCreate##UpperProperty##Wrapper)); \
    104     return &s_propertyInfo; \
    105 } \
    106 PropertyType& OwnerType::LowerProperty##CurrentValue() const \
    107 { \
    108     if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \
    109         if (wrapper->isAnimating()) \
    110             return wrapper->currentAnimatedValue(); \
    111     } \
    112     return m_##LowerProperty.value; \
    113 } \
    114 \
    115 PropertyType& OwnerType::LowerProperty##BaseValue() const \
    116 { \
    117     return m_##LowerProperty.value; \
    118 } \
    119 \
    120 void OwnerType::set##UpperProperty##BaseValue(const PropertyType& type) \
    121 { \
    122     m_##LowerProperty.value = type; \
    123 } \
    124 \
    125 PassRefPtr<TearOffType> OwnerType::LowerProperty() \
    126 { \
    127     m_##LowerProperty.shouldSynchronize = true; \
    128     return static_pointer_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \
    129 } \
    130 \
    131 void OwnerType::synchronize##UpperProperty() \
    132 { \
    133     if (!m_##LowerProperty.shouldSynchronize) \
    134         return; \
    135     AtomicString value(SVGPropertyTraits<PropertyType>::toString(m_##LowerProperty.value)); \
    136     m_##LowerProperty.synchronize(this, LowerProperty##PropertyInfo()->attributeName, value); \
    137 } \
    138 \
    139 PassRefPtr<SVGAnimatedProperty> OwnerType::lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType) \
    140 { \
    141     ASSERT(maskedOwnerType); \
    142     UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
    143     return SVGAnimatedProperty::lookupOrCreateWrapper<UseOwnerType, TearOffType, PropertyType>(ownerType, LowerProperty##PropertyInfo(), ownerType->m_##LowerProperty.value); \
    144 } \
    145 \
    146 void OwnerType::synchronize##UpperProperty(SVGElement* maskedOwnerType) \
    147 { \
    148     ASSERT(maskedOwnerType); \
    149     UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
    150     ownerType->synchronize##UpperProperty(); \
    151 }
    152 
    153 // Property declaration helpers (used in SVG*.h files)
    154 #define BEGIN_DECLARE_ANIMATED_PROPERTIES(OwnerType) \
    155 public: \
    156     static SVGAttributeToPropertyMap& attributeToPropertyMap(); \
    157     virtual SVGAttributeToPropertyMap& localAttributeToPropertyMap() const; \
    158     void registerAnimatedPropertiesFor##OwnerType(); \
    159     typedef OwnerType UseOwnerType;
    160 
    161 #define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
    162 public: \
    163     static const SVGPropertyInfo* LowerProperty##PropertyInfo(); \
    164     PropertyType& LowerProperty##CurrentValue() const; \
    165     PropertyType& LowerProperty##BaseValue() const; \
    166     void set##UpperProperty##BaseValue(const PropertyType& type); \
    167     PassRefPtr<TearOffType> LowerProperty(); \
    168 \
    169 private: \
    170     void synchronize##UpperProperty(); \
    171     static PassRefPtr<SVGAnimatedProperty> lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType); \
    172     static void synchronize##UpperProperty(SVGElement* maskedOwnerType); \
    173 \
    174     mutable SVGSynchronizableAnimatedProperty<PropertyType> m_##LowerProperty;
    175 
    176 #define END_DECLARE_ANIMATED_PROPERTIES \
    177     CleanUpAnimatedPropertiesCaller m_cleanupAnimatedPropertiesCaller;
    178 
    179 // List specific definition/declaration helpers
    180 #define DECLARE_ANIMATED_LIST_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
    181 DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
    182 void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \
    183 { \
    184     if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) \
    185         wrapper->detachListWrappers(newListSize); \
    186 }
    187 
    188 }
    189 
    190 #endif // SVGAnimatedPropertyMacros_h
    191