1 /* 2 Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann (at) kde.org> 3 2004, 2005 Rob Buis <buis (at) kde.org> 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 SVGAnimatedTemplate_h 22 #define SVGAnimatedTemplate_h 23 24 #if ENABLE(SVG) 25 #include "SVGAnimatedPropertyTraits.h" 26 #include <wtf/HashMap.h> 27 28 namespace WebCore { 29 30 class SVGAngle; 31 class SVGElement; 32 class SVGLengthList; 33 class SVGNumberList; 34 class SVGPreserveAspectRatio; 35 class SVGTransformList; 36 class String; 37 class QualifiedName; 38 39 struct SVGAnimatedTypeWrapperKey { 40 // Empty value 41 SVGAnimatedTypeWrapperKey() 42 : element(0) 43 , attributeName(0) 44 { } 45 46 // Deleted value 47 SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValueType) 48 : element(reinterpret_cast<SVGElement*>(-1)) 49 { 50 } 51 52 bool isHashTableDeletedValue() const 53 { 54 return element == reinterpret_cast<SVGElement*>(-1); 55 } 56 57 SVGAnimatedTypeWrapperKey(const SVGElement* _element, const AtomicString& _attributeName) 58 : element(_element) 59 , attributeName(_attributeName.impl()) 60 { 61 ASSERT(element); 62 ASSERT(attributeName); 63 } 64 65 bool operator==(const SVGAnimatedTypeWrapperKey& other) const 66 { 67 return element == other.element && attributeName == other.attributeName; 68 } 69 70 const SVGElement* element; 71 AtomicStringImpl* attributeName; 72 }; 73 74 struct SVGAnimatedTypeWrapperKeyHash { 75 static unsigned hash(const SVGAnimatedTypeWrapperKey& key) 76 { 77 return StringImpl::computeHash(reinterpret_cast<const UChar*>(&key), sizeof(SVGAnimatedTypeWrapperKey) / sizeof(UChar)); 78 } 79 80 static bool equal(const SVGAnimatedTypeWrapperKey& a, const SVGAnimatedTypeWrapperKey& b) 81 { 82 return a == b; 83 } 84 85 static const bool safeToCompareToEmptyOrDeleted = true; 86 }; 87 88 struct SVGAnimatedTypeWrapperKeyHashTraits : WTF::GenericHashTraits<SVGAnimatedTypeWrapperKey> { 89 static const bool emptyValueIsZero = true; 90 91 static void constructDeletedValue(SVGAnimatedTypeWrapperKey& slot) 92 { 93 new (&slot) SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValue); 94 } 95 96 static bool isDeletedValue(const SVGAnimatedTypeWrapperKey& value) 97 { 98 return value.isHashTableDeletedValue(); 99 } 100 }; 101 102 template<typename AnimatedType> 103 class SVGAnimatedTemplate : public RefCounted<SVGAnimatedTemplate<AnimatedType> > { 104 public: 105 typedef typename SVGAnimatedPropertyTraits<AnimatedType>::PassType PassType; 106 typedef typename SVGAnimatedPropertyTraits<AnimatedType>::ReturnType ReturnType; 107 108 virtual ~SVGAnimatedTemplate() { forgetWrapper(this); } 109 110 virtual ReturnType baseVal() const = 0; 111 virtual void setBaseVal(PassType) = 0; 112 113 virtual ReturnType animVal() const = 0; 114 virtual void setAnimVal(PassType) = 0; 115 116 virtual const QualifiedName& associatedAttributeName() const = 0; 117 118 typedef HashMap<SVGAnimatedTypeWrapperKey, SVGAnimatedTemplate<AnimatedType>*, SVGAnimatedTypeWrapperKeyHash, SVGAnimatedTypeWrapperKeyHashTraits > ElementToWrapperMap; 119 typedef typename ElementToWrapperMap::const_iterator ElementToWrapperMapIterator; 120 121 static ElementToWrapperMap* wrapperCache() 122 { 123 static ElementToWrapperMap* s_wrapperCache = new ElementToWrapperMap; 124 return s_wrapperCache; 125 } 126 127 static void forgetWrapper(SVGAnimatedTemplate<AnimatedType>* wrapper) 128 { 129 ElementToWrapperMap* cache = wrapperCache(); 130 ElementToWrapperMapIterator itr = cache->begin(); 131 ElementToWrapperMapIterator end = cache->end(); 132 for (; itr != end; ++itr) { 133 if (itr->second == wrapper) { 134 cache->remove(itr->first); 135 break; 136 } 137 } 138 } 139 }; 140 141 template<typename AnimatedType> 142 class SVGAnimatedProperty; 143 144 template<typename AnimatedType, typename AnimatedTearOff> 145 PassRefPtr<AnimatedTearOff> lookupOrCreateWrapper(SVGElement* element, SVGAnimatedProperty<AnimatedType>& creator, const QualifiedName& attrName) 146 { 147 SVGAnimatedTypeWrapperKey key(element, attrName.localName()); 148 RefPtr<AnimatedTearOff> wrapper = static_cast<AnimatedTearOff*>(AnimatedTearOff::wrapperCache()->get(key)); 149 150 if (!wrapper) { 151 wrapper = AnimatedTearOff::create(creator, element); 152 AnimatedTearOff::wrapperCache()->set(key, wrapper.get()); 153 } 154 155 return wrapper.release(); 156 } 157 158 // Common type definitions, to ease IDL generation. 159 typedef SVGAnimatedTemplate<SVGAngle> SVGAnimatedAngle; 160 typedef SVGAnimatedTemplate<bool> SVGAnimatedBoolean; 161 typedef SVGAnimatedTemplate<int> SVGAnimatedEnumeration; 162 typedef SVGAnimatedTemplate<long> SVGAnimatedInteger; 163 typedef SVGAnimatedTemplate<SVGLength> SVGAnimatedLength; 164 typedef SVGAnimatedTemplate<SVGLengthList*> SVGAnimatedLengthList; 165 typedef SVGAnimatedTemplate<float> SVGAnimatedNumber; 166 typedef SVGAnimatedTemplate<SVGNumberList*> SVGAnimatedNumberList; 167 typedef SVGAnimatedTemplate<SVGPreserveAspectRatio> SVGAnimatedPreserveAspectRatio; 168 typedef SVGAnimatedTemplate<FloatRect> SVGAnimatedRect; 169 typedef SVGAnimatedTemplate<String> SVGAnimatedString; 170 typedef SVGAnimatedTemplate<SVGTransformList*> SVGAnimatedTransformList; 171 172 } 173 174 #endif 175 #endif 176