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