• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005 Rob Buis <buis@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 {
SVGSynchronizableAnimatedPropertySVGSynchronizableAnimatedProperty36     SVGSynchronizableAnimatedProperty()
37         : value(SVGPropertyTraits<PropertyType>::initialValue())
38         , shouldSynchronize(false)
39     {
40     }
41 
42     template<typename ConstructorParameter1>
SVGSynchronizableAnimatedPropertySVGSynchronizableAnimatedProperty43     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
44         : value(value1)
45         , shouldSynchronize(false)
46     {
47     }
48 
49     template<typename ConstructorParameter1, typename ConstructorParameter2>
SVGSynchronizableAnimatedPropertySVGSynchronizableAnimatedProperty50     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
51         : value(value1, value2)
52         , shouldSynchronize(false)
53     {
54     }
55 
synchronizeSVGSynchronizableAnimatedProperty56     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