Home | History | Annotate | Download | only in svg
      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