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