⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jssvgpodtypewrapper.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
字号:
/* * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#ifndef JSSVGPODTypeWrapper_h#define JSSVGPODTypeWrapper_h#if ENABLE(SVG)#include "SVGElement.h"#include <wtf/StdLibExtras.h>namespace WebCore {template<typename PODType>class JSSVGPODTypeWrapper : public RefCounted<JSSVGPODTypeWrapper<PODType> > {public:    virtual ~JSSVGPODTypeWrapper() { }    virtual operator PODType() = 0;    virtual void commitChange(PODType, SVGElement*) = 0;};// This file contains JS wrapper objects for SVG datatypes, that are passed around by value// in WebCore/svg (aka. 'POD types'). For instance SVGMatrix is mapped to TransformationMatrix, and// passed around as const reference. SVG DOM demands these objects to be "live", changes to any// of the writable attributes of SVGMatrix need to be reflected in the object which exposed the// SVGMatrix object (ie. 'someElement.transform.matrix.a = 50.0', in that case 'SVGTransform').// The SVGTransform class stores its "TransformationMatrix m_matrix" object on the stack. If it would// be stored as pointer we could just build an auto-generated JSSVG* wrapper object around it// and all changes to that object would automatically affect the TransformationMatrix* object stored// in the SVGTransform object. For the sake of efficiency and memory we don't pass around any// primitive values as pointers, so a custom JS wrapper object is needed for all SVG types, that// are internally represented by POD types (SVGRect <-> FloatRect, SVGPoint <-> FloatPoint, ...).// Those custom wrappers are called JSSVGPODTypeWrapper and are capable of updating the POD types// by taking function pointers to the getter & setter functions of the "creator object", the object// which exposed a SVG POD type. For example, the JSSVGPODTypeWrapper object wrapping a SVGMatrix// object takes (SVGTransform*, &SVGTransform::matrix, &SVGTransform::setMatrix). A JS call like// "someElement.transform.matrix.a = 50.0' causes the JSSVGMatrix object to call SVGTransform::setMatrix,// method, which in turn notifies 'someElement' that the 'SVGNames::transformAttr' has changed.// That's a short sketch of our SVG DOM implementation.// Represents a JS wrapper object for SVGAnimated* classes, exposing SVG POD types that contain writable properties// (Two cases: SVGAnimatedLength exposing SVGLength, SVGAnimatedRect exposing SVGRect)#if COMPILER(MSVC)// GetterMethod and SetterMethod are each 12 bytes. We have to pack to a size// greater than or equal to that to avoid an alignment warning (C4121). 16 is// the next-largest size allowed for packing, so we use that.#pragma pack(16)#endiftemplate<typename PODType, typename PODTypeCreator>class JSSVGDynamicPODTypeWrapper : public JSSVGPODTypeWrapper<PODType> {public:    typedef PODType (PODTypeCreator::*GetterMethod)() const;     typedef void (PODTypeCreator::*SetterMethod)(PODType);    static PassRefPtr<JSSVGDynamicPODTypeWrapper> create(PassRefPtr<PODTypeCreator> creator, GetterMethod getter, SetterMethod setter)    {        return adoptRef(new JSSVGDynamicPODTypeWrapper(creator, getter, setter));    }    virtual operator PODType()    {        return (m_creator.get()->*m_getter)();    }    virtual void commitChange(PODType type, SVGElement* context)    {        (m_creator.get()->*m_setter)(type);        if (context)            context->svgAttributeChanged(m_creator->associatedAttributeName());    }private:    JSSVGDynamicPODTypeWrapper(PassRefPtr<PODTypeCreator> creator, GetterMethod getter, SetterMethod setter)        : m_creator(creator)        , m_getter(getter)        , m_setter(setter)    {        ASSERT(m_creator);        ASSERT(m_getter);        ASSERT(m_setter);    }    // Update callbacks    RefPtr<PODTypeCreator> m_creator;    GetterMethod m_getter;    SetterMethod m_setter;};// Represents a JS wrapper object for SVG POD types (not for SVGAnimated* clases). Any modification to the SVG POD// types don't cause any updates unlike JSSVGDynamicPODTypeWrapper. This class is used for return values (ie. getBBox())// and for properties where SVG specification explicitely states, that the contents of the POD type are immutable.template<typename PODType>class JSSVGStaticPODTypeWrapper : public JSSVGPODTypeWrapper<PODType> {public:    static PassRefPtr<JSSVGStaticPODTypeWrapper> create(PODType type)    {        return adoptRef(new JSSVGStaticPODTypeWrapper(type));    }    virtual operator PODType()    {        return m_podType;    }    virtual void commitChange(PODType type, SVGElement*)    {        m_podType = type;    }protected:    JSSVGStaticPODTypeWrapper(PODType type)        : m_podType(type)    {    }    PODType m_podType;};template<typename PODType, typename ParentTypeArg>class JSSVGStaticPODTypeWrapperWithPODTypeParent : public JSSVGStaticPODTypeWrapper<PODType> {public:    typedef JSSVGPODTypeWrapper<ParentTypeArg> ParentType;    static PassRefPtr<JSSVGStaticPODTypeWrapperWithPODTypeParent> create(PODType type, PassRefPtr<ParentType> parent)    {        return adoptRef(new JSSVGStaticPODTypeWrapperWithPODTypeParent(type, parent));    }    virtual void commitChange(PODType type, SVGElement* context)    {        JSSVGStaticPODTypeWrapper<PODType>::commitChange(type, context);        m_parentType->commitChange(ParentTypeArg(type), context);        }private:    JSSVGStaticPODTypeWrapperWithPODTypeParent(PODType type, PassRefPtr<ParentType> parent)        : JSSVGStaticPODTypeWrapper<PODType>(type)        , m_parentType(parent)    {    }    RefPtr<ParentType> m_parentType;};#if COMPILER(MSVC)// GetterMethod and SetterMethod are each 12 bytes. We have to pack to a size// greater than or equal to that to avoid an alignment warning (C4121). 16 is// the next-largest size allowed for packing, so we use that.#pragma pack(16)#endiftemplate<typename PODType, typename ParentType>class JSSVGStaticPODTypeWrapperWithParent : public JSSVGPODTypeWrapper<PODType> {public:    typedef PODType (ParentType::*GetterMethod)() const;    typedef void (ParentType::*SetterMethod)(const PODType&);    static PassRefPtr<JSSVGStaticPODTypeWrapperWithParent> create(PassRefPtr<ParentType> parent, GetterMethod getter, SetterMethod setter)    {        return adoptRef(new JSSVGStaticPODTypeWrapperWithParent(parent, getter, setter));    }    virtual operator PODType()    {        return (m_parent.get()->*m_getter)();    }    virtual void commitChange(PODType type, SVGElement*)    {        (m_parent.get()->*m_setter)(type);    }private:    JSSVGStaticPODTypeWrapperWithParent(PassRefPtr<ParentType> parent, GetterMethod getter, SetterMethod setter)        : m_parent(parent)        , m_getter(getter)        , m_setter(setter)    {        ASSERT(m_parent);        ASSERT(m_getter);        ASSERT(m_setter);    }    // Update callbacks    RefPtr<ParentType> m_parent;    GetterMethod m_getter;    SetterMethod m_setter;};template<typename PODType>class SVGPODListItem;// Just like JSSVGDynamicPODTypeWrapper, but only used for SVGList* objects wrapping around POD values.template<typename PODType>class JSSVGPODTypeWrapperCreatorForList : public JSSVGPODTypeWrapper<PODType> {public:    typedef SVGPODListItem<PODType> PODListItemPtrType;    typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const;     typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType);    static PassRefPtr<JSSVGPODTypeWrapperCreatorForList> create(PassRefPtr<PODListItemPtrType> creator, const QualifiedName& attributeName)    {        return adoptRef(new JSSVGPODTypeWrapperCreatorForList(creator, attributeName));    }    virtual operator PODType()    {        return (m_creator.get()->*m_getter)();    }    virtual void commitChange(PODType type, SVGElement* context)    {        if (!m_setter)            return;        (m_creator.get()->*m_setter)(type);        if (context)            context->svgAttributeChanged(m_associatedAttributeName);    }private:    JSSVGPODTypeWrapperCreatorForList(PassRefPtr<PODListItemPtrType> creator, const QualifiedName& attributeName)        : m_creator(creator)        , m_getter(&PODListItemPtrType::value)        , m_setter(&PODListItemPtrType::setValue)        , m_associatedAttributeName(attributeName)    {        ASSERT(m_creator);        ASSERT(m_getter);        ASSERT(m_setter);    }    // Update callbacks    RefPtr<PODListItemPtrType> m_creator;    GetterMethod m_getter;    SetterMethod m_setter;    const QualifiedName& m_associatedAttributeName;};// Caching facilitiestemplate<typename PODType, typename PODTypeCreator>struct PODTypeWrapperCacheInfo {    typedef PODType (PODTypeCreator::*GetterMethod)() const;     typedef void (PODTypeCreator::*SetterMethod)(PODType);    // Empty value    PODTypeWrapperCacheInfo()        : creator(0)        , getter(0)        , setter(0)    {    }    // Deleted value    PODTypeWrapperCacheInfo(WTF::HashTableDeletedValueType)        : creator(reinterpret_cast<PODTypeCreator*>(-1))        , getter(0)        , setter(0)    {    }    bool isHashTableDeletedValue() const    {        return creator == reinterpret_cast<PODTypeCreator*>(-1);    }    PODTypeWrapperCacheInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter)        : creator(_creator)        , getter(_getter)        , setter(_setter)    {        ASSERT(creator);        ASSERT(getter);    }    bool operator==(const PODTypeWrapperCacheInfo& other) const    {        return creator == other.creator && getter == other.getter && setter == other.setter;    }    PODTypeCreator* creator;    GetterMethod getter;    SetterMethod setter;};template<typename PODType, typename PODTypeCreator>struct PODTypeWrapperCacheInfoHash {    typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo;    static unsigned hash(const CacheInfo& info)    {        return StringImpl::computeHash(reinterpret_cast<const UChar*>(&info), sizeof(CacheInfo) / sizeof(UChar));    }    static bool equal(const CacheInfo& a, const CacheInfo& b)    {        return a == b;    }    static const bool safeToCompareToEmptyOrDeleted = true;};template<typename PODType, typename PODTypeCreator>struct PODTypeWrapperCacheInfoTraits : WTF::GenericHashTraits<PODTypeWrapperCacheInfo<PODType, PODTypeCreator> > {    typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo;    static const bool emptyValueIsZero = true;    static const bool needsDestruction = false;    static const CacheInfo& emptyValue()    {        DEFINE_STATIC_LOCAL(CacheInfo, key, ());        return key;    }    static void constructDeletedValue(CacheInfo& slot)    {        new (&slot) CacheInfo(WTF::HashTableDeletedValue);    }    static bool isDeletedValue(const CacheInfo& value)    {        return value.isHashTableDeletedValue();    }};template<typename PODType, typename PODTypeCreator>class JSSVGDynamicPODTypeWrapperCache {public:    typedef PODType (PODTypeCreator::*GetterMethod)() const;     typedef void (PODTypeCreator::*SetterMethod)(PODType);    typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo;    typedef PODTypeWrapperCacheInfoHash<PODType, PODTypeCreator> CacheInfoHash;    typedef PODTypeWrapperCacheInfoTraits<PODType, PODTypeCreator> CacheInfoTraits;    typedef JSSVGPODTypeWrapper<PODType> WrapperBase;    typedef JSSVGDynamicPODTypeWrapper<PODType, PODTypeCreator> DynamicWrapper;    typedef HashMap<CacheInfo, DynamicWrapper*, CacheInfoHash, CacheInfoTraits> DynamicWrapperHashMap;    typedef typename DynamicWrapperHashMap::const_iterator DynamicWrapperHashMapIterator;    static DynamicWrapperHashMap& dynamicWrapperHashMap()    {        DEFINE_STATIC_LOCAL(DynamicWrapperHashMap, s_dynamicWrapperHashMap, ());        return s_dynamicWrapperHashMap;    }    // Used for readwrite attributes only    static PassRefPtr<WrapperBase> lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter)    {        DynamicWrapperHashMap& map(dynamicWrapperHashMap());        CacheInfo info(creator, getter, setter);        if (map.contains(info))            return map.get(info);        RefPtr<DynamicWrapper> wrapper = DynamicWrapper::create(creator, getter, setter);        map.set(info, wrapper.get());        return wrapper.release();    }    static void forgetWrapper(WrapperBase* wrapper)    {        DynamicWrapperHashMap& map(dynamicWrapperHashMap());        DynamicWrapperHashMapIterator it = map.begin();        DynamicWrapperHashMapIterator end = map.end();        for (; it != end; ++it) {            if (it->second != wrapper)                continue;            // It's guaranteed that there's just one object we need to take care of.            map.remove(it->first);            break;        }    }};};#endif // ENABLE(SVG)#endif // JSSVGPODTypeWrapper_h

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -