1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/*
2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This library is free software; you can redistribute it and/or
7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * modify it under the terms of the GNU Library General Public
8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * License as published by the Free Software Foundation; either
9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * version 2 of the License, or (at your option) any later version.
10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This library is distributed in the hope that it will be useful,
12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Library General Public License for more details.
15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project *
16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * You should have received a copy of the GNU Library General Public License
17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Boston, MA 02110-1301, USA.
20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#ifndef SVGAnimatedPropertyMacros_h
23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#define SVGAnimatedPropertyMacros_h
24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "core/dom/Element.h"
26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "core/svg/properties/SVGAnimatedProperty.h"
27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "core/svg/properties/SVGAttributeToPropertyMap.h"
28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "core/svg/properties/SVGPropertyTraits.h"
29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project#include "wtf/StdLibExtras.h"
30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectnamespace WebCore {
32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project// SVGSynchronizableAnimatedProperty implementation
34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projecttemplate<typename PropertyType>
35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectstruct SVGSynchronizableAnimatedProperty {
36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    SVGSynchronizableAnimatedProperty()
37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        : value(SVGPropertyTraits<PropertyType>::initialValue())
38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        , shouldSynchronize(false)
39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        , isValid(false)
40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    {
41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    template<typename ConstructorParameter1>
44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        : value(value1)
46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        , shouldSynchronize(false)
47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        , isValid(false)
48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    {
49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    template<typename ConstructorParameter1, typename ConstructorParameter2>
52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        : value(value1, value2)
54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        , shouldSynchronize(false)
55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        , isValid(false)
56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    {
57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    void synchronize(Element* ownerElement, const QualifiedName& attrName, const AtomicString& value)
60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    {
61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        ownerElement->setSynchronizedLazyAttribute(attrName, value);
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
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) \
71SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \
72{ \
73    DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, s_attributeToPropertyMap, ()); \
74    return s_attributeToPropertyMap; \
75} \
76\
77SVGAttributeToPropertyMap& OwnerType::localAttributeToPropertyMap() const \
78{ \
79    return attributeToPropertyMap(); \
80} \
81\
82static 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) \
99const 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} \
109PropertyType& 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\
118PropertyType& OwnerType::LowerProperty##BaseValue() const \
119{ \
120    return m_##LowerProperty.value; \
121} \
122\
123void OwnerType::set##UpperProperty##BaseValue(const PropertyType& type, const bool validValue) \
124{ \
125    m_##LowerProperty.value = type; \
126    m_##LowerProperty.isValid = validValue; \
127} \
128\
129PassRefPtr<TearOffType> OwnerType::LowerProperty() \
130{ \
131    m_##LowerProperty.shouldSynchronize = true; \
132    return static_pointer_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \
133} \
134\
135bool OwnerType::LowerProperty##IsValid() const \
136{ \
137    return m_##LowerProperty.isValid; \
138} \
139\
140void 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\
148PassRefPtr<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\
155void 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) \
164public: \
165    static SVGAttributeToPropertyMap& attributeToPropertyMap(); \
166    virtual SVGAttributeToPropertyMap& localAttributeToPropertyMap() const; \
167    typedef OwnerType UseOwnerType;
168
169#define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
170public: \
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\
178private: \
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) \
189DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
190void 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