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