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. 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 #if ENABLE(SVG)
26 #include "SVGAnimatedPropertySynchronizer.h"
27 #include "SVGPropertyTraits.h"
28 
29 namespace WebCore {
30 
31 // GetOwnerElementForType implementation
32 template<typename OwnerType, bool isDerivedFromSVGElement>
33 struct GetOwnerElementForType;
34 
35 template<typename OwnerType>
36 struct GetOwnerElementForType<OwnerType, true> {
37     static SVGElement* ownerElement(OwnerType* type)
38     {
39         return type;
40     }
41 };
42 
43 template<typename OwnerType>
44 struct GetOwnerElementForType<OwnerType, false> {
45     static SVGElement* ownerElement(OwnerType* type)
46     {
47         SVGElement* context = type->contextElement();
48         ASSERT(context);
49         return context;
50     }
51 };
52 
53 // IsDerivedFromSVGElement implementation
54 template<typename OwnerType>
55 struct IsDerivedFromSVGElement {
56     static const bool value = true;
57 };
58 
59 class SVGViewSpec;
60 template<>
61 struct IsDerivedFromSVGElement<SVGViewSpec> {
62     static const bool value = false;
63 };
64 
65 // SVGSynchronizableAnimatedProperty implementation
66 template<typename PropertyType>
67 struct SVGSynchronizableAnimatedProperty {
68     SVGSynchronizableAnimatedProperty()
69         : value(SVGPropertyTraits<PropertyType>::initialValue())
70         , shouldSynchronize(false)
71     {
72     }
73 
74     template<typename ConstructorParameter1>
75     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
76         : value(value1)
77         , shouldSynchronize(false)
78     {
79     }
80 
81     template<typename ConstructorParameter1, typename ConstructorParameter2>
82     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
83         : value(value1, value2)
84         , shouldSynchronize(false)
85     {
86     }
87 
88     PropertyType value;
89     bool shouldSynchronize : 1;
90 };
91 
92 #define DEFINE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, TearOffType, PropertyType, UpperProperty, LowerProperty) \
93 void OwnerType::synchronize##UpperProperty() \
94 { \
95     if (!m_##LowerProperty.shouldSynchronize) \
96          return; \
97     AtomicString value(SVGPropertyTraits<PropertyType>::toString(LowerProperty##BaseValue())); \
98     SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
99     SVGAnimatedPropertySynchronizer<IsDerivedFromSVGElement<OwnerType>::value>::synchronize(contextElement, DOMAttribute, value); \
100 } \
101 \
102 PassRefPtr<TearOffType> OwnerType::LowerProperty##Animated() \
103 { \
104     m_##LowerProperty.shouldSynchronize = true; \
105     SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
106     return SVGAnimatedProperty::lookupOrCreateWrapper<TearOffType, PropertyType>(contextElement, DOMAttribute, SVGDOMAttributeIdentifier, m_##LowerProperty.value); \
107 }
108 
109 #define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
110 public: \
111 PropertyType& LowerProperty() const \
112 { \
113     return m_##LowerProperty.value; \
114 } \
115 \
116 PropertyType& LowerProperty##BaseValue() const \
117 { \
118     return m_##LowerProperty.value; \
119 } \
120 \
121 void set##UpperProperty##BaseValue(const PropertyType& type) \
122 { \
123     m_##LowerProperty.value = type; \
124 } \
125 \
126 PassRefPtr<TearOffType> LowerProperty##Animated(); \
127 \
128 private: \
129     void synchronize##UpperProperty(); \
130 \
131     mutable SVGSynchronizableAnimatedProperty<PropertyType> m_##LowerProperty;
132 
133 #define DECLARE_ANIMATED_LIST_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
134 DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
135 void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize);
136 
137 #define DEFINE_ANIMATED_LIST_PROPERTY(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, TearOffType, PropertyType, UpperProperty, LowerProperty) \
138 DEFINE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, TearOffType, PropertyType, UpperProperty, LowerProperty) \
139 void OwnerType::detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \
140 { \
141     SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
142     SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<TearOffType>(contextElement, DOMAttribute.localName()); \
143     if (!wrapper) \
144         return; \
145     static_cast<TearOffType*>(wrapper)->detachListWrappers(newListSize); \
146 }
147 
148 }
149 
150 #endif // ENABLE(SVG)
151 #endif // SVGAnimatedPropertyMacros_h
152