diff options
author | Steve Block <steveblock@google.com> | 2010-02-02 14:57:50 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-04 15:06:55 +0000 |
commit | d0825bca7fe65beaee391d30da42e937db621564 (patch) | |
tree | 7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/svg | |
parent | 3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff) | |
download | external_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2 |
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/svg')
217 files changed, 3308 insertions, 2631 deletions
diff --git a/WebCore/svg/ElementTimeControl.idl b/WebCore/svg/ElementTimeControl.idl index e8ca615..4ac01c4 100644 --- a/WebCore/svg/ElementTimeControl.idl +++ b/WebCore/svg/ElementTimeControl.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] ElementTimeControl { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] ElementTimeControl { void beginElement(); void beginElementAt(in float offset); void endElement(); diff --git a/WebCore/svg/SVGAElement.cpp b/WebCore/svg/SVGAElement.cpp index d0d3613..b344a4e 100644 --- a/WebCore/svg/SVGAElement.cpp +++ b/WebCore/svg/SVGAElement.cpp @@ -51,9 +51,6 @@ SVGAElement::SVGAElement(const QualifiedName& tagName, Document *doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_target(this, SVGNames::targetAttr) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -98,6 +95,25 @@ void SVGAElement::svgAttributeChanged(const QualifiedName& attrName) } } +void SVGAElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeTarget(); + synchronizeHref(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::targetAttr) + synchronizeTarget(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + RenderObject* SVGAElement::createRenderer(RenderArena* arena, RenderStyle*) { if (static_cast<SVGElement*>(parent())->isTextContent()) diff --git a/WebCore/svg/SVGAElement.h b/WebCore/svg/SVGAElement.h index a3e59c5..36046d3 100644 --- a/WebCore/svg/SVGAElement.h +++ b/WebCore/svg/SVGAElement.h @@ -46,6 +46,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); @@ -59,15 +60,13 @@ namespace WebCore { virtual bool childShouldCreateRenderer(Node*) const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGAElement, SVGNames::aTagString, SVGNames::targetAttrString, String, Target, target) + DECLARE_ANIMATED_PROPERTY(SVGAElement, SVGNames::targetAttr, String, Target, target) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGAElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGAElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGAElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGAElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGAllInOne.cpp b/WebCore/svg/SVGAllInOne.cpp index 6606243..067adf2 100644 --- a/WebCore/svg/SVGAllInOne.cpp +++ b/WebCore/svg/SVGAllInOne.cpp @@ -30,11 +30,11 @@ #include "SVGAltGlyphElement.cpp" #include "SVGAngle.cpp" #include "SVGAnimateColorElement.cpp" +#include "SVGAnimatedPathData.cpp" +#include "SVGAnimatedPoints.cpp" #include "SVGAnimateElement.cpp" #include "SVGAnimateMotionElement.cpp" #include "SVGAnimateTransformElement.cpp" -#include "SVGAnimatedPathData.cpp" -#include "SVGAnimatedPoints.cpp" #include "SVGAnimationElement.cpp" #include "SVGCircleElement.cpp" #include "SVGClipPathElement.cpp" @@ -80,13 +80,16 @@ #include "SVGFont.cpp" #include "SVGFontData.cpp" #include "SVGFontElement.cpp" +#include "SVGFontFaceElement.cpp" #include "SVGFontFaceFormatElement.cpp" #include "SVGFontFaceNameElement.cpp" #include "SVGFontFaceSrcElement.cpp" #include "SVGFontFaceUriElement.cpp" #include "SVGForeignObjectElement.cpp" #include "SVGGElement.cpp" +#include "SVGGlyphElement.cpp" #include "SVGGradientElement.cpp" +#include "SVGHKernElement.cpp" #include "SVGImageElement.cpp" #include "SVGImageLoader.cpp" #include "SVGLangSpace.cpp" @@ -97,6 +100,7 @@ #include "SVGLocatable.cpp" #include "SVGMPathElement.cpp" #include "SVGMarkerElement.cpp" +#include "SVGMaskElement.cpp" #include "SVGMetadataElement.cpp" #include "SVGMissingGlyphElement.cpp" #include "SVGNumberList.cpp" @@ -128,6 +132,8 @@ #include "SVGStopElement.cpp" #include "SVGStringList.cpp" #include "SVGStylable.cpp" +#include "SVGStyleElement.cpp" +#include "SVGStyledElement.cpp" #include "SVGStyledLocatableElement.cpp" #include "SVGStyledTransformableElement.cpp" #include "SVGSwitchElement.cpp" @@ -141,13 +147,12 @@ #include "SVGTextPositioningElement.cpp" #include "SVGTitleElement.cpp" #include "SVGTransform.cpp" +#include "SVGTransformable.cpp" #include "SVGTransformDistance.cpp" #include "SVGTransformList.cpp" -#include "SVGTransformable.cpp" #include "SVGURIReference.cpp" #include "SVGUseElement.cpp" #include "SVGViewElement.cpp" #include "SVGViewSpec.cpp" #include "SVGZoomAndPan.cpp" #include "SVGZoomEvent.cpp" -#include "SynchronizablePropertyController.cpp" diff --git a/WebCore/svg/SVGAltGlyphElement.cpp b/WebCore/svg/SVGAltGlyphElement.cpp index f13edf5..8371867 100644 --- a/WebCore/svg/SVGAltGlyphElement.cpp +++ b/WebCore/svg/SVGAltGlyphElement.cpp @@ -35,7 +35,6 @@ namespace WebCore { SVGAltGlyphElement::SVGAltGlyphElement(const QualifiedName& tagName, Document* doc) : SVGTextPositioningElement(tagName, doc) - , m_href(this, XLinkNames::hrefAttr) { } @@ -43,6 +42,14 @@ SVGAltGlyphElement::~SVGAltGlyphElement() { } +void SVGAltGlyphElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGTextPositioningElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + void SVGAltGlyphElement::setGlyphRef(const AtomicString&, ExceptionCode& ec) { ec = NO_MODIFICATION_ALLOWED_ERR; diff --git a/WebCore/svg/SVGAltGlyphElement.h b/WebCore/svg/SVGAltGlyphElement.h index b571880..a28bbad 100644 --- a/WebCore/svg/SVGAltGlyphElement.h +++ b/WebCore/svg/SVGAltGlyphElement.h @@ -36,7 +36,9 @@ namespace WebCore { public: SVGAltGlyphElement(const QualifiedName&, Document*); virtual ~SVGAltGlyphElement(); - + + virtual void synchronizeProperty(const QualifiedName&); + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); bool childShouldCreateRenderer(Node*) const; @@ -49,7 +51,7 @@ namespace WebCore { private: // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGAltGlyphElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGAltGlyphElement, XLinkNames::hrefAttr, String, Href, href) }; } // namespace WebCore diff --git a/WebCore/svg/SVGAngle.h b/WebCore/svg/SVGAngle.h index 13b9fd4..3d0bdeb 100644 --- a/WebCore/svg/SVGAngle.h +++ b/WebCore/svg/SVGAngle.h @@ -27,16 +27,11 @@ namespace WebCore { - class SVGStyledElement; - - class SVGAngle : public RefCounted<SVGAngle> { + class SVGAngle { public: - static PassRefPtr<SVGAngle> create() - { - return adoptRef(new SVGAngle); - } + SVGAngle(); virtual ~SVGAngle(); - + enum SVGAngleType { SVG_ANGLETYPE_UNKNOWN = 0, SVG_ANGLETYPE_UNSPECIFIED = 1, @@ -59,12 +54,7 @@ namespace WebCore { void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits); void convertToSpecifiedUnits(unsigned short unitType); - // Throughout SVG 1.1 'SVGAngle' is only used for 'SVGMarkerElement' (orient-angle) - const QualifiedName& associatedAttributeName() const { return SVGNames::orientAttr; } - private: - SVGAngle(); - SVGAngleType m_unitType; float m_value; float m_valueInSpecifiedUnits; diff --git a/WebCore/svg/SVGAngle.idl b/WebCore/svg/SVGAngle.idl index 1a05646..023fb39 100644 --- a/WebCore/svg/SVGAngle.idl +++ b/WebCore/svg/SVGAngle.idl @@ -22,7 +22,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGAngle { + interface [Conditional=SVG, PODType=SVGAngle] SVGAngle { // Angle Unit Types const unsigned short SVG_ANGLETYPE_UNKNOWN = 0; const unsigned short SVG_ANGLETYPE_UNSPECIFIED = 1; diff --git a/WebCore/svg/SVGAnimateMotionElement.cpp b/WebCore/svg/SVGAnimateMotionElement.cpp index 44bf5fb..bd6de49 100644 --- a/WebCore/svg/SVGAnimateMotionElement.cpp +++ b/WebCore/svg/SVGAnimateMotionElement.cpp @@ -215,9 +215,9 @@ void SVGAnimateMotionElement::applyResultsToTarget() targetElement->renderer()->setNeedsLayout(true); // ...except in case where we have additional instances in <use> trees. - HashSet<SVGElementInstance*> instances = targetElement->instancesForElement(); - HashSet<SVGElementInstance*>::iterator end = instances.end(); - for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) { + const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement(); + const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); + for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); ASSERT(shadowTreeElement); TransformationMatrix* transform = shadowTreeElement->supplementalTransform(); diff --git a/WebCore/svg/SVGAnimateTransformElement.cpp b/WebCore/svg/SVGAnimateTransformElement.cpp index 3ebba06..ac6eac9 100644 --- a/WebCore/svg/SVGAnimateTransformElement.cpp +++ b/WebCore/svg/SVGAnimateTransformElement.cpp @@ -163,16 +163,16 @@ void SVGAnimateTransformElement::applyResultsToTarget() targetElement->renderer()->setNeedsLayout(true); // ...except in case where we have additional instances in <use> trees. - HashSet<SVGElementInstance*> instances = targetElement->instancesForElement(); + const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement(); RefPtr<SVGTransformList> transformList = transformListFor(targetElement); - HashSet<SVGElementInstance*>::iterator end = instances.end(); - for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) { + const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); + for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); ASSERT(shadowTreeElement); if (shadowTreeElement->isStyledTransformable()) - static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransform(transformList.get()); + static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransformBaseValue(transformList.get()); else if (shadowTreeElement->hasTagName(SVGNames::textTag)) - static_cast<SVGTextElement*>(shadowTreeElement)->setTransform(transformList.get()); + static_cast<SVGTextElement*>(shadowTreeElement)->setTransformBaseValue(transformList.get()); if (shadowTreeElement->renderer()) shadowTreeElement->renderer()->setNeedsLayout(true); } diff --git a/WebCore/svg/SVGAnimatedPathData.idl b/WebCore/svg/SVGAnimatedPathData.idl index 46ec7b1..63a5209 100644 --- a/WebCore/svg/SVGAnimatedPathData.idl +++ b/WebCore/svg/SVGAnimatedPathData.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGAnimatedPathData { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGAnimatedPathData { readonly attribute SVGPathSegList pathSegList; readonly attribute SVGPathSegList normalizedPathSegList; readonly attribute SVGPathSegList animatedPathSegList; diff --git a/WebCore/svg/SVGAnimatedPoints.idl b/WebCore/svg/SVGAnimatedPoints.idl index 877f684..056b139 100644 --- a/WebCore/svg/SVGAnimatedPoints.idl +++ b/WebCore/svg/SVGAnimatedPoints.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGAnimatedPoints { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGAnimatedPoints { readonly attribute SVGPointList points; readonly attribute SVGPointList animatedPoints; }; diff --git a/WebCore/svg/SVGAnimatedProperty.h b/WebCore/svg/SVGAnimatedProperty.h index 984046f..0e3ceda 100644 --- a/WebCore/svg/SVGAnimatedProperty.h +++ b/WebCore/svg/SVGAnimatedProperty.h @@ -1,6 +1,6 @@ /* Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> - Copyright (C) Research In Motion Limited 2009. All rights reserved. + Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -22,493 +22,196 @@ #define SVGAnimatedProperty_h #if ENABLE(SVG) +#include "SVGAnimatedPropertySynchronizer.h" +#include "SVGAnimatedPropertyTraits.h" #include "SVGAnimatedTemplate.h" -#include "SVGDocumentExtensions.h" -#include "SynchronizableTypeWrapper.h" namespace WebCore { - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - class SVGAnimatedProperty; - - template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> - class SVGAnimatedPropertyTearOff : public SVGAnimatedTemplate<DecoratedType> { - public: - typedef SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName> Self; - typedef SVGAnimatedProperty<OwnerType, AnimatedType, TagName, PropertyName> Creator; +template<typename AnimatedType> +class SVGAnimatedProperty; - static PassRefPtr<Self> create(const Creator& creator, const OwnerElement* owner, const QualifiedName& attributeName) - { - return adoptRef(new Self(creator, owner, attributeName)); - } +template<typename AnimatedType> +class SVGAnimatedPropertyTearOff : public SVGAnimatedTemplate<AnimatedType> { +public: + typedef typename SVGAnimatedPropertyTraits<AnimatedType>::PassType PassType; + typedef typename SVGAnimatedPropertyTraits<AnimatedType>::ReturnType ReturnType; - virtual DecoratedType baseVal() const; - virtual void setBaseVal(DecoratedType); + typedef SVGAnimatedPropertyTearOff<AnimatedType> Self; + typedef SVGAnimatedProperty<AnimatedType> Creator; - virtual DecoratedType animVal() const; - virtual void setAnimVal(DecoratedType); - - private: - SVGAnimatedPropertyTearOff(const Creator&, const OwnerElement*, const QualifiedName& attributeName); - - Creator& m_creator; - RefPtr<OwnerElement> m_ownerElement; - }; - - // Helper templates mapping owner types to owner elements (for SVG*Element OwnerType is equal to OwnerElement, for non-SVG*Element derived types, they're different) - template<typename OwnerType, bool isDerivedFromSVGElement> - struct GetOwnerElementForType; - - template<typename OwnerType> - struct IsDerivedFromSVGElement; - - // Helper template used for synchronizing SVG <-> XML properties - template<typename OwnerType, typename DecoratedType, bool isDerivedFromSVGElement> - struct PropertySynchronizer; - - // Abstract base class - class SVGAnimatedPropertyBase : public Noncopyable { - public: - virtual ~SVGAnimatedPropertyBase() { } - virtual void synchronize() const = 0; - virtual void startAnimation() const = 0; - virtual void stopAnimation() = 0; - }; - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - class SVGAnimatedProperty : public SVGAnimatedPropertyBase { - public: - typedef OwnerTypeArg OwnerType; - typedef AnimatedTypeArg AnimatedType; - - typedef typename SVGAnimatedTypeValue<AnimatedType>::StorableType StorableType; - typedef typename SVGAnimatedTypeValue<AnimatedType>::DecoratedType DecoratedType; - - typedef GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value> OwnerElementForType; - typedef typename OwnerElementForType::OwnerElement OwnerElement; - typedef SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName> TearOff; - - // attributeName & attributeIdentifier may differ. For SVGMarkerElement, there are two exposed SVG animatable - // properties: orientType & orientAngle, though only one DOM attribute "orient", handle these cases! - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName); - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier); - - // "Forwarding constructors" for primitive type assignment with more than one argument - template<typename T1> - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, - const T1&); - - template<typename T1> - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier, - const T1&); - - template<typename T1, typename T2> - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, - const T1&, const T2&); - - template<typename T1, typename T2> - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier, - const T1&, const T2&); - - template<typename T1, typename T2, typename T3> - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, - const T1&, const T2&, const T3&); - - template<typename T1, typename T2, typename T3> - SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier, - const T1&, const T2&, const T3&); - - DecoratedType value() const; - void setValue(DecoratedType); - - DecoratedType baseValue() const; - void setBaseValue(DecoratedType); - - // Tear offs only used by bindings, never in internal code - PassRefPtr<TearOff> animatedTearOff() const; - - void registerProperty(); - virtual void synchronize() const; - - void startAnimation() const; - void stopAnimation(); - - private: - const OwnerElement* ownerElement() const; - - private: - // We're a member variable on stack, living in OwnerType, NO need to ref here. - const OwnerType* m_ownerType; - - const QualifiedName& m_attributeName; - const AtomicString& m_attributeIdentifier; - - mutable SynchronizableTypeWrapper<StorableType> m_value; - -#ifndef NDEBUG - bool m_registered; -#endif - }; - - // SVGAnimatedPropertyTearOff implementation - template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> - SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::SVGAnimatedPropertyTearOff(const Creator& creator, - const OwnerElement* owner, - const QualifiedName& attributeName) - : SVGAnimatedTemplate<DecoratedType>(attributeName) - , m_creator(const_cast<Creator&>(creator)) - , m_ownerElement(const_cast<OwnerElement*>(owner)) + static PassRefPtr<Self> create(Creator& creator, SVGElement* contextElement) { - ASSERT(m_ownerElement); + return adoptRef(new Self(creator, contextElement)); } - template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> - DecoratedType SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::baseVal() const + virtual void setBaseVal(PassType type) { - return m_creator.baseValue(); + m_creator.setBaseValue(type); + m_contextElement->setSynchronizedSVGAttributes(false); } - template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> - void SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::setBaseVal(DecoratedType newBaseVal) + virtual void setAnimVal(PassType type) { - m_creator.setBaseValue(newBaseVal); + m_creator.setValue(type); + m_contextElement->setSynchronizedSVGAttributes(false); } - template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> - DecoratedType SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::animVal() const - { - return m_creator.value(); - } + virtual ReturnType baseVal() const { return m_creator.baseValue(); } + virtual ReturnType animVal() const { return m_creator.value(); } + virtual const QualifiedName& associatedAttributeName() const { return m_creator.associatedAttributeName(); } - template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> - void SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::setAnimVal(DecoratedType newAnimVal) +private: + SVGAnimatedPropertyTearOff(Creator& creator, SVGElement* contextElement) + : m_creator(creator) + , m_contextElement(contextElement) { - m_creator.setValue(newAnimVal); + m_creator.setShouldSynchronize(true); } - // SVGAnimatedProperty implementation - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeName.localName()) - , m_value() -#ifndef NDEBUG - , m_registered(false) -#endif + virtual ~SVGAnimatedPropertyTearOff() { - ASSERT(m_ownerType); - registerProperty(); + m_creator.setShouldSynchronize(false); } - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName, - const AtomicString& attributeIdentifier) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeIdentifier) - , m_value() -#ifndef NDEBUG - , m_registered(false) -#endif - { - ASSERT(m_ownerType); - registerProperty(); - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - template<typename T1> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName, - const T1& arg1) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeName.localName()) - , m_value(arg1) -#ifndef NDEBUG - , m_registered(false) -#endif - { - ASSERT(m_ownerType); - registerProperty(); - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - template<typename T1> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName, - const AtomicString& attributeIdentifier, - const T1& arg1) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeIdentifier) - , m_value(arg1) -#ifndef NDEBUG - , m_registered(false) -#endif - { - ASSERT(m_ownerType); - registerProperty(); - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - template<typename T1, typename T2> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName, - const T1& arg1, - const T2& arg2) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeName.localName()) - , m_value(arg1, arg2) -#ifndef NDEBUG - , m_registered(false) -#endif - { - ASSERT(m_ownerType); - registerProperty(); - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - template<typename T1, typename T2> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName, - const AtomicString& attributeIdentifier, - const T1& arg1, - const T2& arg2) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeIdentifier) - , m_value(arg1, arg2) -#ifndef NDEBUG - , m_registered(false) -#endif - { - ASSERT(m_ownerType); - registerProperty(); - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - template<typename T1, typename T2, typename T3> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName, - const T1& arg1, - const T2& arg2, - const T3& arg3) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeName.localName()) - , m_value(arg1, arg2, arg3) -#ifndef NDEBUG - , m_registered(false) -#endif - { - ASSERT(m_ownerType); - registerProperty(); - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - template<typename T1, typename T2, typename T3> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, - const QualifiedName& attributeName, - const AtomicString& attributeIdentifier, - const T1& arg1, - const T2& arg2, - const T3& arg3) - : m_ownerType(owner) - , m_attributeName(attributeName) - , m_attributeIdentifier(attributeIdentifier) - , m_value(arg1, arg2, arg3) -#ifndef NDEBUG - , m_registered(false) -#endif - { - ASSERT(m_ownerType); - registerProperty(); - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::DecoratedType - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::value() const - { - ASSERT(m_registered); - return m_value; - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::setValue(typename SVGAnimatedProperty::DecoratedType newValue) - { - ASSERT(m_registered); - m_value = newValue; - ownerElement()->setSynchronizedSVGAttributes(false); - } + Creator& m_creator; + RefPtr<SVGElement> m_contextElement; +}; - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::DecoratedType - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::baseValue() const - { - ASSERT(m_registered); - const OwnerElement* ownerElement = this->ownerElement(); - SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions(); - if (extensions && extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)) - return extensions->baseValue<DecoratedType>(ownerElement, m_attributeIdentifier); +template<typename AnimatedType> +class SVGAnimatedProperty { +public: + virtual ~SVGAnimatedProperty() { } - return m_value; - } + typedef typename SVGAnimatedPropertyTraits<AnimatedType>::PassType PassType; + typedef typename SVGAnimatedPropertyTraits<AnimatedType>::ReturnType ReturnType; + typedef typename SVGAnimatedPropertyTraits<AnimatedType>::StoredType StoredType; - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::setBaseValue(typename SVGAnimatedProperty::DecoratedType newValue) + SVGAnimatedProperty() + : m_value(SVGAnimatedPropertyTraits<AnimatedType>::null()) + , m_shouldSynchronize(false) { - ASSERT(m_registered); - const OwnerElement* ownerElement = this->ownerElement(); - SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions(); - if (extensions && extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)) { - extensions->setBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier, newValue); - return; - } - - // Only update stored property, if not animating - m_value = newValue; - ownerElement->setSynchronizedSVGAttributes(false); } - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - PassRefPtr<typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::TearOff> - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::animatedTearOff() const + template<typename ConstructorParameterOne> + SVGAnimatedProperty(const ConstructorParameterOne& value1) + : m_value(value1) + , m_shouldSynchronize(false) { - ASSERT(m_registered); - return lookupOrCreateWrapper<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName, TearOff, OwnerElement>(*this, ownerElement(), m_attributeName, m_attributeIdentifier); } - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::registerProperty() + template<typename ConstructorParameterOne, typename ConstructorParameterTwo> + SVGAnimatedProperty(const ConstructorParameterOne& value1, const ConstructorParameterTwo& value2) + : m_value(value1, value2) + , m_shouldSynchronize(false) { - ASSERT(!m_registered); - ownerElement()->propertyController().registerProperty(m_attributeName, this); - -#ifndef NDEBUG - m_registered = true; -#endif } - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::synchronize() const - { - ASSERT(m_registered); - if (!m_value.needsSynchronization()) - return; + ReturnType value() const { return SVGAnimatedPropertyTraits<AnimatedType>::toReturnType(m_value); } + ReturnType baseValue() const { return SVGAnimatedPropertyTraits<AnimatedType>::toReturnType(m_value); } - PropertySynchronizer<OwnerElement, DecoratedType, IsDerivedFromSVGElement<OwnerType>::value>::synchronize(ownerElement(), m_attributeName, baseValue()); - m_value.setSynchronized(); - } + void setValue(PassType type) { m_value = type; } + void setBaseValue(PassType type) { m_value = type; } - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::startAnimation() const - { - ASSERT(m_registered); - const OwnerElement* ownerElement = this->ownerElement(); - if (SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions()) { - ASSERT(!extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)); - extensions->setBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier, m_value); - } - } - - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::stopAnimation() - { - ASSERT(m_registered); - const OwnerElement* ownerElement = this->ownerElement(); - if (SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions()) { - ASSERT(extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)); - setValue(extensions->baseValue<DecoratedType>(ownerElement, m_attributeIdentifier)); - extensions->removeBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier); - } - } + bool shouldSynchronize() const { return m_shouldSynchronize; } + void setShouldSynchronize(bool value) { m_shouldSynchronize = value; } - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> - const typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::OwnerElement* - SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::ownerElement() const - { - return OwnerElementForType::ownerElement(m_ownerType); - } + virtual const QualifiedName& associatedAttributeName() const = 0; - // GetOwnerElementForType implementation - template<typename OwnerType> - struct GetOwnerElementForType<OwnerType, true> : Noncopyable { - typedef OwnerType OwnerElement; - - static const OwnerElement* ownerElement(const OwnerType* type) - { - return type; - } - }; - - template<typename OwnerType> - struct GetOwnerElementForType<OwnerType, false> : Noncopyable { - typedef SVGElement OwnerElement; - - static const OwnerElement* ownerElement(const OwnerType* type) - { - const OwnerElement* context = type->contextElement(); - ASSERT(context); - return context; - } - }; - - // IsDerivedFromSVGElement implementation - template<typename OwnerType> - struct IsDerivedFromSVGElement : Noncopyable { - static const bool value = true; - }; - - class SVGViewSpec; - template<> - struct IsDerivedFromSVGElement<SVGViewSpec> : Noncopyable { - static const bool value = false; - }; - - // PropertySynchronizer implementation - template<typename OwnerElement, typename DecoratedType> - struct PropertySynchronizer<OwnerElement, DecoratedType, true> : Noncopyable { - static void synchronize(const OwnerElement* ownerElement, const QualifiedName& attributeName, DecoratedType baseValue) - { - AtomicString value(SVGAnimatedTypeValue<DecoratedType>::toString(baseValue)); - - NamedNodeMap* namedAttrMap = ownerElement->attributes(false); - Attribute* old = namedAttrMap->getAttributeItem(attributeName); - if (old && value.isNull()) - namedAttrMap->removeAttribute(old->name()); - else if (!old && !value.isNull()) - namedAttrMap->addAttribute(const_cast<OwnerElement*>(ownerElement)->createAttribute(attributeName, value)); - else if (old && !value.isNull()) - old->setValue(value); - } - }; - - template<typename OwnerElement, typename DecoratedType> - struct PropertySynchronizer<OwnerElement, DecoratedType, false> : Noncopyable { - static void synchronize(const OwnerElement*, const QualifiedName&, DecoratedType) - { - // no-op, for types not inheriting from Element, thus nothing to synchronize - } - }; - - // Helper macro used to register animated properties within SVG* classes - #define ANIMATED_PROPERTY_DECLARATIONS(OwnerType, ElementTag, AttributeTag, AnimatedType, UpperProperty, LowerProperty) \ - private: \ - typedef SVGAnimatedProperty<OwnerType, AnimatedType, ElementTag, AttributeTag> SVGAnimatedProperty##UpperProperty; \ - typedef SVGAnimatedTypeValue<AnimatedType>::DecoratedType DecoratedTypeFor##UpperProperty; \ - SVGAnimatedProperty##UpperProperty m_##LowerProperty; \ - public: \ - DecoratedTypeFor##UpperProperty LowerProperty() const { return m_##LowerProperty.value(); } \ - void set##UpperProperty(DecoratedTypeFor##UpperProperty type) { m_##LowerProperty.setValue(type); } \ - DecoratedTypeFor##UpperProperty LowerProperty##BaseValue() const { return m_##LowerProperty.baseValue(); } \ - void set##UpperProperty##BaseValue(DecoratedTypeFor##UpperProperty type) { m_##LowerProperty.setBaseValue(type); } \ - PassRefPtr<SVGAnimatedProperty##UpperProperty::TearOff> LowerProperty##Animated() const { return m_##LowerProperty.animatedTearOff(); } +protected: + StoredType m_value; + bool m_shouldSynchronize; +}; }; +// Helper macro used within DECLARE_ANIMATED_PROPERTY below +#define DEFINE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, AnimatedType, UpperProperty) \ +class SVGAnimatedProperty##UpperProperty : public SVGAnimatedProperty<AnimatedType> { \ +public: \ + SVGAnimatedProperty##UpperProperty() \ + : SVGAnimatedProperty<AnimatedType>() \ + { \ + } \ + \ + template<typename ConstructorParameterOne> \ + SVGAnimatedProperty##UpperProperty(const ConstructorParameterOne& value1) \ + : SVGAnimatedProperty<AnimatedType>(value1) \ + { \ + } \ + \ + template<typename ConstructorParameterOne, typename ConstructorParameterTwo> \ + SVGAnimatedProperty##UpperProperty(const ConstructorParameterOne& value1, const ConstructorParameterTwo& value2) \ + : SVGAnimatedProperty<AnimatedType>(value1, value2) \ + { \ + } \ + \ + void synchronize(SVGElement* contextElement) \ + { \ + ASSERT(m_shouldSynchronize); \ + AtomicString value(SVGAnimatedPropertyTraits<AnimatedType>::toString(baseValue())); \ + SVGAnimatedPropertySynchronizer<IsDerivedFromSVGElement<OwnerType>::value>::synchronize(contextElement, DOMAttribute, value); \ + } \ + \ + virtual const QualifiedName& associatedAttributeName() const \ + { \ + return DOMAttribute; \ + } \ +} + +// Helper macro shared by DECLARE_ANIMATED_PROPERTY / DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS +#define DECLARE_ANIMATED_PROPERTY_SHARED(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, AnimatedType, UpperProperty, LowerProperty) \ +private: \ + typedef SVGAnimatedPropertyTearOff<AnimatedType> SVGAnimatedPropertyTearOff##UpperProperty; \ + DEFINE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, AnimatedType, UpperProperty); \ + SVGAnimatedProperty##UpperProperty m_##LowerProperty; \ + \ +public: \ + SVGAnimatedPropertyTraits<AnimatedType>::ReturnType LowerProperty() const \ + { \ + return m_##LowerProperty.value(); \ + } \ + \ + SVGAnimatedPropertyTraits<AnimatedType>::ReturnType LowerProperty##BaseValue() const \ + { \ + return m_##LowerProperty.baseValue(); \ + } \ + \ + void set##UpperProperty(SVGAnimatedPropertyTraits<AnimatedType>::PassType type) \ + { \ + m_##LowerProperty.setValue(type); \ + SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \ + contextElement->setSynchronizedSVGAttributes(false); \ + } \ + \ + void set##UpperProperty##BaseValue(SVGAnimatedPropertyTraits<AnimatedType>::PassType type) \ + { \ + m_##LowerProperty.setBaseValue(type); \ + SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \ + contextElement->setSynchronizedSVGAttributes(false); \ + } \ + \ + void synchronize##UpperProperty() \ + { \ + if (!m_##LowerProperty.shouldSynchronize()) \ + return; \ + SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \ + m_##LowerProperty.synchronize(contextElement); \ + } \ + \ + PassRefPtr<SVGAnimatedPropertyTearOff##UpperProperty> LowerProperty##Animated() \ + { \ + SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \ + return lookupOrCreateWrapper<AnimatedType, SVGAnimatedPropertyTearOff##UpperProperty>(contextElement, m_##LowerProperty, DOMAttribute); \ + } + +// Used for SVG DOM properties that map exactly to one XML DOM attribute +#define DECLARE_ANIMATED_PROPERTY(OwnerType, DOMAttribute, AnimatedType, UpperProperty, LowerProperty) \ +DECLARE_ANIMATED_PROPERTY_SHARED(OwnerType, DOMAttribute, DOMAttribute.localName(), AnimatedType, UpperProperty, LowerProperty) + +// Used for the rare case multiple SVG DOM properties that map to the same XML dom attribute +#define DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, AnimatedType, UpperProperty, LowerProperty) \ +DECLARE_ANIMATED_PROPERTY_SHARED(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, AnimatedType, UpperProperty, LowerProperty) + #endif #endif diff --git a/WebCore/svg/SVGAnimatedPropertySynchronizer.h b/WebCore/svg/SVGAnimatedPropertySynchronizer.h new file mode 100644 index 0000000..ddd0493 --- /dev/null +++ b/WebCore/svg/SVGAnimatedPropertySynchronizer.h @@ -0,0 +1,96 @@ +/* + Copyright (C) Research In Motion Limited 2010. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SVGAnimatedPropertySynchronizer_h +#define SVGAnimatedPropertySynchronizer_h + +#include "SVGAnimatedPropertyTraits.h" + +#if ENABLE(SVG) +namespace WebCore { + +class SVGElement; + +// GetOwnerElementForType implementation +template<typename OwnerType, bool isDerivedFromSVGElement> +struct GetOwnerElementForType; + +template<typename OwnerType> +struct GetOwnerElementForType<OwnerType, true> : public Noncopyable { + static SVGElement* ownerElement(OwnerType* type) + { + return type; + } +}; + +template<typename OwnerType> +struct GetOwnerElementForType<OwnerType, false> : public Noncopyable { + static SVGElement* ownerElement(OwnerType* type) + { + SVGElement* context = type->contextElement(); + ASSERT(context); + return context; + } +}; + +// IsDerivedFromSVGElement implementation +template<typename OwnerType> +struct IsDerivedFromSVGElement : public Noncopyable { + static const bool value = true; +}; + +class SVGViewSpec; +template<> +struct IsDerivedFromSVGElement<SVGViewSpec> : public Noncopyable { + static const bool value = false; +}; + +// Helper template used for synchronizing SVG <-> XML properties +template<bool isDerivedFromSVGElement> +struct SVGAnimatedPropertySynchronizer { + static void synchronize(SVGElement*, const QualifiedName&, const AtomicString&); +}; + +template<> +struct SVGAnimatedPropertySynchronizer<true> { + static void synchronize(SVGElement* ownerElement, const QualifiedName& attrName, const AtomicString& value) + { + NamedNodeMap* namedAttrMap = ownerElement->attributes(false); + Attribute* old = namedAttrMap->getAttributeItem(attrName); + if (old && value.isNull()) + namedAttrMap->removeAttribute(old->name()); + else if (!old && !value.isNull()) + namedAttrMap->addAttribute(ownerElement->createAttribute(attrName, value)); + else if (old && !value.isNull()) + old->setValue(value); + } +}; + +template<> +struct SVGAnimatedPropertySynchronizer<false> { + static void synchronize(SVGElement*, const QualifiedName&, const AtomicString&) + { + // no-op, for types not inheriting from Element, thus nothing to synchronize + } +}; + +}; + +#endif +#endif diff --git a/WebCore/svg/SVGAnimatedPropertyTraits.h b/WebCore/svg/SVGAnimatedPropertyTraits.h new file mode 100644 index 0000000..4e34dbe --- /dev/null +++ b/WebCore/svg/SVGAnimatedPropertyTraits.h @@ -0,0 +1,186 @@ +/* + Copyright (C) Research In Motion Limited 2010. All rights reserved. + Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SVGAnimatedPropertyTraits_h +#define SVGAnimatedPropertyTraits_h + +#if ENABLE(SVG) +#include "FloatRect.h" +#include "PlatformString.h" +#include "SVGAngle.h" +#include "SVGLength.h" +#include "SVGLengthList.h" +#include "SVGNumberList.h" +#include "SVGPreserveAspectRatio.h" +#include "SVGTransformList.h" + +namespace WebCore { + +template<typename Type> +struct SVGAnimatedPropertyTraits : public Noncopyable { }; + +// SVGAnimatedAngle +template<> +struct SVGAnimatedPropertyTraits<SVGAngle> : public Noncopyable { + typedef const SVGAngle& PassType; + typedef SVGAngle ReturnType; + typedef SVGAngle StoredType; + + static ReturnType null() { return SVGAngle(); } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return type.valueAsString(); } +}; + +// SVGAnimatedBoolean +template<> +struct SVGAnimatedPropertyTraits<bool> : public Noncopyable { + typedef const bool& PassType; + typedef bool ReturnType; + typedef bool StoredType; + + static ReturnType null() { return false; } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return type ? "true" : "false"; } +}; + +// SVGAnimatedEnumeration +template<> +struct SVGAnimatedPropertyTraits<int> : public Noncopyable { + typedef const int& PassType; + typedef int ReturnType; + typedef int StoredType; + + static ReturnType null() { return 0; } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return String::number(type); } +}; + +// SVGAnimatedInteger +template<> +struct SVGAnimatedPropertyTraits<long> : public Noncopyable { + typedef const long& PassType; + typedef long ReturnType; + typedef long StoredType; + + static ReturnType null() { return 0l; } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return String::number(type); } +}; + +// SVGAnimatedLength +template<> +struct SVGAnimatedPropertyTraits<SVGLength> : public Noncopyable { + typedef const SVGLength& PassType; + typedef SVGLength ReturnType; + typedef SVGLength StoredType; + + static ReturnType null() { return SVGLength(); } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return type.valueAsString(); } +}; + +// SVGAnimatedLengthList +template<> +struct SVGAnimatedPropertyTraits<SVGLengthList*> : public Noncopyable { + typedef SVGLengthList* PassType; + typedef SVGLengthList* ReturnType; + typedef RefPtr<SVGLengthList> StoredType; + + static ReturnType null() { return 0; } + static ReturnType toReturnType(const StoredType& type) { return type.get(); } + static String toString(PassType type) { return type ? type->valueAsString() : String(); } +}; + +// SVGAnimatedNumber +template<> +struct SVGAnimatedPropertyTraits<float> : public Noncopyable { + typedef const float& PassType; + typedef float ReturnType; + typedef float StoredType; + + static ReturnType null() { return 0.0f; } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return String::number(type); } +}; + +// SVGAnimatedNumberList +template<> +struct SVGAnimatedPropertyTraits<SVGNumberList*> : public Noncopyable { + typedef SVGNumberList* PassType; + typedef SVGNumberList* ReturnType; + typedef RefPtr<SVGNumberList> StoredType; + + static ReturnType null() { return 0; } + static ReturnType toReturnType(const StoredType& type) { return type.get(); } + static String toString(PassType type) { return type ? type->valueAsString() : String(); } +}; + +// SVGAnimatedPreserveAspectRatio +template<> +struct SVGAnimatedPropertyTraits<SVGPreserveAspectRatio> : public Noncopyable { + typedef const SVGPreserveAspectRatio& PassType; + typedef SVGPreserveAspectRatio ReturnType; + typedef SVGPreserveAspectRatio StoredType; + + static ReturnType null() { return SVGPreserveAspectRatio(); } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return type.valueAsString(); } +}; + +// SVGAnimatedRect +template<> +struct SVGAnimatedPropertyTraits<FloatRect> : public Noncopyable { + typedef const FloatRect& PassType; + typedef FloatRect ReturnType; + typedef FloatRect StoredType; + + static ReturnType null() { return FloatRect(); } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return String::format("%f %f %f %f", type.x(), type.y(), type.width(), type.height()); } +}; + +// SVGAnimatedString +template<> +struct SVGAnimatedPropertyTraits<String> : public Noncopyable { + typedef const String& PassType; + typedef String ReturnType; + typedef String StoredType; + + static ReturnType null() { return String(); } + static ReturnType toReturnType(const StoredType& type) { return type; } + static String toString(PassType type) { return type; } +}; + +// SVGAnimatedTransformList +template<> +struct SVGAnimatedPropertyTraits<SVGTransformList*> : public Noncopyable { + typedef SVGTransformList* PassType; + typedef SVGTransformList* ReturnType; + typedef RefPtr<SVGTransformList> StoredType; + + static ReturnType null() { return 0; } + static ReturnType toReturnType(const StoredType& type) { return type.get(); } + static String toString(PassType type) { return type ? type->valueAsString() : String(); } +}; + +} + +#endif +#endif diff --git a/WebCore/svg/SVGAnimatedTemplate.h b/WebCore/svg/SVGAnimatedTemplate.h index d65fe0b..589d724 100644 --- a/WebCore/svg/SVGAnimatedTemplate.h +++ b/WebCore/svg/SVGAnimatedTemplate.h @@ -22,9 +22,7 @@ #define SVGAnimatedTemplate_h #if ENABLE(SVG) -#include "AtomicString.h" -#include "FloatRect.h" -#include "SVGLength.h" +#include "SVGAnimatedPropertyTraits.h" #include <wtf/HashMap.h> namespace WebCore { @@ -101,18 +99,23 @@ namespace WebCore { } }; - template<typename BareType> - class SVGAnimatedTemplate : public RefCounted<SVGAnimatedTemplate<BareType> > { + template<typename AnimatedType> + class SVGAnimatedTemplate : public RefCounted<SVGAnimatedTemplate<AnimatedType> > { public: + typedef typename SVGAnimatedPropertyTraits<AnimatedType>::PassType PassType; + typedef typename SVGAnimatedPropertyTraits<AnimatedType>::ReturnType ReturnType; + virtual ~SVGAnimatedTemplate() { forgetWrapper(this); } - virtual BareType baseVal() const = 0; - virtual void setBaseVal(BareType) = 0; + virtual ReturnType baseVal() const = 0; + virtual void setBaseVal(PassType) = 0; + + virtual ReturnType animVal() const = 0; + virtual void setAnimVal(PassType) = 0; - virtual BareType animVal() const = 0; - virtual void setAnimVal(BareType) = 0; + virtual const QualifiedName& associatedAttributeName() const = 0; - typedef HashMap<SVGAnimatedTypeWrapperKey, SVGAnimatedTemplate<BareType>*, SVGAnimatedTypeWrapperKeyHash, SVGAnimatedTypeWrapperKeyHashTraits > ElementToWrapperMap; + typedef HashMap<SVGAnimatedTypeWrapperKey, SVGAnimatedTemplate<AnimatedType>*, SVGAnimatedTypeWrapperKeyHash, SVGAnimatedTypeWrapperKeyHashTraits > ElementToWrapperMap; typedef typename ElementToWrapperMap::const_iterator ElementToWrapperMapIterator; static ElementToWrapperMap* wrapperCache() @@ -121,7 +124,7 @@ namespace WebCore { return s_wrapperCache; } - static void forgetWrapper(SVGAnimatedTemplate<BareType>* wrapper) + static void forgetWrapper(SVGAnimatedTemplate<AnimatedType>* wrapper) { ElementToWrapperMap* cache = wrapperCache(); ElementToWrapperMapIterator itr = cache->begin(); @@ -133,113 +136,27 @@ namespace WebCore { } } } - - const QualifiedName& associatedAttributeName() const { return m_associatedAttributeName; } - - protected: - SVGAnimatedTemplate(const QualifiedName& attributeName) - : m_associatedAttributeName(attributeName) - { - } - - private: - const QualifiedName& m_associatedAttributeName; }; - template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + template<typename AnimatedType> class SVGAnimatedProperty; - template<typename OwnerType, typename AnimatedType, const char* TagName, const char* PropertyName, typename Type, typename OwnerElement> - PassRefPtr<Type> lookupOrCreateWrapper(const SVGAnimatedProperty<OwnerType, AnimatedType, TagName, PropertyName>& creator, - const OwnerElement* element, const QualifiedName& attrName, const AtomicString& attrIdentifier) + template<typename AnimatedType, typename AnimatedTearOff> + PassRefPtr<AnimatedTearOff> lookupOrCreateWrapper(SVGElement* element, SVGAnimatedProperty<AnimatedType>& creator, const QualifiedName& attrName) { - SVGAnimatedTypeWrapperKey key(element, attrIdentifier); - RefPtr<Type> wrapper = static_cast<Type*>(Type::wrapperCache()->get(key)); + SVGAnimatedTypeWrapperKey key(element, attrName.localName()); + RefPtr<AnimatedTearOff> wrapper = static_cast<AnimatedTearOff*>(AnimatedTearOff::wrapperCache()->get(key)); if (!wrapper) { - wrapper = Type::create(creator, element, attrName); - element->propertyController().setPropertyNeedsSynchronization(attrName); - Type::wrapperCache()->set(key, wrapper.get()); + wrapper = AnimatedTearOff::create(creator, element); + AnimatedTearOff::wrapperCache()->set(key, wrapper.get()); } return wrapper.release(); } - // Default implementation for pointer types - template<typename Type> - struct SVGAnimatedTypeValue : Noncopyable { - typedef RefPtr<Type> StorableType; - typedef Type* DecoratedType; - - static Type null() { return 0; } - static String toString(Type type) { return type ? type->valueAsString() : String(); } - }; - - template<> - struct SVGAnimatedTypeValue<bool> : Noncopyable { - typedef bool StorableType; - typedef bool DecoratedType; - - static bool null() { return false; } - static String toString(bool type) { return type ? "true" : "false"; } - }; - - template<> - struct SVGAnimatedTypeValue<int> : Noncopyable { - typedef int StorableType; - typedef int DecoratedType; - - static int null() { return 0; } - static String toString(int type) { return String::number(type); } - }; - - template<> - struct SVGAnimatedTypeValue<long> : Noncopyable { - typedef long StorableType; - typedef long DecoratedType; - - static long null() { return 0l; } - static String toString(long type) { return String::number(type); } - }; - - template<> - struct SVGAnimatedTypeValue<SVGLength> : Noncopyable { - typedef SVGLength StorableType; - typedef SVGLength DecoratedType; - - static SVGLength null() { return SVGLength(); } - static String toString(const SVGLength& type) { return type.valueAsString(); } - }; - - template<> - struct SVGAnimatedTypeValue<float> : Noncopyable { - typedef float StorableType; - typedef float DecoratedType; - - static float null() { return 0.0f; } - static String toString(float type) { return String::number(type); } - }; - - template<> - struct SVGAnimatedTypeValue<FloatRect> : Noncopyable { - typedef FloatRect StorableType; - typedef FloatRect DecoratedType; - - static FloatRect null() { return FloatRect(); } - static String toString(const FloatRect& type) { return String::format("%f %f %f %f", type.x(), type.y(), type.width(), type.height()); } - }; - - template<> - struct SVGAnimatedTypeValue<String> : Noncopyable { - typedef String StorableType; - typedef String DecoratedType; - - static String null() { return String(); } - static String toString(const String& type) { return type; } - }; - // Common type definitions, to ease IDL generation. - typedef SVGAnimatedTemplate<SVGAngle*> SVGAnimatedAngle; + typedef SVGAnimatedTemplate<SVGAngle> SVGAnimatedAngle; typedef SVGAnimatedTemplate<bool> SVGAnimatedBoolean; typedef SVGAnimatedTemplate<int> SVGAnimatedEnumeration; typedef SVGAnimatedTemplate<long> SVGAnimatedInteger; @@ -247,12 +164,12 @@ namespace WebCore { typedef SVGAnimatedTemplate<SVGLengthList*> SVGAnimatedLengthList; typedef SVGAnimatedTemplate<float> SVGAnimatedNumber; typedef SVGAnimatedTemplate<SVGNumberList*> SVGAnimatedNumberList; - typedef SVGAnimatedTemplate<SVGPreserveAspectRatio*> SVGAnimatedPreserveAspectRatio; + typedef SVGAnimatedTemplate<SVGPreserveAspectRatio> SVGAnimatedPreserveAspectRatio; typedef SVGAnimatedTemplate<FloatRect> SVGAnimatedRect; typedef SVGAnimatedTemplate<String> SVGAnimatedString; typedef SVGAnimatedTemplate<SVGTransformList*> SVGAnimatedTransformList; } -#endif // ENABLE(SVG) -#endif // SVGAnimatedTemplate_h +#endif +#endif diff --git a/WebCore/svg/SVGAnimationElement.cpp b/WebCore/svg/SVGAnimationElement.cpp index ce3670d..39abbfc 100644 --- a/WebCore/svg/SVGAnimationElement.cpp +++ b/WebCore/svg/SVGAnimationElement.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> Copyright (C) 2007 Eric Seidel <eric@webkit.org> Copyright (C) 2008 Apple Inc. All rights reserved. @@ -51,7 +51,6 @@ SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document* : SVGSMILElement(tagName, doc) , SVGTests() , SVGExternalResourcesRequired() - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) , m_animationValid(false) { } @@ -59,7 +58,7 @@ SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document* SVGAnimationElement::~SVGAnimationElement() { } - + static void parseKeyTimes(const String& parse, Vector<float>& result, bool verifyOrder) { result.clear(); @@ -141,6 +140,14 @@ void SVGAnimationElement::attributeChanged(Attribute* attr, bool preserveDecls) SVGSMILElement::attributeChanged(attr, preserveDecls); } +void SVGAnimationElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGSMILElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + float SVGAnimationElement::getStartTime() const { return narrowPrecisionToFloat(intervalBegin().value()); @@ -309,9 +316,9 @@ void SVGAnimationElement::setTargetAttributeAnimatedValue(const String& value) static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(false); // If the target element is used in an <use> instance tree, update that as well. - HashSet<SVGElementInstance*> instances = target->instancesForElement(); - HashSet<SVGElementInstance*>::iterator end = instances.end(); - for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) { + const HashSet<SVGElementInstance*>& instances = target->instancesForElement(); + const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); + for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); ASSERT(shadowTreeElement); if (isCSS) diff --git a/WebCore/svg/SVGAnimationElement.h b/WebCore/svg/SVGAnimationElement.h index b0b091b..27cec88 100644 --- a/WebCore/svg/SVGAnimationElement.h +++ b/WebCore/svg/SVGAnimationElement.h @@ -46,9 +46,10 @@ namespace WebCore { public: SVGAnimationElement(const QualifiedName&, Document*); virtual ~SVGAnimationElement(); - + virtual void parseMappedAttribute(MappedAttribute*); virtual void attributeChanged(Attribute*, bool preserveDecls); + virtual void synchronizeProperty(const QualifiedName&); // SVGAnimationElement float getStartTime() const; @@ -106,9 +107,7 @@ namespace WebCore { protected: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGAnimationElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGAnimationElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) bool m_animationValid; diff --git a/WebCore/svg/SVGAnimationElement.idl b/WebCore/svg/SVGAnimationElement.idl index afa3cbb..e221545 100644 --- a/WebCore/svg/SVGAnimationElement.idl +++ b/WebCore/svg/SVGAnimationElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG_ANIMATION] SVGAnimationElement : SVGElement, + interface [Conditional=SVG_ANIMATION, OmitConstructor] SVGAnimationElement : SVGElement, SVGTests, SVGExternalResourcesRequired, ElementTimeControl { diff --git a/WebCore/svg/SVGCircleElement.cpp b/WebCore/svg/SVGCircleElement.cpp index d96842a..10da742 100644 --- a/WebCore/svg/SVGCircleElement.cpp +++ b/WebCore/svg/SVGCircleElement.cpp @@ -36,10 +36,9 @@ SVGCircleElement::SVGCircleElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_cx(this, SVGNames::cxAttr, LengthModeWidth) - , m_cy(this, SVGNames::cyAttr, LengthModeHeight) - , m_r(this, SVGNames::rAttr, LengthModeOther) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_cx(LengthModeWidth) + , m_cy(LengthModeHeight) + , m_r(LengthModeOther) { } @@ -84,6 +83,28 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGCircleElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeCx(); + synchronizeCy(); + synchronizeR(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::cxAttr) + synchronizeCx(); + else if (attrName == SVGNames::cyAttr) + synchronizeCy(); + else if (attrName == SVGNames::rAttr) + synchronizeR(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + Path SVGCircleElement::toPathData() const { return Path::createCircle(FloatPoint(cx().value(this), cy().value(this)), r().value(this)); diff --git a/WebCore/svg/SVGCircleElement.h b/WebCore/svg/SVGCircleElement.h index 69b015d..027918c 100644 --- a/WebCore/svg/SVGCircleElement.h +++ b/WebCore/svg/SVGCircleElement.h @@ -41,6 +41,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual Path toPathData() const; @@ -48,14 +49,12 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGNames::circleTagString, SVGNames::cxAttrString, SVGLength, Cx, cx) - ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGNames::circleTagString, SVGNames::cyAttrString, SVGLength, Cy, cy) - ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGNames::circleTagString, SVGNames::rAttrString, SVGLength, R, r) + DECLARE_ANIMATED_PROPERTY(SVGCircleElement, SVGNames::cxAttr, SVGLength, Cx, cx) + DECLARE_ANIMATED_PROPERTY(SVGCircleElement, SVGNames::cyAttr, SVGLength, Cy, cy) + DECLARE_ANIMATED_PROPERTY(SVGCircleElement, SVGNames::rAttr, SVGLength, R, r) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGCircleElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGClipPathElement.cpp b/WebCore/svg/SVGClipPathElement.cpp index d5df29c..0fa12ff 100644 --- a/WebCore/svg/SVGClipPathElement.cpp +++ b/WebCore/svg/SVGClipPathElement.cpp @@ -26,6 +26,7 @@ #include "CSSStyleSelector.h" #include "Document.h" #include "MappedAttribute.h" +#include "RenderSVGHiddenContainer.h" #include "SVGNames.h" #include "SVGTransformList.h" #include "SVGUnitTypes.h" @@ -37,8 +38,7 @@ SVGClipPathElement::SVGClipPathElement(const QualifiedName& tagName, Document* d , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_clipPathUnits(this, SVGNames::clipPathUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_clipPathUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { } @@ -79,6 +79,22 @@ void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName) m_clipper->invalidate(); } +void SVGClipPathElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeClipPathUnits(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::clipPathUnitsAttr) + synchronizeClipPathUnits(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + void SVGClipPathElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGStyledTransformableElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); @@ -89,7 +105,12 @@ void SVGClipPathElement::childrenChanged(bool changedByParser, Node* beforeChang m_clipper->invalidate(); } -SVGResource* SVGClipPathElement::canvasResource() +RenderObject* SVGClipPathElement::createRenderer(RenderArena* arena, RenderStyle*) +{ + return new (arena) RenderSVGHiddenContainer(this); +} + +SVGResource* SVGClipPathElement::canvasResource(const RenderObject*) { if (!m_clipper) m_clipper = SVGResourceClipper::create(); @@ -98,17 +119,17 @@ SVGResource* SVGClipPathElement::canvasResource() bool bbox = clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; - RefPtr<RenderStyle> clipPathStyle = styleForRenderer(); // FIXME: Manual style resolution is a hack - for (Node* n = firstChild(); n; n = n->nextSibling()) { - if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) { - SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(n); - RefPtr<RenderStyle> pathStyle = document()->styleSelector()->styleForElement(styled, clipPathStyle.get()); - if (pathStyle->display() != NONE) { - Path pathData = styled->toClipPath(); - if (!pathData.isEmpty()) - m_clipper->addClipData(pathData, pathStyle->svgStyle()->clipRule(), bbox); - } - } + for (Node* node = firstChild(); node; node = node->nextSibling()) { + if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyledTransformable()) + continue; + SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(node); + RenderStyle* style = styled->renderer() ? styled->renderer()->style() : 0; + if (!style || style->display() == NONE) + continue; + Path pathData = styled->toClipPath(); + if (pathData.isEmpty()) + continue; + m_clipper->addClipData(pathData, style->svgStyle()->clipRule(), bbox); } if (m_clipper->clipData().isEmpty()) { Path pathData; diff --git a/WebCore/svg/SVGClipPathElement.h b/WebCore/svg/SVGClipPathElement.h index 6079159..cf7ff2b 100644 --- a/WebCore/svg/SVGClipPathElement.h +++ b/WebCore/svg/SVGClipPathElement.h @@ -22,6 +22,7 @@ #define SVGClipPathElement_h #if ENABLE(SVG) +#include "RenderObject.h" #include "SVGExternalResourcesRequired.h" #include "SVGLangSpace.h" #include "SVGResourceClipper.h" @@ -39,21 +40,20 @@ namespace WebCore { virtual ~SVGClipPathElement(); virtual bool isValid() const { return SVGTests::isValid(); } - virtual bool rendererIsNeeded(RenderStyle*) { return false; } virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); - virtual SVGResource* canvasResource(); + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + virtual SVGResource* canvasResource(const RenderObject*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGClipPathElement, SVGNames::clipPathTagString, SVGNames::clipPathUnitsAttrString, int, ClipPathUnits, clipPathUnits) + DECLARE_ANIMATED_PROPERTY(SVGClipPathElement, SVGNames::clipPathUnitsAttr, int, ClipPathUnits, clipPathUnits) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGClipPathElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGClipPathElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) RefPtr<SVGResourceClipper> m_clipper; }; diff --git a/WebCore/svg/SVGColor.idl b/WebCore/svg/SVGColor.idl index 43bcb70..32a2683 100644 --- a/WebCore/svg/SVGColor.idl +++ b/WebCore/svg/SVGColor.idl @@ -21,7 +21,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGColor : css::CSSValue { + interface [Conditional=SVG] SVGColor : css::CSSValue { // Color Types const unsigned short SVG_COLORTYPE_UNKNOWN = 0; const unsigned short SVG_COLORTYPE_RGBCOLOR = 1; diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.cpp b/WebCore/svg/SVGComponentTransferFunctionElement.cpp index bb08ebb..f61b2ea 100644 --- a/WebCore/svg/SVGComponentTransferFunctionElement.cpp +++ b/WebCore/svg/SVGComponentTransferFunctionElement.cpp @@ -30,17 +30,13 @@ namespace WebCore { -char SVGComponentTransferFunctionElementIdentifier[] = "SVGComponentTransferFunctionElement"; - SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) - , m_type(this, SVGNames::typeAttr, FECOMPONENTTRANSFER_TYPE_UNKNOWN) - , m_tableValues(this, SVGNames::tableValuesAttr, SVGNumberList::create(SVGNames::tableValuesAttr)) - , m_slope(this, SVGNames::slopeAttr, 1.0f) - , m_intercept(this, SVGNames::interceptAttr) - , m_amplitude(this, SVGNames::amplitudeAttr, 1.0f) - , m_exponent(this, SVGNames::exponentAttr, 1.0f) - , m_offset(this, SVGNames::offsetAttr) + , m_type(FECOMPONENTTRANSFER_TYPE_UNKNOWN) + , m_tableValues(SVGNumberList::create(SVGNames::tableValuesAttr)) + , m_slope(1.0f) + , m_amplitude(1.0f) + , m_exponent(1.0f) { } @@ -51,8 +47,7 @@ SVGComponentTransferFunctionElement::~SVGComponentTransferFunctionElement() void SVGComponentTransferFunctionElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); - if (attr->name() == SVGNames::typeAttr) - { + if (attr->name() == SVGNames::typeAttr) { if (value == "identity") setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_IDENTITY); else if (value == "table") @@ -80,6 +75,37 @@ void SVGComponentTransferFunctionElement::parseMappedAttribute(MappedAttribute* SVGElement::parseMappedAttribute(attr); } +void SVGComponentTransferFunctionElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeType(); + synchronizeTableValues(); + synchronizeSlope(); + synchronizeIntercept(); + synchronizeAmplitude(); + synchronizeExponent(); + synchronizeOffset(); + return; + } + + if (attrName == SVGNames::typeAttr) + synchronizeType(); + else if (attrName == SVGNames::tableValuesAttr) + synchronizeTableValues(); + else if (attrName == SVGNames::slopeAttr) + synchronizeSlope(); + else if (attrName == SVGNames::interceptAttr) + synchronizeIntercept(); + else if (attrName == SVGNames::amplitudeAttr) + synchronizeAmplitude(); + else if (attrName == SVGNames::exponentAttr) + synchronizeExponent(); + else if (attrName == SVGNames::offsetAttr) + synchronizeOffset(); +} + ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction() const { ComponentTransferFunction func; @@ -100,6 +126,4 @@ ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction( } -// vim:ts=4:noet #endif // ENABLE(SVG) - diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.h b/WebCore/svg/SVGComponentTransferFunctionElement.h index c955df5..9862a99 100644 --- a/WebCore/svg/SVGComponentTransferFunctionElement.h +++ b/WebCore/svg/SVGComponentTransferFunctionElement.h @@ -29,25 +29,24 @@ namespace WebCore { - extern char SVGComponentTransferFunctionElementIdentifier[]; - class SVGComponentTransferFunctionElement : public SVGElement { public: SVGComponentTransferFunctionElement(const QualifiedName&, Document*); virtual ~SVGComponentTransferFunctionElement(); - virtual void parseMappedAttribute(MappedAttribute* attr); + virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); ComponentTransferFunction transferFunction() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::typeAttrString, int, Type, type) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::tableValuesAttrString, SVGNumberList, TableValues, tableValues) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::slopeAttrString, float, Slope, slope) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::interceptAttrString, float, Intercept, intercept) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::amplitudeAttrString, float, Amplitude, amplitude) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::exponentAttrString, float, Exponent, exponent) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::offsetAttrString, float, Offset, offset) + DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::typeAttr, int, Type, type) + DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::tableValuesAttr, SVGNumberList*, TableValues, tableValues) + DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::slopeAttr, float, Slope, slope) + DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::interceptAttr, float, Intercept, intercept) + DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::amplitudeAttr, float, Amplitude, amplitude) + DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::exponentAttr, float, Exponent, exponent) + DECLARE_ANIMATED_PROPERTY(SVGComponentTransferFunctionElement, SVGNames::offsetAttr, float, Offset, offset) }; } // namespace WebCore diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.idl b/WebCore/svg/SVGComponentTransferFunctionElement.idl index 0868175..950f77d 100644 --- a/WebCore/svg/SVGComponentTransferFunctionElement.idl +++ b/WebCore/svg/SVGComponentTransferFunctionElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGComponentTransferFunctionElement : SVGElement { + interface [Conditional=SVG&FILTERS] SVGComponentTransferFunctionElement : SVGElement { // Component Transfer Types const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0; const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1; diff --git a/WebCore/svg/SVGCursorElement.cpp b/WebCore/svg/SVGCursorElement.cpp index f5aa615..e904516 100644 --- a/WebCore/svg/SVGCursorElement.cpp +++ b/WebCore/svg/SVGCursorElement.cpp @@ -36,10 +36,8 @@ SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGExternalResourcesRequired() , SVGURIReference() - , m_x(this, SVGNames::xAttr, LengthModeWidth) - , m_y(this, SVGNames::yAttr, LengthModeHeight) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_x(LengthModeWidth) + , m_y(LengthModeHeight) { } @@ -96,6 +94,28 @@ void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName) } } +void SVGCursorElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + void SVGCursorElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const { SVGElement::addSubresourceAttributeURLs(urls); diff --git a/WebCore/svg/SVGCursorElement.h b/WebCore/svg/SVGCursorElement.h index ee919a4..0978124 100644 --- a/WebCore/svg/SVGCursorElement.h +++ b/WebCore/svg/SVGCursorElement.h @@ -45,20 +45,19 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGNames::cursorTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGNames::cursorTagString, SVGNames::yAttrString, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGCursorElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGCursorElement, SVGNames::yAttr, SVGLength, Y, y) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGCursorElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGCursorElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) HashSet<SVGElement*> m_clients; }; diff --git a/WebCore/svg/SVGDefsElement.cpp b/WebCore/svg/SVGDefsElement.cpp index 051edeb..e7bf51d 100644 --- a/WebCore/svg/SVGDefsElement.cpp +++ b/WebCore/svg/SVGDefsElement.cpp @@ -32,7 +32,6 @@ SVGDefsElement::SVGDefsElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -50,6 +49,14 @@ RenderObject* SVGDefsElement::createRenderer(RenderArena* arena, RenderStyle*) return new (arena) RenderSVGHiddenContainer(this); } +void SVGDefsElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGDefsElement.h b/WebCore/svg/SVGDefsElement.h index 4bb206e..cb62d45 100644 --- a/WebCore/svg/SVGDefsElement.h +++ b/WebCore/svg/SVGDefsElement.h @@ -40,12 +40,11 @@ namespace WebCore { virtual bool isValid() const; virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + virtual void synchronizeProperty(const QualifiedName&); private: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGDefsElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGDefsElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGDocument.cpp b/WebCore/svg/SVGDocument.cpp index fe8ab80..2264a11 100644 --- a/WebCore/svg/SVGDocument.cpp +++ b/WebCore/svg/SVGDocument.cpp @@ -36,7 +36,7 @@ namespace WebCore { SVGDocument::SVGDocument(Frame* frame) - : Document(frame, false) + : Document(frame, false, false) { } diff --git a/WebCore/svg/SVGDocumentExtensions.h b/WebCore/svg/SVGDocumentExtensions.h index b66e2dc..050e6f6 100644 --- a/WebCore/svg/SVGDocumentExtensions.h +++ b/WebCore/svg/SVGDocumentExtensions.h @@ -31,15 +31,11 @@ #include "StringHash.h" #include "StringImpl.h" -#include "SVGAnimatedTemplate.h" namespace WebCore { class Document; -class EventListener; -class Node; class String; -class SVGElementInstance; class SVGStyledElement; class SVGSMILElement; class SVGSVGElement; @@ -68,13 +64,6 @@ private: SVGDocumentExtensions(const SVGDocumentExtensions&); SVGDocumentExtensions& operator=(const SVGDocumentExtensions&); - template<typename ValueType> - HashMap<const SVGElement*, HashMap<StringImpl*, ValueType>*>* baseValueMap() const - { - static HashMap<const SVGElement*, HashMap<StringImpl*, ValueType>*>* s_baseValueMap = new HashMap<const SVGElement*, HashMap<StringImpl*, ValueType>*>(); - return s_baseValueMap; - } - public: // This HashMap contains a list of pending resources. Pending resources, are such // which are referenced by any object in the SVG document, but do NOT exist yet. @@ -82,52 +71,9 @@ public: void addPendingResource(const AtomicString& id, SVGStyledElement*); bool isPendingResource(const AtomicString& id) const; std::auto_ptr<HashSet<SVGStyledElement*> > removePendingResource(const AtomicString& id); - - // Used by the ANIMATED_PROPERTY_* macros - template<typename ValueType> - ValueType baseValue(const SVGElement* element, const AtomicString& propertyName) const - { - HashMap<StringImpl*, ValueType>* propertyMap = baseValueMap<ValueType>()->get(element); - if (propertyMap) - return propertyMap->get(propertyName.impl()); - - return SVGAnimatedTypeValue<ValueType>::null(); - } - - template<typename ValueType> - void setBaseValue(const SVGElement* element, const AtomicString& propertyName, ValueType newValue) - { - HashMap<StringImpl*, ValueType>* propertyMap = baseValueMap<ValueType>()->get(element); - if (!propertyMap) { - propertyMap = new HashMap<StringImpl*, ValueType>(); - baseValueMap<ValueType>()->set(element, propertyMap); - } - - propertyMap->set(propertyName.impl(), newValue); - } - - template<typename ValueType> - void removeBaseValue(const SVGElement* element, const AtomicString& propertyName) - { - HashMap<StringImpl*, ValueType>* propertyMap = baseValueMap<ValueType>()->get(element); - if (!propertyMap) - return; - - propertyMap->remove(propertyName.impl()); - } - - template<typename ValueType> - bool hasBaseValue(const SVGElement* element, const AtomicString& propertyName) const - { - HashMap<StringImpl*, ValueType>* propertyMap = baseValueMap<ValueType>()->get(element); - if (propertyMap) - return propertyMap->contains(propertyName.impl()); - - return false; - } }; } -#endif // ENABLE(SVG) +#endif #endif diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp index 27e8c04..19c5f3b 100644 --- a/WebCore/svg/SVGElement.cpp +++ b/WebCore/svg/SVGElement.cpp @@ -38,8 +38,8 @@ #include "RegisteredEventListener.h" #include "RenderObject.h" #include "SVGCursorElement.h" -#include "SVGDocumentExtensions.h" #include "SVGElementInstance.h" +#include "SVGElementRareData.h" #include "SVGNames.h" #include "SVGResource.h" #include "SVGSVGElement.h" @@ -54,9 +54,6 @@ using namespace HTMLNames; SVGElement::SVGElement(const QualifiedName& tagName, Document* document) : StyledElement(tagName, document, CreateElementZeroRefCount) - , m_shadowParent(0) - , m_cursorElement(0) - , m_cursorImageValue(0) { } @@ -67,10 +64,40 @@ PassRefPtr<SVGElement> SVGElement::create(const QualifiedName& tagName, Document SVGElement::~SVGElement() { - if (m_cursorElement) - m_cursorElement->removeClient(this); - if (m_cursorImageValue) - m_cursorImageValue->removeReferencedElement(this); + if (!hasRareSVGData()) + ASSERT(!SVGElementRareData::rareDataMap().contains(this)); + else { + SVGElementRareData::SVGElementRareDataMap& rareDataMap = SVGElementRareData::rareDataMap(); + SVGElementRareData::SVGElementRareDataMap::iterator it = rareDataMap.find(this); + ASSERT(it != rareDataMap.end()); + + SVGElementRareData* rareData = it->second; + if (SVGCursorElement* cursorElement = rareData->cursorElement()) + cursorElement->removeClient(this); + if (CSSCursorImageValue* cursorImageValue = rareData->cursorImageValue()) + cursorImageValue->removeReferencedElement(this); + + delete rareData; + rareDataMap.remove(it); + } +} + +SVGElementRareData* SVGElement::rareSVGData() const +{ + ASSERT(hasRareSVGData()); + return SVGElementRareData::rareDataFromMap(this); +} + +SVGElementRareData* SVGElement::ensureRareSVGData() +{ + if (hasRareSVGData()) + return rareSVGData(); + + ASSERT(!SVGElementRareData::rareDataMap().contains(this)); + SVGElementRareData* data = new SVGElementRareData; + SVGElementRareData::rareDataMap().set(this, data); + m_hasRareSVGData = true; + return data; } bool SVGElement::isSupported(StringImpl* feature, StringImpl* version) const @@ -118,7 +145,6 @@ SVGElement* SVGElement::viewportElement() const SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions() const { - // This function is provided for use by SVGAnimatedProperty to avoid // global inclusion of Document.h in SVG code. return document() ? document()->accessSVGExtensions() : 0; @@ -127,20 +153,41 @@ SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions() const void SVGElement::mapInstanceToElement(SVGElementInstance* instance) { ASSERT(instance); - ASSERT(!m_elementInstances.contains(instance)); - m_elementInstances.add(instance); + + HashSet<SVGElementInstance*>& instances = ensureRareSVGData()->elementInstances(); + ASSERT(!instances.contains(instance)); + + instances.add(instance); } void SVGElement::removeInstanceMapping(SVGElementInstance* instance) { ASSERT(instance); - ASSERT(m_elementInstances.contains(instance)); - m_elementInstances.remove(instance); + ASSERT(hasRareSVGData()); + + HashSet<SVGElementInstance*>& instances = rareSVGData()->elementInstances(); + ASSERT(instances.contains(instance)); + + instances.remove(instance); } -HashSet<SVGElementInstance*> SVGElement::instancesForElement() const +const HashSet<SVGElementInstance*>& SVGElement::instancesForElement() const { - return m_elementInstances; + if (!hasRareSVGData()) { + DEFINE_STATIC_LOCAL(HashSet<SVGElementInstance*>, emptyInstances, ()); + return emptyInstances; + } + return rareSVGData()->elementInstances(); +} + +void SVGElement::setCursorElement(SVGCursorElement* cursorElement) +{ + ensureRareSVGData()->setCursorElement(cursorElement); +} + +void SVGElement::setCursorImageValue(CSSCursorImageValue* cursorImageValue) +{ + ensureRareSVGData()->setCursorImageValue(cursorImageValue); } void SVGElement::parseMappedAttribute(MappedAttribute* attr) @@ -234,7 +281,7 @@ void SVGElement::insertedIntoDocument() StyledElement::insertedIntoDocument(); SVGDocumentExtensions* extensions = document()->accessSVGExtensions(); - String resourceId = SVGURIReference::getTarget(getAttribute(idAttr)); + String resourceId = SVGURIReference::getTarget(getAttribute(idAttributeName())); if (extensions->isPendingResource(resourceId)) { std::auto_ptr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(resourceId)); if (clients->isEmpty()) @@ -260,7 +307,7 @@ void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls) svgAttributeChanged(attr->name()); } -void SVGElement::updateAnimatedSVGAttribute(const String& name) const +void SVGElement::updateAnimatedSVGAttribute(const QualifiedName& name) const { ASSERT(!m_areSVGAttributesValid); @@ -269,23 +316,20 @@ void SVGElement::updateAnimatedSVGAttribute(const String& name) const m_synchronizingSVGAttributes = true; - if (name.isEmpty()) { - m_propertyController.synchronizeAllProperties(); - setSynchronizedSVGAttributes(true); - } else - m_propertyController.synchronizeProperty(name); + const_cast<SVGElement*>(this)->synchronizeProperty(name); + if (name == anyQName()) + m_areSVGAttributesValid = true; m_synchronizingSVGAttributes = false; } -void SVGElement::setSynchronizedSVGAttributes(bool value) const -{ - m_areSVGAttributesValid = value; -} - ContainerNode* SVGElement::eventParentNode() { - return m_shadowParent ? m_shadowParent : StyledElement::eventParentNode(); + if (Node* shadowParent = shadowParentNode()) { + ASSERT(shadowParent->isContainerNode()); + return static_cast<ContainerNode*>(shadowParent); + } + return StyledElement::eventParentNode(); } } diff --git a/WebCore/svg/SVGElement.h b/WebCore/svg/SVGElement.h index b247a74..679c265 100644 --- a/WebCore/svg/SVGElement.h +++ b/WebCore/svg/SVGElement.h @@ -23,17 +23,16 @@ #define SVGElement_h #if ENABLE(SVG) +#include "SVGDocumentExtensions.h" #include "StyledElement.h" -#include "SVGAnimatedProperty.h" -#include "SynchronizablePropertyController.h" namespace WebCore { class CSSCursorImageValue; class Document; class SVGCursorElement; - class SVGDocumentExtensions; class SVGElementInstance; + class SVGElementRareData; class SVGSVGElement; class TransformationMatrix; @@ -60,8 +59,6 @@ namespace WebCore { virtual bool isGradientStop() const { return false; } virtual bool isTextContent() const { return false; } - void setShadowParentNode(ContainerNode* node) { m_shadowParent = node; } - // For SVGTests virtual bool isValid() const { return true; } @@ -69,19 +66,18 @@ namespace WebCore { virtual bool childShouldCreateRenderer(Node*) const; virtual void svgAttributeChanged(const QualifiedName&) { } + virtual void synchronizeProperty(const QualifiedName&) { } void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false); virtual TransformationMatrix* supplementalTransform() { return 0; } - virtual void setSynchronizedSVGAttributes(bool) const; + void setSynchronizedSVGAttributes(bool value) { m_areSVGAttributesValid = value; } - HashSet<SVGElementInstance*> instancesForElement() const; + const HashSet<SVGElementInstance*>& instancesForElement() const; - void setCursorElement(SVGCursorElement* cursorElement) { m_cursorElement = cursorElement; } - void setCursorImageValue(CSSCursorImageValue* cursorImageValue) { m_cursorImageValue = cursorImageValue; } - - SynchronizablePropertyController& propertyController() const { return m_propertyController; } + void setCursorElement(SVGCursorElement*); + void setCursorImageValue(CSSCursorImageValue*); protected: SVGElement(const QualifiedName&, Document*); @@ -89,36 +85,30 @@ namespace WebCore { virtual void finishParsingChildren(); virtual void insertedIntoDocument(); virtual void attributeChanged(Attribute*, bool preserveDecls = false); - virtual void updateAnimatedSVGAttribute(const String&) const; + virtual void updateAnimatedSVGAttribute(const QualifiedName&) const; + + SVGElementRareData* rareSVGData() const; + SVGElementRareData* ensureRareSVGData(); private: friend class SVGElementInstance; virtual bool isSVGElement() const { return true; } - virtual bool isSupported(StringImpl* feature, StringImpl* version) const; - - virtual bool isShadowNode() const { return m_shadowParent; } - virtual Node* shadowParentNode() { return m_shadowParent; } - virtual ContainerNode* eventParentNode(); + virtual ContainerNode* eventParentNode(); virtual void buildPendingResource() { } void mapInstanceToElement(SVGElementInstance*); void removeInstanceMapping(SVGElementInstance*); virtual bool haveLoadedRequiredResources(); - - ContainerNode* m_shadowParent; - mutable SynchronizablePropertyController m_propertyController; - - SVGCursorElement* m_cursorElement; - CSSCursorImageValue* m_cursorImageValue; - - HashSet<SVGElementInstance*> m_elementInstances; }; -} // namespace WebCore +} + +// This file needs to be included after the SVGElement declaration +#include "SVGAnimatedProperty.h" -#endif // ENABLE(SVG) -#endif // SVGElement_h +#endif +#endif diff --git a/WebCore/svg/SVGElementInstance.cpp b/WebCore/svg/SVGElementInstance.cpp index 46e8221..ca0a70c 100644 --- a/WebCore/svg/SVGElementInstance.cpp +++ b/WebCore/svg/SVGElementInstance.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) Research In Motion Limited 2010. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -33,26 +34,14 @@ #include <wtf/RefCountedLeakCounter.h> -#if USE(JSC) -#include "GCController.h" -#endif - namespace WebCore { #ifndef NDEBUG static WTF::RefCountedLeakCounter instanceCounter("WebCoreSVGElementInstance"); #endif -static EventTargetData& dummyEventTargetData() -{ - DEFINE_STATIC_LOCAL(EventTargetData, dummyEventTargetData, ()); - dummyEventTargetData.eventListenerMap.clear(); - return dummyEventTargetData; -} - SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement) - : m_needsUpdate(false) - , m_useElement(useElement) + : m_useElement(useElement) , m_element(originalElement) , m_previousSibling(0) , m_nextSibling(0) @@ -93,20 +82,6 @@ void SVGElementInstance::setShadowTreeElement(SVGElement* element) m_shadowTreeElement = element; } -void SVGElementInstance::forgetWrapper() -{ -#if USE(JSC) - // FIXME: This is fragile, as discussed with Sam. Need to find a better solution. - // Think about the case where JS explicitely holds "var root = useElement.instanceRoot;". - // We still have to recreate this wrapper somehow. The gc collection below, won't catch it. - - // If the use shadow tree has been rebuilt, just the JSSVGElementInstance objects - // are still holding RefPtrs of SVGElementInstance objects, which prevent us to - // be deleted (and the shadow tree is not destructed as well). Force JS GC. - gcController().garbageCollectNow(); -#endif -} - void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child) { appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), this); @@ -117,52 +92,39 @@ void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element) if (!element) return; - HashSet<SVGElementInstance*> set = element->instancesForElement(); + if (element->isStyled() && static_cast<SVGStyledElement*>(element)->instanceUpdatesBlocked()) + return; + + const HashSet<SVGElementInstance*>& set = element->instancesForElement(); if (set.isEmpty()) return; - // Find all use elements referencing the instances - ask them _once_ to rebuild. - HashSet<SVGElementInstance*>::const_iterator it = set.begin(); + // Mark all use elements referencing 'element' for rebuilding const HashSet<SVGElementInstance*>::const_iterator end = set.end(); - - for (; it != end; ++it) - (*it)->setNeedsUpdate(true); -} - -void SVGElementInstance::setNeedsUpdate(bool value) -{ - m_needsUpdate = value; - - if (m_needsUpdate) - correspondingUseElement()->setNeedsStyleRecalc(); + for (HashSet<SVGElementInstance*>::const_iterator it = set.begin(); it != end; ++it) { + ASSERT((*it)->correspondingElement() == element); + (*it)->correspondingUseElement()->invalidateShadowTree(); + } } ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const { - if (SVGElement* element = correspondingElement()) - return element->document(); - return 0; + return m_element->document(); } bool SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { - if (!correspondingElement()) - return false; - return correspondingElement()->addEventListener(eventType, listener, useCapture); + return m_element->addEventListener(eventType, listener, useCapture); } bool SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - if (!correspondingElement()) - return false; - return correspondingElement()->removeEventListener(eventType, listener, useCapture); + return m_element->removeEventListener(eventType, listener, useCapture); } void SVGElementInstance::removeAllEventListeners() { - if (!correspondingElement()) - return; - correspondingElement()->removeAllEventListeners(); + m_element->removeAllEventListeners(); } bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> prpEvent) @@ -182,14 +144,17 @@ bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> prpEvent) EventTargetData* SVGElementInstance::eventTargetData() { - return correspondingElement() ? correspondingElement()->eventTargetData() : 0; + return m_element->eventTargetData(); } EventTargetData* SVGElementInstance::ensureEventTargetData() { - return &dummyEventTargetData(); // return something, so we don't crash + // Avoid crashing - return a default dummy value + DEFINE_STATIC_LOCAL(EventTargetData, dummyEventTargetData, ()); + dummyEventTargetData.eventListenerMap.clear(); + return &dummyEventTargetData; } -} // namespace WebCore +} -#endif // ENABLE(SVG) +#endif diff --git a/WebCore/svg/SVGElementInstance.h b/WebCore/svg/SVGElementInstance.h index 3cdc761..58152be 100644 --- a/WebCore/svg/SVGElementInstance.h +++ b/WebCore/svg/SVGElementInstance.h @@ -46,9 +46,6 @@ namespace WebCore { virtual ~SVGElementInstance(); - bool needsUpdate() const { return m_needsUpdate; } - void setNeedsUpdate(bool); - virtual ScriptExecutionContext* scriptExecutionContext() const; virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); @@ -129,7 +126,6 @@ namespace WebCore { void appendChild(PassRefPtr<SVGElementInstance> child); void setShadowTreeElement(SVGElement*); - void forgetWrapper(); template<class GenericNode, class GenericNodeContainer> friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container); @@ -153,8 +149,6 @@ namespace WebCore { virtual EventTargetData* eventTargetData(); virtual EventTargetData* ensureEventTargetData(); - bool m_needsUpdate : 1; - SVGUseElement* m_useElement; RefPtr<SVGElement> m_element; RefPtr<SVGElement> m_shadowTreeElement; diff --git a/WebCore/svg/SVGElementRareData.h b/WebCore/svg/SVGElementRareData.h new file mode 100644 index 0000000..4e7f671 --- /dev/null +++ b/WebCore/svg/SVGElementRareData.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef SVGElementRareData_h +#define SVGElementRareData_h + +#include <wtf/HashSet.h> +#include <wtf/Noncopyable.h> +#include <wtf/StdLibExtras.h> + +namespace WebCore { + +class CSSCursorImageValue; +class SVGCursorElement; +class SVGElement; +class SVGElementInstance; + +class SVGElementRareData : public Noncopyable { +public: + SVGElementRareData() + : m_cursorElement(0) + , m_cursorImageValue(0) + , m_instancesUpdatesBlocked(false) + { + } + + typedef HashMap<const SVGElement*, SVGElementRareData*> SVGElementRareDataMap; + + static SVGElementRareDataMap& rareDataMap() + { + DEFINE_STATIC_LOCAL(SVGElementRareDataMap, rareDataMap, ()); + return rareDataMap; + } + + static SVGElementRareData* rareDataFromMap(const SVGElement* element) + { + return rareDataMap().get(element); + } + + HashSet<SVGElementInstance*>& elementInstances() { return m_elementInstances; } + const HashSet<SVGElementInstance*>& elementInstances() const { return m_elementInstances; } + + bool instanceUpdatesBlocked() const { return m_instancesUpdatesBlocked; } + void setInstanceUpdatesBlocked(bool value) { m_instancesUpdatesBlocked = value; } + + SVGCursorElement* cursorElement() const { return m_cursorElement; } + void setCursorElement(SVGCursorElement* cursorElement) { m_cursorElement = cursorElement; } + + CSSCursorImageValue* cursorImageValue() const { return m_cursorImageValue; } + void setCursorImageValue(CSSCursorImageValue* cursorImageValue) { m_cursorImageValue = cursorImageValue; } + +private: + HashSet<SVGElementInstance*> m_elementInstances; + SVGCursorElement* m_cursorElement; + CSSCursorImageValue* m_cursorImageValue; + bool m_instancesUpdatesBlocked : 1; +}; + +} + +#endif diff --git a/WebCore/svg/SVGEllipseElement.cpp b/WebCore/svg/SVGEllipseElement.cpp index 3946fb9..a7400fa 100644 --- a/WebCore/svg/SVGEllipseElement.cpp +++ b/WebCore/svg/SVGEllipseElement.cpp @@ -36,11 +36,10 @@ SVGEllipseElement::SVGEllipseElement(const QualifiedName& tagName, Document* doc , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_cx(this, SVGNames::cxAttr, LengthModeWidth) - , m_cy(this, SVGNames::cyAttr, LengthModeHeight) - , m_rx(this, SVGNames::rxAttr, LengthModeWidth) - , m_ry(this, SVGNames::ryAttr, LengthModeHeight) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_cx(LengthModeWidth) + , m_cy(LengthModeHeight) + , m_rx(LengthModeWidth) + , m_ry(LengthModeHeight) { } @@ -89,6 +88,31 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeCx(); + synchronizeCy(); + synchronizeRx(); + synchronizeRy(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::cxAttr) + synchronizeCx(); + else if (attrName == SVGNames::cyAttr) + synchronizeCy(); + else if (attrName == SVGNames::rxAttr) + synchronizeRx(); + else if (attrName == SVGNames::ryAttr) + synchronizeRy(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + Path SVGEllipseElement::toPathData() const { return Path::createEllipse(FloatPoint(cx().value(this), cy().value(this)), diff --git a/WebCore/svg/SVGEllipseElement.h b/WebCore/svg/SVGEllipseElement.h index 5b54fd5..adaa0d2 100644 --- a/WebCore/svg/SVGEllipseElement.h +++ b/WebCore/svg/SVGEllipseElement.h @@ -41,6 +41,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual Path toPathData() const; @@ -48,15 +49,13 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::cxAttrString, SVGLength, Cx, cx) - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::cyAttrString, SVGLength, Cy, cy) - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::rxAttrString, SVGLength, Rx, rx) - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::ryAttrString, SVGLength, Ry, ry) + DECLARE_ANIMATED_PROPERTY(SVGEllipseElement, SVGNames::cxAttr, SVGLength, Cx, cx) + DECLARE_ANIMATED_PROPERTY(SVGEllipseElement, SVGNames::cyAttr, SVGLength, Cy, cy) + DECLARE_ANIMATED_PROPERTY(SVGEllipseElement, SVGNames::rxAttr, SVGLength, Rx, rx) + DECLARE_ANIMATED_PROPERTY(SVGEllipseElement, SVGNames::ryAttr, SVGLength, Ry, ry) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGEllipseElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGException.idl b/WebCore/svg/SVGException.idl index 233f653..db565ff 100644 --- a/WebCore/svg/SVGException.idl +++ b/WebCore/svg/SVGException.idl @@ -21,8 +21,7 @@ module svg { interface [ - Conditional=SVG, - GenerateConstructor + Conditional=SVG ] SVGException { readonly attribute unsigned short code; diff --git a/WebCore/svg/SVGExternalResourcesRequired.cpp b/WebCore/svg/SVGExternalResourcesRequired.cpp index b6b62d1..99bc5eb 100644 --- a/WebCore/svg/SVGExternalResourcesRequired.cpp +++ b/WebCore/svg/SVGExternalResourcesRequired.cpp @@ -30,8 +30,6 @@ namespace WebCore { -char SVGExternalResourcesRequiredIdentifier[] = "SVGExternalResourcesRequired"; - SVGExternalResourcesRequired::SVGExternalResourcesRequired() { } diff --git a/WebCore/svg/SVGExternalResourcesRequired.h b/WebCore/svg/SVGExternalResourcesRequired.h index f088c82..b2a741d 100644 --- a/WebCore/svg/SVGExternalResourcesRequired.h +++ b/WebCore/svg/SVGExternalResourcesRequired.h @@ -27,7 +27,6 @@ namespace WebCore { - extern char SVGExternalResourcesRequiredIdentifier[]; class MappedAttribute; // Notes on a SVG 1.1 spec discrepancy: @@ -44,7 +43,7 @@ namespace WebCore { bool isKnownAttribute(const QualifiedName&); protected: - virtual void setExternalResourcesRequiredBaseValue(SVGAnimatedTypeValue<bool>::DecoratedType type) = 0; + virtual void setExternalResourcesRequiredBaseValue(SVGAnimatedPropertyTraits<bool>::PassType) = 0; }; } // namespace WebCore diff --git a/WebCore/svg/SVGExternalResourcesRequired.idl b/WebCore/svg/SVGExternalResourcesRequired.idl index 6600939..c1a0352 100644 --- a/WebCore/svg/SVGExternalResourcesRequired.idl +++ b/WebCore/svg/SVGExternalResourcesRequired.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGExternalResourcesRequired { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGExternalResourcesRequired { readonly attribute SVGAnimatedBoolean externalResourcesRequired; }; diff --git a/WebCore/svg/SVGFEBlendElement.cpp b/WebCore/svg/SVGFEBlendElement.cpp index 03c5795..46c412c 100644 --- a/WebCore/svg/SVGFEBlendElement.cpp +++ b/WebCore/svg/SVGFEBlendElement.cpp @@ -30,9 +30,7 @@ namespace WebCore { SVGFEBlendElement::SVGFEBlendElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_in2(this, SVGNames::in2Attr) - , m_mode(this, SVGNames::modeAttr, FEBLEND_MODE_NORMAL) + , m_mode(FEBLEND_MODE_NORMAL) { } @@ -62,6 +60,25 @@ void SVGFEBlendElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEBlendElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeMode(); + synchronizeIn1(); + synchronizeIn2(); + return; + } + + if (attrName == SVGNames::modeAttr) + synchronizeMode(); + else if (attrName == SVGNames::inAttr) + synchronizeIn1(); + else if (attrName == SVGNames::in2Attr) + synchronizeIn2(); +} + bool SVGFEBlendElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEBlendElement.h b/WebCore/svg/SVGFEBlendElement.h index c32eabd..7e32244 100644 --- a/WebCore/svg/SVGFEBlendElement.h +++ b/WebCore/svg/SVGFEBlendElement.h @@ -32,12 +32,13 @@ namespace WebCore { virtual ~SVGFEBlendElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, SVGNames::feBlendTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, SVGNames::feBlendTagString, SVGNames::in2AttrString, String, In2, in2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, SVGNames::feBlendTagString, SVGNames::modeAttrString, int, Mode, mode) + DECLARE_ANIMATED_PROPERTY(SVGFEBlendElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEBlendElement, SVGNames::in2Attr, String, In2, in2) + DECLARE_ANIMATED_PROPERTY(SVGFEBlendElement, SVGNames::modeAttr, int, Mode, mode) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEBlendElement.idl b/WebCore/svg/SVGFEBlendElement.idl index 4c1a18b..bb6d86d 100644 --- a/WebCore/svg/SVGFEBlendElement.idl +++ b/WebCore/svg/SVGFEBlendElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFEBlendElement : SVGElement, + interface [Conditional=SVG&FILTERS] SVGFEBlendElement : SVGElement, SVGFilterPrimitiveStandardAttributes { // Blend Mode Types const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0; diff --git a/WebCore/svg/SVGFEColorMatrixElement.cpp b/WebCore/svg/SVGFEColorMatrixElement.cpp index 88a0d66..e27ad86 100644 --- a/WebCore/svg/SVGFEColorMatrixElement.cpp +++ b/WebCore/svg/SVGFEColorMatrixElement.cpp @@ -32,9 +32,8 @@ namespace WebCore { SVGFEColorMatrixElement::SVGFEColorMatrixElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_type(this, SVGNames::typeAttr, FECOLORMATRIX_TYPE_UNKNOWN) - , m_values(this, SVGNames::valuesAttr, SVGNumberList::create(SVGNames::valuesAttr)) + , m_type(FECOLORMATRIX_TYPE_UNKNOWN) + , m_values(SVGNumberList::create(SVGNames::valuesAttr)) { } @@ -63,6 +62,25 @@ void SVGFEColorMatrixElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEColorMatrixElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeType(); + synchronizeIn1(); + synchronizeValues(); + return; + } + + if (attrName == SVGNames::typeAttr) + synchronizeType(); + else if (attrName == SVGNames::inAttr) + synchronizeIn1(); + else if (attrName == SVGNames::valuesAttr) + synchronizeValues(); +} + bool SVGFEColorMatrixElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEColorMatrixElement.h b/WebCore/svg/SVGFEColorMatrixElement.h index f3329e4..811494d 100644 --- a/WebCore/svg/SVGFEColorMatrixElement.h +++ b/WebCore/svg/SVGFEColorMatrixElement.h @@ -34,12 +34,13 @@ namespace WebCore { virtual ~SVGFEColorMatrixElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, SVGNames::feColorMatrixTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, SVGNames::feColorMatrixTagString, SVGNames::typeAttrString, int, Type, type) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, SVGNames::feColorMatrixTagString, SVGNames::valuesAttrString, SVGNumberList, Values, values) + DECLARE_ANIMATED_PROPERTY(SVGFEColorMatrixElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEColorMatrixElement, SVGNames::typeAttr, int, Type, type) + DECLARE_ANIMATED_PROPERTY(SVGFEColorMatrixElement, SVGNames::valuesAttr, SVGNumberList*, Values, values) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEColorMatrixElement.idl b/WebCore/svg/SVGFEColorMatrixElement.idl index c116fe7..d704906 100644 --- a/WebCore/svg/SVGFEColorMatrixElement.idl +++ b/WebCore/svg/SVGFEColorMatrixElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFEColorMatrixElement : SVGElement, + interface [Conditional=SVG&FILTERS] SVGFEColorMatrixElement : SVGElement, SVGFilterPrimitiveStandardAttributes { // Color Matrix Types const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0; diff --git a/WebCore/svg/SVGFEComponentTransferElement.cpp b/WebCore/svg/SVGFEComponentTransferElement.cpp index f1df08c..4cda9c9 100644 --- a/WebCore/svg/SVGFEComponentTransferElement.cpp +++ b/WebCore/svg/SVGFEComponentTransferElement.cpp @@ -37,7 +37,6 @@ namespace WebCore { SVGFEComponentTransferElement::SVGFEComponentTransferElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) { } @@ -54,6 +53,14 @@ void SVGFEComponentTransferElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEComponentTransferElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName() || attrName == SVGNames::inAttr) + synchronizeIn1(); +} + bool SVGFEComponentTransferElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEComponentTransferElement.h b/WebCore/svg/SVGFEComponentTransferElement.h index 46d6d9d..b1d9373 100644 --- a/WebCore/svg/SVGFEComponentTransferElement.h +++ b/WebCore/svg/SVGFEComponentTransferElement.h @@ -33,10 +33,11 @@ namespace WebCore { virtual ~SVGFEComponentTransferElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEComponentTransferElement, SVGNames::feComponentTransferTagString, SVGNames::inAttrString, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEComponentTransferElement, SVGNames::inAttr, String, In1, in1) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFECompositeElement.cpp b/WebCore/svg/SVGFECompositeElement.cpp index a2dd05a..734c2fe 100644 --- a/WebCore/svg/SVGFECompositeElement.cpp +++ b/WebCore/svg/SVGFECompositeElement.cpp @@ -31,13 +31,7 @@ namespace WebCore { SVGFECompositeElement::SVGFECompositeElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_in2(this, SVGNames::in2Attr) - , m__operator(this, SVGNames::operatorAttr, FECOMPOSITE_OPERATOR_OVER) - , m_k1(this, SVGNames::k1Attr) - , m_k2(this, SVGNames::k2Attr) - , m_k3(this, SVGNames::k3Attr) - , m_k4(this, SVGNames::k4Attr) + , m__operator(FECOMPOSITE_OPERATOR_OVER) { } @@ -61,8 +55,7 @@ void SVGFECompositeElement::parseMappedAttribute(MappedAttribute *attr) set_operatorBaseValue(FECOMPOSITE_OPERATOR_XOR); else if (value == "arithmetic") set_operatorBaseValue(FECOMPOSITE_OPERATOR_ARITHMETIC); - } - else if (attr->name() == SVGNames::inAttr) + } else if (attr->name() == SVGNames::inAttr) setIn1BaseValue(value); else if (attr->name() == SVGNames::in2Attr) setIn2BaseValue(value); @@ -78,6 +71,37 @@ void SVGFECompositeElement::parseMappedAttribute(MappedAttribute *attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFECompositeElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronize_operator(); + synchronizeIn1(); + synchronizeIn2(); + synchronizeK1(); + synchronizeK2(); + synchronizeK3(); + synchronizeK4(); + return; + } + + if (attrName == SVGNames::operatorAttr) + synchronize_operator(); + else if (attrName == SVGNames::inAttr) + synchronizeIn1(); + else if (attrName == SVGNames::in2Attr) + synchronizeIn2(); + else if (attrName == SVGNames::k1Attr) + synchronizeK1(); + else if (attrName == SVGNames::k2Attr) + synchronizeK2(); + else if (attrName == SVGNames::k3Attr) + synchronizeK3(); + else if (attrName == SVGNames::k4Attr) + synchronizeK4(); +} + bool SVGFECompositeElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFECompositeElement.h b/WebCore/svg/SVGFECompositeElement.h index 1bb6b05..c9fecc8 100644 --- a/WebCore/svg/SVGFECompositeElement.h +++ b/WebCore/svg/SVGFECompositeElement.h @@ -33,16 +33,17 @@ namespace WebCore { virtual ~SVGFECompositeElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::in2AttrString, String, In2, in2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::operatorAttrString, int, _operator, _operator) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k1AttrString, float, K1, k1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k2AttrString, float, K2, k2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k3AttrString, float, K3, k3) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k4AttrString, float, K4, k4) + DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::in2Attr, String, In2, in2) + DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::operatorAttr, int, _operator, _operator) + DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k1Attr, float, K1, k1) + DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k2Attr, float, K2, k2) + DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k3Attr, float, K3, k3) + DECLARE_ANIMATED_PROPERTY(SVGFECompositeElement, SVGNames::k4Attr, float, K4, k4) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFECompositeElement.idl b/WebCore/svg/SVGFECompositeElement.idl index d317997..d3adb25 100644 --- a/WebCore/svg/SVGFECompositeElement.idl +++ b/WebCore/svg/SVGFECompositeElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFECompositeElement : SVGElement, + interface [Conditional=SVG&FILTERS] SVGFECompositeElement : SVGElement, SVGFilterPrimitiveStandardAttributes { // Composite Operators const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0; diff --git a/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/WebCore/svg/SVGFEDiffuseLightingElement.cpp index ed6e353..a3db66d 100644 --- a/WebCore/svg/SVGFEDiffuseLightingElement.cpp +++ b/WebCore/svg/SVGFEDiffuseLightingElement.cpp @@ -40,11 +40,8 @@ char SVGKernelUnitLengthYIdentifier[] = "SVGKernelUnitLengthY"; SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_diffuseConstant(this, SVGNames::diffuseConstantAttr, 1.0f) - , m_surfaceScale(this, SVGNames::surfaceScaleAttr, 1.0f) - , m_kernelUnitLengthX(this, SVGNames::kernelUnitLengthAttr) - , m_kernelUnitLengthY(this, SVGNames::kernelUnitLengthAttr) + , m_diffuseConstant(1.0f) + , m_surfaceScale(1.0f) { } @@ -71,6 +68,31 @@ void SVGFEDiffuseLightingElement::parseMappedAttribute(MappedAttribute *attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEDiffuseLightingElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeIn1(); + synchronizeSurfaceScale(); + synchronizeDiffuseConstant(); + synchronizeKernelUnitLengthX(); + synchronizeKernelUnitLengthY(); + return; + } + + if (attrName == SVGNames::inAttr) + synchronizeIn1(); + else if (attrName == SVGNames::surfaceScaleAttr) + synchronizeSurfaceScale(); + else if (attrName == SVGNames::diffuseConstantAttr) + synchronizeDiffuseConstant(); + else if (attrName == SVGNames::kernelUnitLengthAttr) { + synchronizeKernelUnitLengthX(); + synchronizeKernelUnitLengthY(); + } +} + bool SVGFEDiffuseLightingElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEDiffuseLightingElement.h b/WebCore/svg/SVGFEDiffuseLightingElement.h index ed117a4..2e1b8cf 100644 --- a/WebCore/svg/SVGFEDiffuseLightingElement.h +++ b/WebCore/svg/SVGFEDiffuseLightingElement.h @@ -40,14 +40,15 @@ namespace WebCore { virtual ~SVGFEDiffuseLightingElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGNames::diffuseConstantAttrString, float, DiffuseConstant, diffuseConstant) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGNames::surfaceScaleAttrString, float, SurfaceScale, surfaceScale) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGKernelUnitLengthXIdentifier, float, KernelUnitLengthX, kernelUnitLengthX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGKernelUnitLengthYIdentifier, float, KernelUnitLengthY, kernelUnitLengthY) + DECLARE_ANIMATED_PROPERTY(SVGFEDiffuseLightingElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEDiffuseLightingElement, SVGNames::diffuseConstantAttr, float, DiffuseConstant, diffuseConstant) + DECLARE_ANIMATED_PROPERTY(SVGFEDiffuseLightingElement, SVGNames::surfaceScaleAttr, float, SurfaceScale, surfaceScale) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, SVGKernelUnitLengthXIdentifier, float, KernelUnitLengthX, kernelUnitLengthX) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, SVGKernelUnitLengthYIdentifier, float, KernelUnitLengthY, kernelUnitLengthY) PassRefPtr<LightSource> findLights() const; }; diff --git a/WebCore/svg/SVGFEDisplacementMapElement.cpp b/WebCore/svg/SVGFEDisplacementMapElement.cpp index adf02fe..b4fcb92 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.cpp +++ b/WebCore/svg/SVGFEDisplacementMapElement.cpp @@ -29,11 +29,8 @@ namespace WebCore { SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_in2(this, SVGNames::in2Attr) - , m_xChannelSelector(this, SVGNames::xChannelSelectorAttr, CHANNEL_A) - , m_yChannelSelector(this, SVGNames::yChannelSelectorAttr, CHANNEL_A) - , m_scale(this, SVGNames::scaleAttr) + , m_xChannelSelector(CHANNEL_A) + , m_yChannelSelector(CHANNEL_A) { } @@ -72,6 +69,31 @@ void SVGFEDisplacementMapElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEDisplacementMapElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeXChannelSelector(); + synchronizeYChannelSelector(); + synchronizeIn1(); + synchronizeIn2(); + synchronizeScale(); + return; + } + + if (attrName == SVGNames::xChannelSelectorAttr) + synchronizeXChannelSelector(); + else if (attrName == SVGNames::yChannelSelectorAttr) + synchronizeYChannelSelector(); + else if (attrName == SVGNames::inAttr) + synchronizeIn1(); + else if (attrName == SVGNames::in2Attr) + synchronizeIn2(); + else if (attrName == SVGNames::scaleAttr) + synchronizeScale(); +} + bool SVGFEDisplacementMapElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEDisplacementMapElement.h b/WebCore/svg/SVGFEDisplacementMapElement.h index 48e6930..95c6672 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.h +++ b/WebCore/svg/SVGFEDisplacementMapElement.h @@ -34,14 +34,15 @@ namespace WebCore { static ChannelSelectorType stringToChannel(const String&); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::in2AttrString, String, In2, in2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::xChannelSelectorAttrString, int, XChannelSelector, xChannelSelector) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::yChannelSelectorAttrString, int, YChannelSelector, yChannelSelector) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::scaleAttrString, float, Scale, scale) + DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::in2Attr, String, In2, in2) + DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::xChannelSelectorAttr, int, XChannelSelector, xChannelSelector) + DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::yChannelSelectorAttr, int, YChannelSelector, yChannelSelector) + DECLARE_ANIMATED_PROPERTY(SVGFEDisplacementMapElement, SVGNames::scaleAttr, float, Scale, scale) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEDisplacementMapElement.idl b/WebCore/svg/SVGFEDisplacementMapElement.idl index 4fde219..b003e8f 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.idl +++ b/WebCore/svg/SVGFEDisplacementMapElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFEDisplacementMapElement : SVGElement, + interface [Conditional=SVG&FILTERS] SVGFEDisplacementMapElement : SVGElement, SVGFilterPrimitiveStandardAttributes { // Channel Selectors const unsigned short SVG_CHANNEL_UNKNOWN = 0; diff --git a/WebCore/svg/SVGFEFloodElement.idl b/WebCore/svg/SVGFEFloodElement.idl index b3c3180..59b9751 100644 --- a/WebCore/svg/SVGFEFloodElement.idl +++ b/WebCore/svg/SVGFEFloodElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFEFloodElement : SVGElement, + interface [Conditional=SVG&FILTERS] SVGFEFloodElement : SVGElement, SVGFilterPrimitiveStandardAttributes { }; } diff --git a/WebCore/svg/SVGFEGaussianBlurElement.cpp b/WebCore/svg/SVGFEGaussianBlurElement.cpp index b2970b3..fd49fe7 100644 --- a/WebCore/svg/SVGFEGaussianBlurElement.cpp +++ b/WebCore/svg/SVGFEGaussianBlurElement.cpp @@ -35,9 +35,6 @@ char SVGStdDeviationYAttrIdentifier[] = "SVGStdDeviationYAttr"; SVGFEGaussianBlurElement::SVGFEGaussianBlurElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_stdDeviationX(this, SVGNames::stdDeviationAttr) - , m_stdDeviationY(this, SVGNames::stdDeviationAttr) { } @@ -65,6 +62,24 @@ void SVGFEGaussianBlurElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEGaussianBlurElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeStdDeviationX(); + synchronizeStdDeviationY(); + synchronizeIn1(); + return; + } + + if (attrName == SVGNames::stdDeviationAttr) { + synchronizeStdDeviationX(); + synchronizeStdDeviationY(); + } else if (attrName == SVGNames::inAttr) + synchronizeIn1(); +} + bool SVGFEGaussianBlurElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEGaussianBlurElement.h b/WebCore/svg/SVGFEGaussianBlurElement.h index 9a5c058..a03b9df 100644 --- a/WebCore/svg/SVGFEGaussianBlurElement.h +++ b/WebCore/svg/SVGFEGaussianBlurElement.h @@ -38,12 +38,13 @@ namespace WebCore { void setStdDeviation(float stdDeviationX, float stdDeviationY); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, SVGNames::feGaussianBlurTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, SVGNames::feGaussianBlurTagString, SVGStdDeviationXAttrIdentifier, float, StdDeviationX, stdDeviationX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, SVGNames::feGaussianBlurTagString, SVGStdDeviationYAttrIdentifier, float, StdDeviationY, stdDeviationY) + DECLARE_ANIMATED_PROPERTY(SVGFEGaussianBlurElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, SVGStdDeviationXAttrIdentifier, float, StdDeviationX, stdDeviationX) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, SVGStdDeviationYAttrIdentifier, float, StdDeviationY, stdDeviationY) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEImageElement.cpp b/WebCore/svg/SVGFEImageElement.cpp index 52531ee..7be972c 100644 --- a/WebCore/svg/SVGFEImageElement.cpp +++ b/WebCore/svg/SVGFEImageElement.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> + 2010 Dirk Schulze <krit@webkit.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -31,6 +32,7 @@ #include "SVGLength.h" #include "SVGNames.h" #include "SVGPreserveAspectRatio.h" +#include "SVGRenderSupport.h" #include "SVGResourceFilter.h" namespace WebCore { @@ -40,9 +42,6 @@ SVGFEImageElement::SVGFEImageElement(const QualifiedName& tagName, Document* doc , SVGURIReference() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -52,23 +51,31 @@ SVGFEImageElement::~SVGFEImageElement() m_cachedImage->removeClient(this); } +void SVGFEImageElement::requestImageResource() +{ + if (m_cachedImage) { + m_cachedImage->removeClient(this); + m_cachedImage = 0; + } + + Element* hrefElement = document()->getElementById(SVGURIReference::getTarget(href())); + if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer()) + return; + + m_cachedImage = ownerDocument()->docLoader()->requestImage(href()); + + if (m_cachedImage) + m_cachedImage->addClient(this); +} + void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); - if (attr->name() == SVGNames::preserveAspectRatioAttr) { - const UChar* c = value.characters(); - const UChar* end = c + value.length(); - preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end); - } else { + if (attr->name() == SVGNames::preserveAspectRatioAttr) + SVGPreserveAspectRatio::parsePreserveAspectRatio(this, value); + else { if (SVGURIReference::parseMappedAttribute(attr)) { - if (!href().startsWith("#")) { - // FIXME: this code needs to special-case url fragments and later look them up using getElementById instead of loading them here - if (m_cachedImage) - m_cachedImage->removeClient(this); - m_cachedImage = ownerDocument()->docLoader()->requestImage(href()); - if (m_cachedImage) - m_cachedImage->addClient(this); - } + requestImageResource(); return; } if (SVGLangSpace::parseMappedAttribute(attr)) @@ -80,16 +87,48 @@ void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr) } } +void SVGFEImageElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizePreserveAspectRatio(); + synchronizeHref(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::preserveAspectRatioAttr) + synchronizePreserveAspectRatio(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + void SVGFEImageElement::notifyFinished(CachedResource*) { + SVGStyledElement::invalidateResourcesInAncestorChain(); } bool SVGFEImageElement::build(SVGResourceFilter* filterResource) { - if (!m_cachedImage) - return false; + if (!m_cachedImage && !m_targetImage) { + Element* hrefElement = document()->getElementById(SVGURIReference::getTarget(href())); + if (!hrefElement || !hrefElement->isSVGElement()) + return false; + + RenderObject* renderer = hrefElement->renderer(); + if (!renderer) + return false; + + IntRect targetRect = enclosingIntRect(renderer->objectBoundingBox()); + m_targetImage = ImageBuffer::create(targetRect.size(), LinearRGB); + + renderSubtreeToImage(m_targetImage.get(), renderer); + } - RefPtr<FilterEffect> effect = FEImage::create(m_cachedImage.get()); + RefPtr<FilterEffect> effect = FEImage::create(m_targetImage ? m_targetImage->image() : m_cachedImage->image(), preserveAspectRatio()); filterResource->addFilterEffect(this, effect.release()); return true; diff --git a/WebCore/svg/SVGFEImageElement.h b/WebCore/svg/SVGFEImageElement.h index 7c6d89b..72cd949 100644 --- a/WebCore/svg/SVGFEImageElement.h +++ b/WebCore/svg/SVGFEImageElement.h @@ -23,12 +23,13 @@ #if ENABLE(SVG) && ENABLE(FILTERS) #include "CachedResourceHandle.h" -#include "SVGFilterPrimitiveStandardAttributes.h" -#include "SVGURIReference.h" -#include "SVGLangSpace.h" +#include "ImageBuffer.h" #include "SVGExternalResourcesRequired.h" #include "SVGFEImage.h" +#include "SVGFilterPrimitiveStandardAttributes.h" +#include "SVGLangSpace.h" #include "SVGPreserveAspectRatio.h" +#include "SVGURIReference.h" namespace WebCore { @@ -42,23 +43,25 @@ namespace WebCore { virtual ~SVGFEImageElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual void notifyFinished(CachedResource*); virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const; virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEImageElement, SVGNames::feImageTagString, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + void requestImageResource(); + + DECLARE_ANIMATED_PROPERTY(SVGFEImageElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGFEImageElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGFEImageElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGFEImageElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGFEImageElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) CachedResourceHandle<CachedImage> m_cachedImage; + OwnPtr<ImageBuffer> m_targetImage; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEImageElement.idl b/WebCore/svg/SVGFEImageElement.idl index 23b9c86..0ebe53e 100644 --- a/WebCore/svg/SVGFEImageElement.idl +++ b/WebCore/svg/SVGFEImageElement.idl @@ -26,10 +26,11 @@ module svg { interface [Conditional=SVG&FILTERS] SVGFEImageElement : SVGElement, - SVGURIReference, - SVGLangSpace, - SVGExternalResourcesRequired, - SVGFilterPrimitiveStandardAttributes { + SVGURIReference, + SVGLangSpace, + SVGExternalResourcesRequired, + SVGFilterPrimitiveStandardAttributes { + readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; }; } diff --git a/WebCore/svg/SVGFELightElement.cpp b/WebCore/svg/SVGFELightElement.cpp index bb954eb..dc711cf 100644 --- a/WebCore/svg/SVGFELightElement.cpp +++ b/WebCore/svg/SVGFELightElement.cpp @@ -29,20 +29,9 @@ namespace WebCore { -char SVGFELightElementIdentifier[] = "SVGFELightElement"; - SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) - , m_azimuth(this, SVGNames::azimuthAttr) - , m_elevation(this, SVGNames::elevationAttr) - , m_x(this, SVGNames::xAttr) - , m_y(this, SVGNames::yAttr) - , m_z(this, SVGNames::zAttr) - , m_pointsAtX(this, SVGNames::pointsAtXAttr) - , m_pointsAtY(this, SVGNames::pointsAtYAttr) - , m_pointsAtZ(this, SVGNames::pointsAtZAttr) - , m_specularExponent(this, SVGNames::specularExponentAttr, 1.0f) - , m_limitingConeAngle(this, SVGNames::limitingConeAngleAttr) + , m_specularExponent(1.0f) { } @@ -77,8 +66,46 @@ void SVGFELightElement::parseMappedAttribute(MappedAttribute* attr) SVGElement::parseMappedAttribute(attr); } +void SVGFELightElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeAzimuth(); + synchronizeElevation(); + synchronizeX(); + synchronizeY(); + synchronizeZ(); + synchronizePointsAtX(); + synchronizePointsAtY(); + synchronizePointsAtZ(); + synchronizeSpecularExponent(); + synchronizeLimitingConeAngle(); + return; + } + + if (attrName == SVGNames::azimuthAttr) + synchronizeAzimuth(); + else if (attrName == SVGNames::elevationAttr) + synchronizeElevation(); + else if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::zAttr) + synchronizeZ(); + else if (attrName == SVGNames::pointsAtXAttr) + synchronizePointsAtX(); + else if (attrName == SVGNames::pointsAtYAttr) + synchronizePointsAtY(); + else if (attrName == SVGNames::pointsAtZAttr) + synchronizePointsAtZ(); + else if (attrName == SVGNames::specularExponentAttr) + synchronizeSpecularExponent(); + else if (attrName == SVGNames::limitingConeAngleAttr) + synchronizeLimitingConeAngle(); } -#endif // ENABLE(SVG) +} -// vim:ts=4:noet +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGFELightElement.h b/WebCore/svg/SVGFELightElement.h index 705eeaa..4e9c389 100644 --- a/WebCore/svg/SVGFELightElement.h +++ b/WebCore/svg/SVGFELightElement.h @@ -29,8 +29,6 @@ namespace WebCore { - extern char SVGFELightElementIdentifier[]; - class SVGFELightElement : public SVGElement { public: SVGFELightElement(const QualifiedName&, Document*); @@ -38,18 +36,19 @@ namespace WebCore { virtual PassRefPtr<LightSource> lightSource() const = 0; virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::azimuthAttrString, float, Azimuth, azimuth) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::elevationAttrString, float, Elevation, elevation) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::xAttrString, float, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::yAttrString, float, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::zAttrString, float, Z, z) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::pointsAtXAttrString, float, PointsAtX, pointsAtX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::pointsAtYAttrString, float, PointsAtY, pointsAtY) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::pointsAtZAttrString, float, PointsAtZ, pointsAtZ) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::specularExponentAttrString, float, SpecularExponent, specularExponent) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::limitingConeAngleAttrString, float, LimitingConeAngle, limitingConeAngle) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::azimuthAttr, float, Azimuth, azimuth) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::elevationAttr, float, Elevation, elevation) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::xAttr, float, X, x) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::yAttr, float, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::zAttr, float, Z, z) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::pointsAtXAttr, float, PointsAtX, pointsAtX) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::pointsAtYAttr, float, PointsAtY, pointsAtY) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::pointsAtZAttr, float, PointsAtZ, pointsAtZ) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::specularExponentAttr, float, SpecularExponent, specularExponent) + DECLARE_ANIMATED_PROPERTY(SVGFELightElement, SVGNames::limitingConeAngleAttr, float, LimitingConeAngle, limitingConeAngle) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEMergeElement.cpp b/WebCore/svg/SVGFEMergeElement.cpp index 6c703ca..078de22 100644 --- a/WebCore/svg/SVGFEMergeElement.cpp +++ b/WebCore/svg/SVGFEMergeElement.cpp @@ -39,7 +39,7 @@ SVGFEMergeElement::~SVGFEMergeElement() bool SVGFEMergeElement::build(SVGResourceFilter* filterResource) { - Vector<FilterEffect*> mergeInputs; + Vector<RefPtr<FilterEffect> > mergeInputs; for (Node* n = firstChild(); n != 0; n = n->nextSibling()) { if (n->hasTagName(SVGNames::feMergeNodeTag)) { FilterEffect* mergeEffect = filterResource->builder()->getEffectById(static_cast<SVGFEMergeNodeElement*>(n)->in1()); diff --git a/WebCore/svg/SVGFEMergeNodeElement.cpp b/WebCore/svg/SVGFEMergeNodeElement.cpp index 4161de8..9551d29 100644 --- a/WebCore/svg/SVGFEMergeNodeElement.cpp +++ b/WebCore/svg/SVGFEMergeNodeElement.cpp @@ -29,7 +29,6 @@ namespace WebCore { SVGFEMergeNodeElement::SVGFEMergeNodeElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) - , m_in1(this, SVGNames::inAttr) { } @@ -46,6 +45,14 @@ void SVGFEMergeNodeElement::parseMappedAttribute(MappedAttribute* attr) SVGElement::parseMappedAttribute(attr); } +void SVGFEMergeNodeElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || attrName == SVGNames::inAttr) + synchronizeIn1(); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGFEMergeNodeElement.h b/WebCore/svg/SVGFEMergeNodeElement.h index cdec8d2..5ccfe94 100644 --- a/WebCore/svg/SVGFEMergeNodeElement.h +++ b/WebCore/svg/SVGFEMergeNodeElement.h @@ -33,9 +33,10 @@ namespace WebCore { virtual ~SVGFEMergeNodeElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEMergeNodeElement, SVGNames::feMergeNodeTagString, SVGNames::inAttrString, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEMergeNodeElement, SVGNames::inAttr, String, In1, in1) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEMorphologyElement.cpp b/WebCore/svg/SVGFEMorphologyElement.cpp index 4a06188..1f37c08 100644 --- a/WebCore/svg/SVGFEMorphologyElement.cpp +++ b/WebCore/svg/SVGFEMorphologyElement.cpp @@ -34,10 +34,7 @@ char SVGRadiusYAttrIdentifier[] = "SVGRadiusYAttr"; SVGFEMorphologyElement::SVGFEMorphologyElement(const QualifiedName& tagName, Document* document) : SVGFilterPrimitiveStandardAttributes(tagName, document) - , m_in1(this, SVGNames::inAttr) - , m__operator(this, SVGNames::operatorAttr, FEMORPHOLOGY_OPERATOR_ERODE) - , m_radiusX(this, SVGNames::radiusAttr) - , m_radiusY(this, SVGNames::radiusAttr) + , m__operator(FEMORPHOLOGY_OPERATOR_ERODE) { } @@ -70,6 +67,28 @@ void SVGFEMorphologyElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEMorphologyElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronize_operator(); + synchronizeIn1(); + synchronizeRadiusX(); + synchronizeRadiusY(); + return; + } + + if (attrName == SVGNames::operatorAttr) + synchronize_operator(); + else if (attrName == SVGNames::inAttr) + synchronizeIn1(); + else if (attrName == SVGNames::radiusAttr) { + synchronizeRadiusX(); + synchronizeRadiusY(); + } +} + bool SVGFEMorphologyElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEMorphologyElement.h b/WebCore/svg/SVGFEMorphologyElement.h index 6c1aec1..c7e3f6f 100644 --- a/WebCore/svg/SVGFEMorphologyElement.h +++ b/WebCore/svg/SVGFEMorphologyElement.h @@ -37,13 +37,14 @@ namespace WebCore { void setRadius(float radiusX, float radiusY); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEMorphologyElement, SVGNames::feMorphologyTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEMorphologyElement, SVGNames::feMorphologyTagString, SVGNames::operatorAttrString, int, _operator, _operator) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEMorphologyElement, SVGNames::feMorphologyTagString, SVGRadiusXAttrIdentifier, float, RadiusX, radiusX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEMorphologyElement, SVGNames::feMorphologyTagString, SVGRadiusYAttrIdentifier, float, RadiusY, radiusY) + DECLARE_ANIMATED_PROPERTY(SVGFEMorphologyElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEMorphologyElement, SVGNames::operatorAttr, int, _operator, _operator) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, SVGRadiusXAttrIdentifier, float, RadiusX, radiusX) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, SVGRadiusYAttrIdentifier, float, RadiusY, radiusY) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEMorphologyElement.idl b/WebCore/svg/SVGFEMorphologyElement.idl index cce0e36..ffd2289 100644 --- a/WebCore/svg/SVGFEMorphologyElement.idl +++ b/WebCore/svg/SVGFEMorphologyElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFEMorphologyElement : SVGElement, + interface [Conditional=SVG&FILTERS] SVGFEMorphologyElement : SVGElement, SVGFilterPrimitiveStandardAttributes { // Morphology Operators const unsigned short SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0; diff --git a/WebCore/svg/SVGFEOffsetElement.cpp b/WebCore/svg/SVGFEOffsetElement.cpp index 95cbc8d..28955c0 100644 --- a/WebCore/svg/SVGFEOffsetElement.cpp +++ b/WebCore/svg/SVGFEOffsetElement.cpp @@ -31,9 +31,6 @@ namespace WebCore { SVGFEOffsetElement::SVGFEOffsetElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_dx(this, SVGNames::dxAttr) - , m_dy(this, SVGNames::dyAttr) { } @@ -54,6 +51,25 @@ void SVGFEOffsetElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFEOffsetElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeDx(); + synchronizeDy(); + synchronizeIn1(); + return; + } + + if (attrName == SVGNames::dxAttr) + synchronizeDx(); + else if (attrName == SVGNames::dyAttr) + synchronizeDy(); + else if (attrName == SVGNames::inAttr) + synchronizeIn1(); +} + bool SVGFEOffsetElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFEOffsetElement.h b/WebCore/svg/SVGFEOffsetElement.h index ae07ed8..df61a9c 100644 --- a/WebCore/svg/SVGFEOffsetElement.h +++ b/WebCore/svg/SVGFEOffsetElement.h @@ -33,12 +33,13 @@ namespace WebCore { virtual ~SVGFEOffsetElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, SVGNames::feOffsetTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, SVGNames::feOffsetTagString, SVGNames::dxAttrString, float, Dx, dx) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, SVGNames::feOffsetTagString, SVGNames::dyAttrString, float, Dy, dy) + DECLARE_ANIMATED_PROPERTY(SVGFEOffsetElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFEOffsetElement, SVGNames::dxAttr, float, Dx, dx) + DECLARE_ANIMATED_PROPERTY(SVGFEOffsetElement, SVGNames::dyAttr, float, Dy, dy) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFESpecularLightingElement.cpp b/WebCore/svg/SVGFESpecularLightingElement.cpp index 90e9cb3..0602103 100644 --- a/WebCore/svg/SVGFESpecularLightingElement.cpp +++ b/WebCore/svg/SVGFESpecularLightingElement.cpp @@ -36,12 +36,9 @@ namespace WebCore { SVGFESpecularLightingElement::SVGFESpecularLightingElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) - , m_specularConstant(this, SVGNames::specularConstantAttr, 1.0f) - , m_specularExponent(this, SVGNames::specularExponentAttr, 1.0f) - , m_surfaceScale(this, SVGNames::surfaceScaleAttr, 1.0f) - , m_kernelUnitLengthX(this, SVGNames::kernelUnitLengthAttr) - , m_kernelUnitLengthY(this, SVGNames::kernelUnitLengthAttr) + , m_specularConstant(1.0f) + , m_specularExponent(1.0f) + , m_surfaceScale(1.0f) { } @@ -70,6 +67,34 @@ void SVGFESpecularLightingElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFESpecularLightingElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeIn1(); + synchronizeSurfaceScale(); + synchronizeSpecularConstant(); + synchronizeSpecularExponent(); + synchronizeKernelUnitLengthX(); + synchronizeKernelUnitLengthY(); + return; + } + + if (attrName == SVGNames::inAttr) + synchronizeIn1(); + else if (attrName == SVGNames::surfaceScaleAttr) + synchronizeSurfaceScale(); + else if (attrName == SVGNames::specularConstantAttr) + synchronizeSpecularConstant(); + else if (attrName == SVGNames::specularExponentAttr) + synchronizeSpecularExponent(); + else if (attrName == SVGNames::kernelUnitLengthAttr) { + synchronizeKernelUnitLengthX(); + synchronizeKernelUnitLengthY(); + } +} + PassRefPtr<LightSource> SVGFESpecularLightingElement::findLights() const { for (Node* n = firstChild(); n; n = n->nextSibling()) { diff --git a/WebCore/svg/SVGFESpecularLightingElement.h b/WebCore/svg/SVGFESpecularLightingElement.h index b3771fe..fe56980 100644 --- a/WebCore/svg/SVGFESpecularLightingElement.h +++ b/WebCore/svg/SVGFESpecularLightingElement.h @@ -31,23 +31,22 @@ namespace WebCore { extern char SVGKernelUnitLengthXIdentifier[]; extern char SVGKernelUnitLengthYIdentifier[]; - class SVGColor; - class SVGFESpecularLightingElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFESpecularLightingElement(const QualifiedName&, Document*); virtual ~SVGFESpecularLightingElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::inAttrString, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::specularConstantAttrString, float, SpecularConstant, specularConstant) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::specularExponentAttrString, float, SpecularExponent, specularExponent) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::surfaceScaleAttrString, float, SurfaceScale, surfaceScale) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGKernelUnitLengthXIdentifier, float, KernelUnitLengthX, kernelUnitLengthX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGKernelUnitLengthYIdentifier, float, KernelUnitLengthY, kernelUnitLengthY) + DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::inAttr, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::specularConstantAttr, float, SpecularConstant, specularConstant) + DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::specularExponentAttr, float, SpecularExponent, specularExponent) + DECLARE_ANIMATED_PROPERTY(SVGFESpecularLightingElement, SVGNames::surfaceScaleAttr, float, SurfaceScale, surfaceScale) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, SVGKernelUnitLengthXIdentifier, float, KernelUnitLengthX, kernelUnitLengthX) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, SVGKernelUnitLengthYIdentifier, float, KernelUnitLengthY, kernelUnitLengthY) PassRefPtr<LightSource> findLights() const; }; diff --git a/WebCore/svg/SVGFETileElement.cpp b/WebCore/svg/SVGFETileElement.cpp index 8894d4b..94c8e74 100644 --- a/WebCore/svg/SVGFETileElement.cpp +++ b/WebCore/svg/SVGFETileElement.cpp @@ -32,7 +32,6 @@ namespace WebCore { SVGFETileElement::SVGFETileElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_in1(this, SVGNames::inAttr) { } @@ -49,6 +48,14 @@ void SVGFETileElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFETileElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName() || attrName == SVGNames::inAttr) + synchronizeIn1(); +} + bool SVGFETileElement::build(SVGResourceFilter* filterResource) { FilterEffect* input1 = filterResource->builder()->getEffectById(in1()); diff --git a/WebCore/svg/SVGFETileElement.h b/WebCore/svg/SVGFETileElement.h index 142a797..2c86abd 100644 --- a/WebCore/svg/SVGFETileElement.h +++ b/WebCore/svg/SVGFETileElement.h @@ -33,10 +33,11 @@ namespace WebCore { virtual ~SVGFETileElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFETileElement, SVGNames::feTileTagString, SVGNames::inAttrString, String, In1, in1) + DECLARE_ANIMATED_PROPERTY(SVGFETileElement, SVGNames::inAttr, String, In1, in1) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFETurbulenceElement.cpp b/WebCore/svg/SVGFETurbulenceElement.cpp index 57114a3..622971c 100644 --- a/WebCore/svg/SVGFETurbulenceElement.cpp +++ b/WebCore/svg/SVGFETurbulenceElement.cpp @@ -34,12 +34,9 @@ char SVGBaseFrequencyYIdentifier[] = "SVGBaseFrequencyY"; SVGFETurbulenceElement::SVGFETurbulenceElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_baseFrequencyX(this, SVGNames::baseFrequencyAttr) - , m_baseFrequencyY(this, SVGNames::baseFrequencyAttr) - , m_numOctaves(this, SVGNames::numOctavesAttr, 1) - , m_seed(this, SVGNames::seedAttr) - , m_stitchTiles(this, SVGNames::stitchTilesAttr, SVG_STITCHTYPE_NOSTITCH) - , m_type(this, SVGNames::typeAttr, FETURBULENCE_TYPE_TURBULENCE) + , m_numOctaves(1) + , m_stitchTiles(SVG_STITCHTYPE_NOSTITCH) + , m_type(FETURBULENCE_TYPE_TURBULENCE) { } @@ -74,6 +71,33 @@ void SVGFETurbulenceElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } +void SVGFETurbulenceElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeType(); + synchronizeStitchTiles(); + synchronizeBaseFrequencyX(); + synchronizeBaseFrequencyY(); + synchronizeSeed(); + synchronizeNumOctaves(); + return; + } + + if (attrName == SVGNames::typeAttr) + synchronizeType(); + else if (attrName == SVGNames::stitchTilesAttr) + synchronizeStitchTiles(); + else if (attrName == SVGNames::baseFrequencyAttr) { + synchronizeBaseFrequencyX(); + synchronizeBaseFrequencyY(); + } else if (attrName == SVGNames::seedAttr) + synchronizeSeed(); + else if (attrName == SVGNames::numOctavesAttr) + synchronizeNumOctaves(); +} + bool SVGFETurbulenceElement::build(SVGResourceFilter* filterResource) { RefPtr<FilterEffect> effect = FETurbulence::create(static_cast<TurbulanceType>(type()), baseFrequencyX(), diff --git a/WebCore/svg/SVGFETurbulenceElement.h b/WebCore/svg/SVGFETurbulenceElement.h index f024f57..464ce25 100644 --- a/WebCore/svg/SVGFETurbulenceElement.h +++ b/WebCore/svg/SVGFETurbulenceElement.h @@ -42,15 +42,16 @@ namespace WebCore { virtual ~SVGFETurbulenceElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGBaseFrequencyXIdentifier, float, BaseFrequencyX, baseFrequencyX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGBaseFrequencyYIdentifier, float, BaseFrequencyY, baseFrequencyY) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::numOctavesAttrString, long, NumOctaves, numOctaves) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::seedAttrString, float, Seed, seed) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::stitchTilesAttrString, int, StitchTiles, stitchTiles) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::typeAttrString, int, Type, type) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, SVGBaseFrequencyXIdentifier, float, BaseFrequencyX, baseFrequencyX) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, SVGBaseFrequencyYIdentifier, float, BaseFrequencyY, baseFrequencyY) + DECLARE_ANIMATED_PROPERTY(SVGFETurbulenceElement, SVGNames::numOctavesAttr, long, NumOctaves, numOctaves) + DECLARE_ANIMATED_PROPERTY(SVGFETurbulenceElement, SVGNames::seedAttr, float, Seed, seed) + DECLARE_ANIMATED_PROPERTY(SVGFETurbulenceElement, SVGNames::stitchTilesAttr, int, StitchTiles, stitchTiles) + DECLARE_ANIMATED_PROPERTY(SVGFETurbulenceElement, SVGNames::typeAttr, int, Type, type) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFETurbulenceElement.idl b/WebCore/svg/SVGFETurbulenceElement.idl index 9cec66c..934eddf 100644 --- a/WebCore/svg/SVGFETurbulenceElement.idl +++ b/WebCore/svg/SVGFETurbulenceElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG&FILTERS, GenerateConstructor] SVGFETurbulenceElement : SVGElement, + interface [Conditional=SVG&FILTERS] SVGFETurbulenceElement : SVGElement, SVGFilterPrimitiveStandardAttributes { // Turbulence Types const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0; diff --git a/WebCore/svg/SVGFilterElement.cpp b/WebCore/svg/SVGFilterElement.cpp index bb14448..60375fb 100644 --- a/WebCore/svg/SVGFilterElement.cpp +++ b/WebCore/svg/SVGFilterElement.cpp @@ -47,16 +47,12 @@ SVGFilterElement::SVGFilterElement(const QualifiedName& tagName, Document* doc) , SVGURIReference() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_filterUnits(this, SVGNames::filterUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_primitiveUnits(this, SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_x(this, SVGNames::xAttr, LengthModeWidth, "-10%") - , m_y(this, SVGNames::yAttr, LengthModeHeight, "-10%") - , m_width(this, SVGNames::widthAttr, LengthModeWidth, "120%") - , m_height(this, SVGNames::heightAttr, LengthModeHeight, "120%") - , m_filterResX(this, SVGNames::filterResAttr) - , m_filterResY(this, SVGNames::filterResAttr) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_filterUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_primitiveUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + , m_x(LengthModeWidth, "-10%") + , m_y(LengthModeHeight, "-10%") + , m_width(LengthModeWidth, "120%") + , m_height(LengthModeHeight, "120%") { // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. @@ -109,6 +105,62 @@ void SVGFilterElement::parseMappedAttribute(MappedAttribute* attr) } } +void SVGFilterElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizeFilterUnits(); + synchronizePrimitiveUnits(); + synchronizeFilterResX(); + synchronizeFilterResY(); + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (attrName == SVGNames::filterUnitsAttr) + synchronizeFilterUnits(); + else if (attrName == SVGNames::primitiveUnitsAttr) + synchronizePrimitiveUnits(); + else if (attrName == SVGNames::filterResAttr) { + synchronizeFilterResX(); + synchronizeFilterResY(); + } else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + +FloatRect SVGFilterElement::filterBoundingBox(const FloatRect& objectBoundingBox) const +{ + FloatRect filterBBox; + if (filterUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + filterBBox = FloatRect(x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(), + y().valueAsPercentage() * objectBoundingBox.height() + objectBoundingBox.y(), + width().valueAsPercentage() * objectBoundingBox.width(), + height().valueAsPercentage() * objectBoundingBox.height()); + else + filterBBox = FloatRect(x().value(this), + y().value(this), + width().value(this), + height().value(this)); + + return filterBBox; +} + void SVGFilterElement::buildFilter(const FloatRect& targetRect) const { bool filterBBoxMode = filterUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; @@ -160,7 +212,7 @@ void SVGFilterElement::buildFilter(const FloatRect& targetRect) const } } -SVGResource* SVGFilterElement::canvasResource() +SVGResource* SVGFilterElement::canvasResource(const RenderObject*) { if (!attached()) return 0; diff --git a/WebCore/svg/SVGFilterElement.h b/WebCore/svg/SVGFilterElement.h index 836c689..c89352b 100644 --- a/WebCore/svg/SVGFilterElement.h +++ b/WebCore/svg/SVGFilterElement.h @@ -23,6 +23,7 @@ #define SVGFilterElement_h #if ENABLE(SVG) && ENABLE(FILTERS) +#include "RenderObject.h" #include "SVGResourceFilter.h" #include "SVGExternalResourcesRequired.h" #include "SVGLangSpace.h" @@ -34,6 +35,8 @@ namespace WebCore { extern char SVGFilterResXIdentifier[]; extern char SVGFilterResYIdentifier[]; + class SVGResourceFilter; + class SVGFilterElement : public SVGStyledElement, public SVGURIReference, public SVGLangSpace, @@ -42,35 +45,35 @@ namespace WebCore { SVGFilterElement(const QualifiedName&, Document*); virtual ~SVGFilterElement(); - virtual SVGResource* canvasResource(); + virtual SVGResource* canvasResource(const RenderObject*); void setFilterRes(unsigned long filterResX, unsigned long filterResY) const; virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool rendererIsNeeded(RenderStyle*) { return false; } private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::filterUnitsAttrString, int, FilterUnits, filterUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::primitiveUnitsAttrString, int, PrimitiveUnits, primitiveUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::heightAttrString, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGFilterResXIdentifier, long, FilterResX, filterResX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGFilterResYIdentifier, long, FilterResY, filterResY) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::filterUnitsAttr, int, FilterUnits, filterUnits) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::primitiveUnitsAttr, int, PrimitiveUnits, primitiveUnits) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::heightAttr, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFilterElement, SVGNames::filterResAttr, SVGFilterResXIdentifier, long, FilterResX, filterResX) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGFilterElement, SVGNames::filterResAttr, SVGFilterResYIdentifier, long, FilterResY, filterResY) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGFilterElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) mutable RefPtr<SVGResourceFilter> m_filter; private: friend class SVGResourceFilter; + FloatRect filterBoundingBox(const FloatRect&) const; void buildFilter(const FloatRect& targetRect) const; }; diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp index 08559b4..0a95522 100644 --- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp +++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp @@ -33,15 +33,12 @@ namespace WebCore { -char SVGFilterPrimitiveStandardAttributesIdentifierIdentifier[] = "SVGFilterPrimitiveStandardAttributesIdentifier"; - SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) - , m_x(this, SVGNames::xAttr, LengthModeWidth, "0%") - , m_y(this, SVGNames::yAttr, LengthModeHeight, "0%") - , m_width(this, SVGNames::widthAttr, LengthModeWidth, "100%") - , m_height(this, SVGNames::heightAttr, LengthModeHeight, "100%") - , m_result(this, SVGNames::resultAttr) + , m_x(LengthModeWidth, "0%") + , m_y(LengthModeHeight, "0%") + , m_width(LengthModeWidth, "100%") + , m_height(LengthModeHeight, "100%") { // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified. // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified. @@ -68,6 +65,31 @@ void SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(MappedAttribute* return SVGStyledElement::parseMappedAttribute(attr); } +void SVGFilterPrimitiveStandardAttributes::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizeResult(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (attrName == SVGNames::resultAttr) + synchronizeResult(); +} + void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(SVGResourceFilter* resourceFilter, FilterEffect* filterEffect) const { ASSERT(filterEffect); diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h index cb8ec1c..fb8e5f2 100644 --- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h +++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h @@ -29,8 +29,6 @@ namespace WebCore { - extern char SVGFilterPrimitiveStandardAttributesIdentifier[]; - class SVGResourceFilter; class SVGFilterPrimitiveStandardAttributes : public SVGStyledElement { @@ -41,6 +39,7 @@ namespace WebCore { virtual bool isFilterEffect() const { return true; } virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool build(SVGResourceFilter*) = 0; virtual bool rendererIsNeeded(RenderStyle*) { return false; } @@ -50,11 +49,11 @@ namespace WebCore { void setStandardAttributes(SVGResourceFilter*, FilterEffect*) const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::heightAttrString, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::resultAttrString, String, Result, result) + DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::heightAttr, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::resultAttr, String, Result, result) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFitToViewBox.cpp b/WebCore/svg/SVGFitToViewBox.cpp index c566a8f..80dead6 100644 --- a/WebCore/svg/SVGFitToViewBox.cpp +++ b/WebCore/svg/SVGFitToViewBox.cpp @@ -35,8 +35,6 @@ namespace WebCore { -char SVGFitToViewBoxIdentifier[] = "SVGFitToViewBox"; - SVGFitToViewBox::SVGFitToViewBox() { } @@ -77,13 +75,12 @@ bool SVGFitToViewBox::parseViewBox(Document* doc, const UChar*& c, const UChar* return true; } -TransformationMatrix SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBoxRect, SVGPreserveAspectRatio* preserveAspectRatio, float viewWidth, float viewHeight) +TransformationMatrix SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatio& preserveAspectRatio, float viewWidth, float viewHeight) { - ASSERT(preserveAspectRatio); if (!viewBoxRect.width() || !viewBoxRect.height()) return TransformationMatrix(); - return preserveAspectRatio->getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), 0, 0, viewWidth, viewHeight); + return preserveAspectRatio.getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), 0, 0, viewWidth, viewHeight); } bool SVGFitToViewBox::parseMappedAttribute(Document* document, MappedAttribute* attr) @@ -96,9 +93,7 @@ bool SVGFitToViewBox::parseMappedAttribute(Document* document, MappedAttribute* setViewBoxBaseValue(FloatRect(x, y, w, h)); return true; } else if (attr->name() == SVGNames::preserveAspectRatioAttr) { - const UChar* c = attr->value().characters(); - const UChar* end = c + attr->value().length(); - preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end); + SVGPreserveAspectRatio::parsePreserveAspectRatio(this, attr->value()); return true; } diff --git a/WebCore/svg/SVGFitToViewBox.h b/WebCore/svg/SVGFitToViewBox.h index 503a0ef..20fb7c1 100644 --- a/WebCore/svg/SVGFitToViewBox.h +++ b/WebCore/svg/SVGFitToViewBox.h @@ -27,8 +27,6 @@ namespace WebCore { - extern char SVGFitToViewBoxIdentifier[]; - class TransformationMatrix; class SVGFitToViewBox { @@ -37,16 +35,13 @@ namespace WebCore { virtual ~SVGFitToViewBox(); bool parseViewBox(Document*, const UChar*& start, const UChar* end, float& x, float& y, float& w, float& h, bool validate = true); - static TransformationMatrix viewBoxToViewTransform(const FloatRect& viewBoxRect, SVGPreserveAspectRatio*, float viewWidth, float viewHeight); + static TransformationMatrix viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatio&, float viewWidth, float viewHeight); bool parseMappedAttribute(Document*, MappedAttribute*); bool isKnownAttribute(const QualifiedName&); - protected: - virtual SVGAnimatedTypeValue<FloatRect>::DecoratedType viewBoxBaseValue() const = 0; - virtual void setViewBoxBaseValue(SVGAnimatedTypeValue<FloatRect>::DecoratedType type) = 0; - - virtual SVGAnimatedTypeValue<SVGPreserveAspectRatio>::DecoratedType preserveAspectRatioBaseValue() const = 0; + virtual void setViewBoxBaseValue(SVGAnimatedPropertyTraits<FloatRect>::PassType) = 0; + virtual void setPreserveAspectRatioBaseValue(SVGAnimatedPropertyTraits<SVGPreserveAspectRatio>::PassType) = 0; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFitToViewBox.idl b/WebCore/svg/SVGFitToViewBox.idl index a747fc8..d456cf8 100644 --- a/WebCore/svg/SVGFitToViewBox.idl +++ b/WebCore/svg/SVGFitToViewBox.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGFitToViewBox { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGFitToViewBox { readonly attribute SVGAnimatedRect viewBox; readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; }; diff --git a/WebCore/svg/SVGFont.cpp b/WebCore/svg/SVGFont.cpp index 7e3cec0..d978328 100644 --- a/WebCore/svg/SVGFont.cpp +++ b/WebCore/svg/SVGFont.cpp @@ -243,7 +243,8 @@ struct SVGTextRunWalker { // Should hold true for SVG text, otherwhise sth. is wrong ASSERT(to - from == run.length()); - Vector<SVGGlyphIdentifier::ArabicForm> chars(charactersWithArabicForm(String(run.data(from), run.length()), run.rtl())); + const String text = Font::normalizeSpaces(String(run.data(from), run.length())); + Vector<SVGGlyphIdentifier::ArabicForm> chars(charactersWithArabicForm(text, run.rtl())); SVGGlyphIdentifier identifier; bool foundGlyph = false; @@ -270,7 +271,8 @@ struct SVGTextRunWalker { // extended to the n-th next character (where n is 'characterLookupRange'), to check for any possible ligature. characterLookupRange = endOfScanRange - i; - String lookupString(run.data(i), characterLookupRange); + String lookupString = Font::normalizeSpaces(String(run.data(i), characterLookupRange)); + Vector<SVGGlyphIdentifier> glyphs; if (haveAltGlyph) glyphs.append(altGlyphIdentifier); diff --git a/WebCore/svg/SVGFontElement.cpp b/WebCore/svg/SVGFontElement.cpp index 7d62b8c..91d222c 100644 --- a/WebCore/svg/SVGFontElement.cpp +++ b/WebCore/svg/SVGFontElement.cpp @@ -40,7 +40,6 @@ using namespace SVGNames; SVGFontElement::SVGFontElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) , m_isGlyphCacheValid(false) { } @@ -49,6 +48,14 @@ SVGFontElement::~SVGFontElement() { } +void SVGFontElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + void SVGFontElement::invalidateGlyphCache() { if (m_isGlyphCacheValid) { diff --git a/WebCore/svg/SVGFontElement.h b/WebCore/svg/SVGFontElement.h index 1fc5136..90641a8 100644 --- a/WebCore/svg/SVGFontElement.h +++ b/WebCore/svg/SVGFontElement.h @@ -37,6 +37,7 @@ namespace WebCore { SVGFontElement(const QualifiedName&, Document*); virtual ~SVGFontElement(); + virtual void synchronizeProperty(const QualifiedName&); virtual bool rendererIsNeeded(RenderStyle*) { return false; } void invalidateGlyphCache(); @@ -49,9 +50,7 @@ namespace WebCore { private: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGFontElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGFontElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) void ensureGlyphCache() const; diff --git a/WebCore/svg/SVGFontFaceElement.cpp b/WebCore/svg/SVGFontFaceElement.cpp index aa0b6d8..25b3aea 100644 --- a/WebCore/svg/SVGFontFaceElement.cpp +++ b/WebCore/svg/SVGFontFaceElement.cpp @@ -62,13 +62,6 @@ SVGFontFaceElement::~SVGFontFaceElement() removeFromMappedElementSheet(); } -static void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName) -{ - int propertyId = cssPropertyID(attrName.localName()); - ASSERT(propertyId > 0); - propertyNameToIdMap->set(attrName.localName().impl(), propertyId); -} - static int cssPropertyIdForSVGAttributeName(const QualifiedName& attrName) { if (!attrName.namespaceURI().isNull()) @@ -282,7 +275,7 @@ void SVGFontFaceElement::rebuildFontFace() srcElement = static_cast<SVGFontFaceSrcElement*>(child); } - bool describesParentFont = parentNode()->hasTagName(fontTag); + bool describesParentFont = parentNode()->hasTagName(SVGNames::fontTag); RefPtr<CSSValueList> list; if (describesParentFont) { diff --git a/WebCore/svg/SVGFontFaceUriElement.cpp b/WebCore/svg/SVGFontFaceUriElement.cpp index 096f0c2..bfcda70 100644 --- a/WebCore/svg/SVGFontFaceUriElement.cpp +++ b/WebCore/svg/SVGFontFaceUriElement.cpp @@ -91,9 +91,11 @@ void SVGFontFaceUriElement::loadFont() if (!href.isNull()) { DocLoader* docLoader = document()->docLoader(); m_cachedFont = docLoader->requestFont(href); - m_cachedFont->setSVGFont(true); - m_cachedFont->addClient(this); - m_cachedFont->beginLoadIfNeeded(docLoader); + if (m_cachedFont) { + m_cachedFont->setSVGFont(true); + m_cachedFont->addClient(this); + m_cachedFont->beginLoadIfNeeded(docLoader); + } } else m_cachedFont = 0; } diff --git a/WebCore/svg/SVGForeignObjectElement.cpp b/WebCore/svg/SVGForeignObjectElement.cpp index 1e75741..e9118ef 100644 --- a/WebCore/svg/SVGForeignObjectElement.cpp +++ b/WebCore/svg/SVGForeignObjectElement.cpp @@ -39,12 +39,10 @@ SVGForeignObjectElement::SVGForeignObjectElement(const QualifiedName& tagName, D , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_x(this, SVGNames::xAttr, LengthModeWidth) - , m_y(this, SVGNames::yAttr, LengthModeHeight) - , m_width(this, SVGNames::widthAttr, LengthModeWidth) - , m_height(this, SVGNames::heightAttr, LengthModeHeight) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_x(LengthModeWidth) + , m_y(LengthModeHeight) + , m_width(LengthModeWidth) + , m_height(LengthModeHeight) { } @@ -153,6 +151,34 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGForeignObjectElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + RenderObject* SVGForeignObjectElement::createRenderer(RenderArena* arena, RenderStyle*) { return new (arena) RenderForeignObject(this); diff --git a/WebCore/svg/SVGForeignObjectElement.h b/WebCore/svg/SVGForeignObjectElement.h index 1848e2b..fe36a20 100644 --- a/WebCore/svg/SVGForeignObjectElement.h +++ b/WebCore/svg/SVGForeignObjectElement.h @@ -42,23 +42,22 @@ namespace WebCore { virtual bool isValid() const { return SVGTests::isValid(); } virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); bool childShouldCreateRenderer(Node*) const; virtual RenderObject* createRenderer(RenderArena* arena, RenderStyle* style); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::heightAttrString, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY(SVGForeignObjectElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGForeignObjectElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGForeignObjectElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGForeignObjectElement, SVGNames::heightAttr, SVGLength, Height, height) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGForeignObjectElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGForeignObjectElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGGElement.cpp b/WebCore/svg/SVGGElement.cpp index ef46af4..0fd329f 100644 --- a/WebCore/svg/SVGGElement.cpp +++ b/WebCore/svg/SVGGElement.cpp @@ -32,7 +32,6 @@ SVGGElement::SVGGElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -66,6 +65,14 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGGElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + void SVGGElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGStyledTransformableElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); diff --git a/WebCore/svg/SVGGElement.h b/WebCore/svg/SVGGElement.h index 9cfb5a3..3e0dd8e 100644 --- a/WebCore/svg/SVGGElement.h +++ b/WebCore/svg/SVGGElement.h @@ -37,22 +37,19 @@ namespace WebCore { SVGGElement(const QualifiedName&, Document*); virtual ~SVGGElement(); + virtual bool isShadowTreeContainerElement() const { return false; } virtual bool isValid() const { return SVGTests::isValid(); } virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); private: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGGElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) - - friend class SVGUseElement; - TransformationMatrix localMatrix() const; + DECLARE_ANIMATED_PROPERTY(SVGGElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGGlyphElement.cpp b/WebCore/svg/SVGGlyphElement.cpp index 7be0181..2d15569 100644 --- a/WebCore/svg/SVGGlyphElement.cpp +++ b/WebCore/svg/SVGGlyphElement.cpp @@ -49,7 +49,7 @@ SVGGlyphElement::~SVGGlyphElement() void SVGGlyphElement::invalidateGlyphCache() { Node* fontNode = parentNode(); - if (fontNode && fontNode->hasTagName(fontTag)) { + if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) { if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) element->invalidateGlyphCache(); } @@ -167,7 +167,7 @@ SVGGlyphIdentifier SVGGlyphElement::buildGlyphIdentifier() const identifier.orientation = parseOrientation(getAttribute(orientationAttr)); identifier.arabicForm = parseArabicForm(getAttribute(arabic_formAttr)); - String language = getAttribute(langAttr); + String language = getAttribute(SVGNames::langAttr); if (!language.isEmpty()) identifier.languages = parseDelimitedString(language, ','); diff --git a/WebCore/svg/SVGGradientElement.cpp b/WebCore/svg/SVGGradientElement.cpp index b4fe21d..f573265 100644 --- a/WebCore/svg/SVGGradientElement.cpp +++ b/WebCore/svg/SVGGradientElement.cpp @@ -37,17 +37,12 @@ namespace WebCore { -char SVGGradientElementIdentifier[] = "SVGGradientElement"; - SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) , SVGURIReference() , SVGExternalResourcesRequired() - , m_spreadMethod(this, SVGNames::spreadMethodAttr) - , m_gradientUnits(this, SVGNames::gradientUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_gradientTransform(this, SVGNames::gradientTransformAttr, SVGTransformList::create(SVGNames::gradientTransformAttr)) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_gradientTransform(SVGTransformList::create(SVGNames::gradientTransformAttr)) { } @@ -101,6 +96,31 @@ void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName) m_resource->invalidate(); } +void SVGGradientElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeGradientUnits(); + synchronizeGradientTransform(); + synchronizeSpreadMethod(); + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::gradientUnitsAttr) + synchronizeGradientUnits(); + else if (attrName == SVGNames::gradientTransformAttr) + synchronizeGradientTransform(); + else if (attrName == SVGNames::spreadMethodAttr) + synchronizeSpreadMethod(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + void SVGGradientElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); @@ -114,7 +134,7 @@ RenderObject* SVGGradientElement::createRenderer(RenderArena* arena, RenderStyle return new (arena) RenderSVGHiddenContainer(this); } -SVGResource* SVGGradientElement::canvasResource() +SVGResource* SVGGradientElement::canvasResource(const RenderObject*) { if (!m_resource) { if (gradientType() == LinearGradientPaintServer) diff --git a/WebCore/svg/SVGGradientElement.h b/WebCore/svg/SVGGradientElement.h index 8413597..122e1d9 100644 --- a/WebCore/svg/SVGGradientElement.h +++ b/WebCore/svg/SVGGradientElement.h @@ -22,6 +22,7 @@ #define SVGGradientElement_h #if ENABLE(SVG) +#include "RenderObject.h" #include "SVGPaintServerGradient.h" #include "SVGExternalResourcesRequired.h" #include "SVGStyledElement.h" @@ -30,8 +31,6 @@ namespace WebCore { - extern char SVGGradientElementIdentifier[]; - class SVGGradientElement : public SVGStyledElement, public SVGURIReference, public SVGExternalResourcesRequired { @@ -41,11 +40,12 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual SVGResource* canvasResource(); + virtual SVGResource* canvasResource(const RenderObject*); protected: friend class SVGPaintServerGradient; @@ -59,17 +59,15 @@ namespace WebCore { mutable RefPtr<SVGPaintServerGradient> m_resource; protected: - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGGradientElementIdentifier, SVGNames::spreadMethodAttrString, int, SpreadMethod, spreadMethod) - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGGradientElementIdentifier, SVGNames::gradientUnitsAttrString, int, GradientUnits, gradientUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGGradientElementIdentifier, SVGNames::gradientTransformAttrString, SVGTransformList, GradientTransform, gradientTransform) + DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::spreadMethodAttr, int, SpreadMethod, spreadMethod) + DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::gradientUnitsAttr, int, GradientUnits, gradientUnits) + DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::gradientTransformAttr, SVGTransformList*, GradientTransform, gradientTransform) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGGradientElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGGradientElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGGradientElement.idl b/WebCore/svg/SVGGradientElement.idl index 8b09d82..7485780 100644 --- a/WebCore/svg/SVGGradientElement.idl +++ b/WebCore/svg/SVGGradientElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGGradientElement : SVGElement, + interface [Conditional=SVG] SVGGradientElement : SVGElement, SVGURIReference, SVGExternalResourcesRequired, SVGStylable diff --git a/WebCore/svg/SVGHKernElement.cpp b/WebCore/svg/SVGHKernElement.cpp index f232fdc..0ee3e76 100644 --- a/WebCore/svg/SVGHKernElement.cpp +++ b/WebCore/svg/SVGHKernElement.cpp @@ -48,7 +48,7 @@ SVGHKernElement::~SVGHKernElement() void SVGHKernElement::insertedIntoDocument() { Node* fontNode = parentNode(); - if (fontNode && fontNode->hasTagName(fontTag)) { + if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) { if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) element->invalidateGlyphCache(); } @@ -57,7 +57,7 @@ void SVGHKernElement::insertedIntoDocument() void SVGHKernElement::removedFromDocument() { Node* fontNode = parentNode(); - if (fontNode && fontNode->hasTagName(fontTag)) { + if (fontNode && fontNode->hasTagName(SVGNames::fontTag)) { if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) element->invalidateGlyphCache(); } diff --git a/WebCore/svg/SVGImageElement.cpp b/WebCore/svg/SVGImageElement.cpp index e29846c..4055533 100644 --- a/WebCore/svg/SVGImageElement.cpp +++ b/WebCore/svg/SVGImageElement.cpp @@ -41,13 +41,10 @@ SVGImageElement::SVGImageElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGURIReference() - , m_x(this, SVGNames::xAttr, LengthModeWidth) - , m_y(this, SVGNames::yAttr, LengthModeHeight) - , m_width(this, SVGNames::widthAttr, LengthModeWidth) - , m_height(this, SVGNames::heightAttr, LengthModeHeight) - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_x(LengthModeWidth) + , m_y(LengthModeHeight) + , m_width(LengthModeWidth) + , m_height(LengthModeHeight) , m_imageLoader(this) { } @@ -62,11 +59,9 @@ void SVGImageElement::parseMappedAttribute(MappedAttribute *attr) setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) setYBaseValue(SVGLength(LengthModeHeight, attr->value())); - else if (attr->name() == SVGNames::preserveAspectRatioAttr) { - const UChar* c = attr->value().characters(); - const UChar* end = c + attr->value().length(); - preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end); - } else if (attr->name() == SVGNames::widthAttr) { + else if (attr->name() == SVGNames::preserveAspectRatioAttr) + SVGPreserveAspectRatio::parsePreserveAspectRatio(this, attr->value()); + else if (attr->name() == SVGNames::widthAttr) { setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); addCSSProperty(attr, CSSPropertyWidth, attr->value()); if (widthBaseValue().value(this) < 0.0) @@ -110,6 +105,37 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) } } +void SVGImageElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizePreserveAspectRatio(); + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (attrName == SVGNames::preserveAspectRatioAttr) + synchronizePreserveAspectRatio(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + bool SVGImageElement::hasRelativeValues() const { return (x().isRelative() || width().isRelative() || diff --git a/WebCore/svg/SVGImageElement.h b/WebCore/svg/SVGImageElement.h index 1bdcdba..3fa0e3f 100644 --- a/WebCore/svg/SVGImageElement.h +++ b/WebCore/svg/SVGImageElement.h @@ -47,6 +47,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void attach(); virtual void insertedIntoDocument(); @@ -61,19 +62,17 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::heightAttrString, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY(SVGImageElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGImageElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGImageElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGImageElement, SVGNames::heightAttr, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY(SVGImageElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGImageElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGImageElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) SVGImageLoader m_imageLoader; }; diff --git a/WebCore/svg/SVGLangSpace.idl b/WebCore/svg/SVGLangSpace.idl index a10867e..277e514 100644 --- a/WebCore/svg/SVGLangSpace.idl +++ b/WebCore/svg/SVGLangSpace.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGLangSpace { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGLangSpace { attribute core::DOMString xmllang /*setter raises(DOMException)*/; attribute core::DOMString xmlspace diff --git a/WebCore/svg/SVGLength.idl b/WebCore/svg/SVGLength.idl index 3938a2c..a349c47 100644 --- a/WebCore/svg/SVGLength.idl +++ b/WebCore/svg/SVGLength.idl @@ -22,7 +22,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor, PODType=SVGLength] SVGLength { + interface [Conditional=SVG, PODType=SVGLength] SVGLength { // Length Unit Types const unsigned short SVG_LENGTHTYPE_UNKNOWN = 0; const unsigned short SVG_LENGTHTYPE_NUMBER = 1; diff --git a/WebCore/svg/SVGLineElement.cpp b/WebCore/svg/SVGLineElement.cpp index a359698..6c8a16b 100644 --- a/WebCore/svg/SVGLineElement.cpp +++ b/WebCore/svg/SVGLineElement.cpp @@ -36,11 +36,10 @@ SVGLineElement::SVGLineElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_x1(this, SVGNames::x1Attr, LengthModeWidth) - , m_y1(this, SVGNames::y1Attr, LengthModeHeight) - , m_x2(this, SVGNames::x2Attr, LengthModeWidth) - , m_y2(this, SVGNames::y2Attr, LengthModeHeight) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_x1(LengthModeWidth) + , m_y1(LengthModeHeight) + , m_x2(LengthModeWidth) + , m_y2(LengthModeHeight) { } @@ -85,6 +84,31 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGLineElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX1(); + synchronizeY1(); + synchronizeX2(); + synchronizeY2(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::x1Attr) + synchronizeX1(); + else if (attrName == SVGNames::y1Attr) + synchronizeY1(); + else if (attrName == SVGNames::x2Attr) + synchronizeX2(); + else if (attrName == SVGNames::y2Attr) + synchronizeY2(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + Path SVGLineElement::toPathData() const { return Path::createLine(FloatPoint(x1().value(this), y1().value(this)), diff --git a/WebCore/svg/SVGLineElement.h b/WebCore/svg/SVGLineElement.h index a24e009..c5ecafa 100644 --- a/WebCore/svg/SVGLineElement.h +++ b/WebCore/svg/SVGLineElement.h @@ -43,6 +43,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual Path toPathData() const; @@ -52,15 +53,13 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::x1AttrString, SVGLength, X1, x1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::y1AttrString, SVGLength, Y1, y1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::x2AttrString, SVGLength, X2, x2) - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::y2AttrString, SVGLength, Y2, y2) + DECLARE_ANIMATED_PROPERTY(SVGLineElement, SVGNames::x1Attr, SVGLength, X1, x1) + DECLARE_ANIMATED_PROPERTY(SVGLineElement, SVGNames::y1Attr, SVGLength, Y1, y1) + DECLARE_ANIMATED_PROPERTY(SVGLineElement, SVGNames::x2Attr, SVGLength, X2, x2) + DECLARE_ANIMATED_PROPERTY(SVGLineElement, SVGNames::y2Attr, SVGLength, Y2, y2) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGLineElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGLinearGradientElement.cpp b/WebCore/svg/SVGLinearGradientElement.cpp index f5c8cee..665a1da 100644 --- a/WebCore/svg/SVGLinearGradientElement.cpp +++ b/WebCore/svg/SVGLinearGradientElement.cpp @@ -40,10 +40,10 @@ namespace WebCore { SVGLinearGradientElement::SVGLinearGradientElement(const QualifiedName& tagName, Document* doc) : SVGGradientElement(tagName, doc) - , m_x1(this, SVGNames::x1Attr, LengthModeWidth) - , m_y1(this, SVGNames::y1Attr, LengthModeHeight) - , m_x2(this, SVGNames::x2Attr, LengthModeWidth, "100%") - , m_y2(this, SVGNames::y2Attr, LengthModeHeight) + , m_x1(LengthModeWidth) + , m_y1(LengthModeHeight) + , m_x2(LengthModeWidth, "100%") + , m_y2(LengthModeHeight) { // Spec: If the x2 attribute is not specified, the effect is as if a value of "100%" were specified. } @@ -78,6 +78,28 @@ void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName m_resource->invalidate(); } +void SVGLinearGradientElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGGradientElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX1(); + synchronizeY1(); + synchronizeX2(); + synchronizeY2(); + return; + } + + if (attrName == SVGNames::x1Attr) + synchronizeX1(); + else if (attrName == SVGNames::y1Attr) + synchronizeY1(); + else if (attrName == SVGNames::x2Attr) + synchronizeX2(); + else if (attrName == SVGNames::y2Attr) + synchronizeY2(); +} + void SVGLinearGradientElement::buildGradient() const { LinearGradientAttributes attributes = collectGradientProperties(); diff --git a/WebCore/svg/SVGLinearGradientElement.h b/WebCore/svg/SVGLinearGradientElement.h index 492c366..0308c0e 100644 --- a/WebCore/svg/SVGLinearGradientElement.h +++ b/WebCore/svg/SVGLinearGradientElement.h @@ -36,6 +36,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); protected: virtual void buildGradient() const; @@ -44,10 +45,10 @@ namespace WebCore { LinearGradientAttributes collectGradientProperties() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::x1AttrString, SVGLength, X1, x1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::y1AttrString, SVGLength, Y1, y1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::x2AttrString, SVGLength, X2, x2) - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::y2AttrString, SVGLength, Y2, y2) + DECLARE_ANIMATED_PROPERTY(SVGLinearGradientElement, SVGNames::x1Attr, SVGLength, X1, x1) + DECLARE_ANIMATED_PROPERTY(SVGLinearGradientElement, SVGNames::y1Attr, SVGLength, Y1, y1) + DECLARE_ANIMATED_PROPERTY(SVGLinearGradientElement, SVGNames::x2Attr, SVGLength, X2, x2) + DECLARE_ANIMATED_PROPERTY(SVGLinearGradientElement, SVGNames::y2Attr, SVGLength, Y2, y2) }; } // namespace WebCore diff --git a/WebCore/svg/SVGList.h b/WebCore/svg/SVGList.h index 8fb3bc1..e1249e2 100644 --- a/WebCore/svg/SVGList.h +++ b/WebCore/svg/SVGList.h @@ -176,7 +176,7 @@ namespace WebCore { // Updating facilities, used by JSSVGPODTypeWrapperCreatorForList Item value() const { return m_item; } - void setValue(Item newItem) { m_item = newItem; } + void setValue(const Item& newItem) { m_item = newItem; } private: SVGPODListItem() : m_item() { } diff --git a/WebCore/svg/SVGLocatable.idl b/WebCore/svg/SVGLocatable.idl index b051286..72db8f4 100644 --- a/WebCore/svg/SVGLocatable.idl +++ b/WebCore/svg/SVGLocatable.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGLocatable { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGLocatable { readonly attribute SVGElement nearestViewportElement; readonly attribute SVGElement farthestViewportElement; diff --git a/WebCore/svg/SVGMPathElement.cpp b/WebCore/svg/SVGMPathElement.cpp index b8c862a..dfe7e99 100644 --- a/WebCore/svg/SVGMPathElement.cpp +++ b/WebCore/svg/SVGMPathElement.cpp @@ -31,8 +31,6 @@ namespace WebCore { SVGMPathElement::SVGMPathElement(const QualifiedName& qname, Document* doc) : SVGElement(qname, doc) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -47,6 +45,22 @@ void SVGMPathElement::parseMappedAttribute(MappedAttribute* attr) SVGElement::parseMappedAttribute(attr); } +void SVGMPathElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + SVGPathElement* SVGMPathElement::pathElement() { Element* target = document()->getElementById(getTarget(href())); diff --git a/WebCore/svg/SVGMPathElement.h b/WebCore/svg/SVGMPathElement.h index ded6cdf..50a7dd1 100644 --- a/WebCore/svg/SVGMPathElement.h +++ b/WebCore/svg/SVGMPathElement.h @@ -36,17 +36,16 @@ namespace WebCore { virtual ~SVGMPathElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); SVGPathElement* pathElement(); private: // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGMPathElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGMPathElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGMPathElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGMPathElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGMarkerElement.cpp b/WebCore/svg/SVGMarkerElement.cpp index 2e96926..ca57fa6 100644 --- a/WebCore/svg/SVGMarkerElement.cpp +++ b/WebCore/svg/SVGMarkerElement.cpp @@ -26,7 +26,6 @@ #include "MappedAttribute.h" #include "PlatformString.h" #include "RenderSVGViewportContainer.h" -#include "SVGAngle.h" #include "SVGFitToViewBox.h" #include "SVGLength.h" #include "SVGNames.h" @@ -43,27 +42,18 @@ SVGMarkerElement::SVGMarkerElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGFitToViewBox() - , m_refX(this, SVGNames::refXAttr, LengthModeWidth) - , m_refY(this, SVGNames::refYAttr, LengthModeHeight) - , m_markerWidth(this, SVGNames::markerWidthAttr, LengthModeWidth, "3") - , m_markerHeight(this, SVGNames::markerHeightAttr, LengthModeHeight, "3") - , m_markerUnits(this, SVGNames::markerUnitsAttr, SVG_MARKERUNITS_STROKEWIDTH) - , m_orientType(this, SVGNames::orientAttr, SVG_MARKER_ORIENT_ANGLE) - , m_orientAngle(this, SVGNames::orientAttr, SVGAngle::create()) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) - , m_viewBox(this, SVGNames::viewBoxAttr) - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) + , m_refX(LengthModeWidth) + , m_refY(LengthModeHeight) + , m_markerWidth(LengthModeWidth, "3") + , m_markerHeight(LengthModeHeight, "3") + , m_markerUnits(SVG_MARKERUNITS_STROKEWIDTH) + , m_orientType(SVG_MARKER_ORIENT_ANGLE) { // Spec: If the markerWidth/markerHeight attribute is not specified, the effect is as if a value of "3" were specified. } SVGMarkerElement::~SVGMarkerElement() { - // Call detach() here because if we wait until ~Node() calls it, we crash during - // RenderSVGViewportContainer destruction, as the renderer assumes that the element - // is still fully constructed. See <https://bugs.webkit.org/show_bug.cgi?id=21293>. - if (renderer()) - detach(); } TransformationMatrix SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const @@ -87,16 +77,16 @@ void SVGMarkerElement::parseMappedAttribute(MappedAttribute* attr) else if (attr->name() == SVGNames::markerHeightAttr) setMarkerHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::orientAttr) { - RefPtr<SVGAngle> angle = SVGAngle::create(); + SVGAngle angle; if (attr->value() == "auto") setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO); else { - angle->setValueAsString(attr->value()); + angle.setValueAsString(attr->value()); setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE); } - setOrientAngleBaseValue(angle.get()); + setOrientAngleBaseValue(angle); } else { if (SVGLangSpace::parseMappedAttribute(attr)) return; @@ -130,6 +120,45 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) } } +void SVGMarkerElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeMarkerUnits(); + synchronizeRefX(); + synchronizeRefY(); + synchronizeMarkerWidth(); + synchronizeMarkerHeight(); + synchronizeOrientAngle(); + synchronizeOrientType(); + synchronizeExternalResourcesRequired(); + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + return; + } + + if (attrName == SVGNames::markerUnitsAttr) + synchronizeMarkerUnits(); + else if (attrName == SVGNames::refXAttr) + synchronizeRefX(); + else if (attrName == SVGNames::refYAttr) + synchronizeRefY(); + else if (attrName == SVGNames::markerWidthAttr) + synchronizeMarkerWidth(); + else if (attrName == SVGNames::markerHeightAttr) + synchronizeMarkerHeight(); + else if (attrName == SVGNames::orientAttr) { + synchronizeOrientAngle(); + synchronizeOrientType(); + } else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGFitToViewBox::isKnownAttribute(attrName)) { + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + } +} + void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); @@ -146,9 +175,7 @@ void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange, void SVGMarkerElement::setOrientToAuto() { setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO); - - RefPtr<SVGAngle> angle = SVGAngle::create(); - setOrientAngleBaseValue(angle.get()); + setOrientAngleBaseValue(SVGAngle()); if (!m_marker) return; @@ -159,10 +186,10 @@ void SVGMarkerElement::setOrientToAuto() m_marker->invalidate(); } -void SVGMarkerElement::setOrientToAngle(PassRefPtr<SVGAngle> angle) +void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle) { setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE); - setOrientAngleBaseValue(angle.get()); + setOrientAngleBaseValue(angle); if (!m_marker) return; @@ -173,20 +200,20 @@ void SVGMarkerElement::setOrientToAngle(PassRefPtr<SVGAngle> angle) m_marker->invalidate(); } -SVGResource* SVGMarkerElement::canvasResource() +SVGResource* SVGMarkerElement::canvasResource(const RenderObject*) { if (!m_marker) m_marker = SVGResourceMarker::create(); - m_marker->setMarker(toRenderSVGViewportContainer(renderer())); + ASSERT(renderer()); + m_marker->setRenderer(toRenderSVGViewportContainer(renderer())); - if (orientType() == SVG_MARKER_ORIENT_ANGLE) { - if (orientAngle()) - m_marker->setAngle(orientAngle()->value()); - } else + if (orientType() == SVG_MARKER_ORIENT_ANGLE) + m_marker->setAngle(orientAngle().value()); + else m_marker->setAutoAngle(); - m_marker->setRef(refX().value(this), refY().value(this)); + m_marker->setReferencePoint(FloatPoint(refX().value(this), refY().value(this))); m_marker->setUseStrokeWidth(markerUnits() == SVG_MARKERUNITS_STROKEWIDTH); return m_marker.get(); diff --git a/WebCore/svg/SVGMarkerElement.h b/WebCore/svg/SVGMarkerElement.h index 7e08a96..8a25cba 100644 --- a/WebCore/svg/SVGMarkerElement.h +++ b/WebCore/svg/SVGMarkerElement.h @@ -22,7 +22,7 @@ #define SVGMarkerElement_h #if ENABLE(SVG) - +#include "RenderObject.h" #include "SVGAngle.h" #include "SVGExternalResourcesRequired.h" #include "SVGFitToViewBox.h" @@ -33,7 +33,6 @@ namespace WebCore { class Document; - class SVGAngle; extern char SVGOrientTypeAttrIdentifier[]; extern char SVGOrientAngleAttrIdentifier[]; @@ -61,32 +60,31 @@ namespace WebCore { TransformationMatrix viewBoxToViewTransform(float viewWidth, float viewHeight) const; void setOrientToAuto(); - void setOrientToAngle(PassRefPtr<SVGAngle>); + void setOrientToAngle(const SVGAngle&); virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual SVGResource* canvasResource(); + virtual SVGResource* canvasResource(const RenderObject*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::refXAttrString, SVGLength, RefX, refX) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::refYAttrString, SVGLength, RefY, refY) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::markerWidthAttrString, SVGLength, MarkerWidth, markerWidth) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::markerHeightAttrString, SVGLength, MarkerHeight, markerHeight) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::markerUnitsAttrString, int, MarkerUnits, markerUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGOrientTypeAttrIdentifier, int, OrientType, orientType) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGOrientAngleAttrIdentifier, SVGAngle, OrientAngle, orientAngle) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::refXAttr, SVGLength, RefX, refX) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::refYAttr, SVGLength, RefY, refY) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::markerWidthAttr, SVGLength, MarkerWidth, markerWidth) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::markerHeightAttr, SVGLength, MarkerHeight, markerHeight) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::markerUnitsAttr, int, MarkerUnits, markerUnits) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGMarkerElement, SVGNames::orientAttr, SVGOrientTypeAttrIdentifier, int, OrientType, orientType) + DECLARE_ANIMATED_PROPERTY_MULTIPLE_WRAPPERS(SVGMarkerElement, SVGNames::orientAttr, SVGOrientAngleAttrIdentifier, SVGAngle, OrientAngle, orientAngle) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) // SVGFitToViewBox - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGFitToViewBoxIdentifier, SVGNames::viewBoxAttrString, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGFitToViewBoxIdentifier, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) + DECLARE_ANIMATED_PROPERTY(SVGMarkerElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) RefPtr<SVGResourceMarker> m_marker; }; diff --git a/WebCore/svg/SVGMarkerElement.idl b/WebCore/svg/SVGMarkerElement.idl index 2f6c45e..c715d70 100644 --- a/WebCore/svg/SVGMarkerElement.idl +++ b/WebCore/svg/SVGMarkerElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGMarkerElement : SVGElement, + interface [Conditional=SVG] SVGMarkerElement : SVGElement, SVGLangSpace, SVGExternalResourcesRequired, SVGStylable, diff --git a/WebCore/svg/SVGMaskElement.cpp b/WebCore/svg/SVGMaskElement.cpp index e131d34..75f3dcd 100644 --- a/WebCore/svg/SVGMaskElement.cpp +++ b/WebCore/svg/SVGMaskElement.cpp @@ -25,10 +25,14 @@ #if ENABLE(SVG) #include "SVGMaskElement.h" +#include "CanvasPixelArray.h" #include "CSSStyleSelector.h" #include "GraphicsContext.h" +#include "Image.h" #include "ImageBuffer.h" +#include "ImageData.h" #include "MappedAttribute.h" +#include "RenderObject.h" #include "RenderSVGContainer.h" #include "SVGLength.h" #include "SVGNames.h" @@ -37,6 +41,7 @@ #include <math.h> #include <wtf/MathExtras.h> #include <wtf/OwnPtr.h> +#include <wtf/Vector.h> using namespace std; @@ -48,14 +53,12 @@ SVGMaskElement::SVGMaskElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_maskUnits(this, SVGNames::maskUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_maskContentUnits(this, SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_x(this, SVGNames::xAttr, LengthModeWidth, "-10%") - , m_y(this, SVGNames::yAttr, LengthModeHeight, "-10%") - , m_width(this, SVGNames::widthAttr, LengthModeWidth, "120%") - , m_height(this, SVGNames::heightAttr, LengthModeHeight, "120%") - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_maskUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_maskContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + , m_x(LengthModeWidth, "-10%") + , m_y(LengthModeHeight, "-10%") + , m_width(LengthModeWidth, "120%") + , m_height(LengthModeHeight, "120%") { // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. @@ -102,7 +105,7 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledElement::svgAttributeChanged(attrName); - if (!m_masker) + if (m_masker.isEmpty()) return; if (attrName == SVGNames::maskUnitsAttr || attrName == SVGNames::maskContentUnitsAttr || @@ -113,90 +116,151 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName) SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName) || SVGStyledElement::isKnownAttribute(attrName)) - m_masker->invalidate(); + for (HashMap<const RenderObject*, RefPtr<SVGResourceMasker> >::iterator it = m_masker.begin(); it != m_masker.end(); ++it) + it->second->invalidate(); +} + +void SVGMaskElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeMaskUnits(); + synchronizeMaskContentUnits(); + synchronizeX(); + synchronizeY(); + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::maskUnitsAttr) + synchronizeMaskUnits(); + else if (attrName == SVGNames::maskContentUnitsAttr) + synchronizeMaskContentUnits(); + else if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); } void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); - if (!m_masker) + if (m_masker.isEmpty()) return; - m_masker->invalidate(); + for (HashMap<const RenderObject*, RefPtr<SVGResourceMasker> >::iterator it = m_masker.begin(); it != m_masker.end(); ++it) + it->second->invalidate(); } -PassOwnPtr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targetRect, FloatRect& maskDestRect) const -{ - // Determine specified mask size +FloatRect SVGMaskElement::maskBoundingBox(const FloatRect& objectBoundingBox) const +{ + FloatRect maskBBox; if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - maskDestRect = FloatRect(x().valueAsPercentage() * targetRect.width(), - y().valueAsPercentage() * targetRect.height(), - width().valueAsPercentage() * targetRect.width(), - height().valueAsPercentage() * targetRect.height()); + maskBBox = FloatRect(x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(), + y().valueAsPercentage() * objectBoundingBox.height() + objectBoundingBox.y(), + width().valueAsPercentage() * objectBoundingBox.width(), + height().valueAsPercentage() * objectBoundingBox.height()); else - maskDestRect = FloatRect(x().value(this), - y().value(this), - width().value(this), - height().value(this)); + maskBBox = FloatRect(x().value(this), + y().value(this), + width().value(this), + height().value(this)); + + return maskBBox; +} + +PassOwnPtr<ImageBuffer> SVGMaskElement::drawMaskerContent(const RenderObject* object, FloatRect& maskDestRect, bool& emptyMask) const +{ + FloatRect objectBoundingBox = object->objectBoundingBox(); + + // Mask rect clipped with clippingBoundingBox and filterBoundingBox as long as they are present. + maskDestRect = object->repaintRectInLocalCoordinates(); + if (maskDestRect.isEmpty()) { + emptyMask = true; + return 0; + } + + // Calculate the smallest rect for the mask ImageBuffer. + FloatRect repaintRect; + Vector<RenderObject*> rendererList; + for (Node* node = firstChild(); node; node = node->nextSibling()) { + if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer()) + continue; + + rendererList.append(node->renderer()); + repaintRect.unite(node->renderer()->localToParentTransform().mapRect(node->renderer()->repaintRectInLocalCoordinates())); + } - IntSize imageSize(lroundf(maskDestRect.width()), lroundf(maskDestRect.height())); - clampImageBufferSizeToViewport(document()->view(), imageSize); + TransformationMatrix contextTransform; + // We need to scale repaintRect for objectBoundingBox to get the drawing area. + if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { + contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); + FloatPoint contextAdjustment = repaintRect.location(); + repaintRect = contextTransform.mapRect(repaintRect); + repaintRect.move(objectBoundingBox.x(), objectBoundingBox.y()); + contextTransform.translate(-contextAdjustment.x(), -contextAdjustment.y()); + } + repaintRect.intersect(maskDestRect); + maskDestRect = repaintRect; + IntRect maskImageRect = enclosingIntRect(maskDestRect); - if (imageSize.width() < static_cast<int>(maskDestRect.width())) - maskDestRect.setWidth(imageSize.width()); + maskImageRect.setLocation(IntPoint()); - if (imageSize.height() < static_cast<int>(maskDestRect.height())) - maskDestRect.setHeight(imageSize.height()); + // Don't create ImageBuffers with image size of 0 + if (!maskImageRect.width() || !maskImageRect.height()) { + emptyMask = true; + return 0; + } // FIXME: This changes color space to linearRGB, the default color space // for masking operations in SVG. We need a switch for the other color-space // attribute values sRGB, inherit and auto. - OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(imageSize, LinearRGB); + OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskImageRect.size(), LinearRGB); if (!maskImage) return 0; - FloatPoint maskContextLocation = maskDestRect.location(); - if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { - maskDestRect.move(targetRect.x(), targetRect.y()); - if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - maskContextLocation.move(targetRect.x(), targetRect.y()); - } else { - if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - maskContextLocation.move(-targetRect.x(), -targetRect.y()); - } - GraphicsContext* maskImageContext = maskImage->context(); ASSERT(maskImageContext); maskImageContext->save(); - maskImageContext->translate(-maskContextLocation.x(), -maskContextLocation.y()); - if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { - maskImageContext->save(); - maskImageContext->scale(FloatSize(targetRect.width(), targetRect.height())); - } + if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + maskImageContext->translate(-maskDestRect.x(), -maskDestRect.y()); + maskImageContext->concatCTM(contextTransform); - // Render subtree into ImageBuffer - for (Node* n = firstChild(); n; n = n->nextSibling()) { - SVGElement* elem = 0; - if (n->isSVGElement()) - elem = static_cast<SVGElement*>(n); - if (!elem || !elem->isStyled()) - continue; + // draw the content into the ImageBuffer + Vector<RenderObject*>::iterator end = rendererList.end(); + for (Vector<RenderObject*>::iterator it = rendererList.begin(); it != end; it++) + renderSubtreeToImage(maskImage.get(), *it); + + + maskImageContext->restore(); + + // create the luminance mask + RefPtr<ImageData> imageData(maskImage->getUnmultipliedImageData(maskImageRect)); + CanvasPixelArray* srcPixelArray(imageData->data()); - SVGStyledElement* e = static_cast<SVGStyledElement*>(elem); - RenderObject* item = e->renderer(); - if (!item) + for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) { + unsigned char a = srcPixelArray->get(pixelOffset + 3); + if (!a) continue; + unsigned char r = srcPixelArray->get(pixelOffset); + unsigned char g = srcPixelArray->get(pixelOffset + 1); + unsigned char b = srcPixelArray->get(pixelOffset + 2); - renderSubtreeToImage(maskImage.get(), item); + double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); + srcPixelArray->set(pixelOffset + 3, luma); } - if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - maskImageContext->restore(); + maskImage->putUnmultipliedImageData(imageData.get(), maskImageRect, IntPoint()); - maskImageContext->restore(); return maskImage.release(); } @@ -207,11 +271,18 @@ RenderObject* SVGMaskElement::createRenderer(RenderArena* arena, RenderStyle*) return maskContainer; } -SVGResource* SVGMaskElement::canvasResource() +SVGResource* SVGMaskElement::canvasResource(const RenderObject* object) { - if (!m_masker) - m_masker = SVGResourceMasker::create(this); - return m_masker.get(); + ASSERT(object); + + if (m_masker.contains(object)) + return m_masker.get(object).get(); + + RefPtr<SVGResourceMasker> masker = SVGResourceMasker::create(this); + SVGResourceMasker* maskerPtr = masker.get(); + m_masker.set(object, masker.release()); + + return maskerPtr; } } diff --git a/WebCore/svg/SVGMaskElement.h b/WebCore/svg/SVGMaskElement.h index 362c730..3abc08b 100644 --- a/WebCore/svg/SVGMaskElement.h +++ b/WebCore/svg/SVGMaskElement.h @@ -21,17 +21,20 @@ #define SVGMaskElement_h #if ENABLE(SVG) +#include "RenderObject.h" #include "SVGResourceMasker.h" #include "SVGExternalResourcesRequired.h" #include "SVGLangSpace.h" #include "SVGStyledLocatableElement.h" #include "SVGTests.h" #include "SVGURIReference.h" +#include <wtf/HashMap.h> #include <wtf/PassOwnPtr.h> namespace WebCore { class SVGLength; + class SVGResourceMasker; class SVGMaskElement : public SVGStyledLocatableElement, public SVGURIReference, @@ -43,32 +46,32 @@ namespace WebCore { virtual ~SVGMaskElement(); virtual bool isValid() const { return SVGTests::isValid(); } + FloatRect maskBoundingBox(const FloatRect&) const; virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual SVGResource* canvasResource(); + virtual SVGResource* canvasResource(const RenderObject*); - PassOwnPtr<ImageBuffer> drawMaskerContent(const FloatRect& targetRect, FloatRect& maskRect) const; + PassOwnPtr<ImageBuffer> drawMaskerContent(const RenderObject*, FloatRect& maskRect, bool& emptyMask) const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::maskUnitsAttrString, int, MaskUnits, maskUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::maskContentUnitsAttrString, int, MaskContentUnits, maskContentUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::heightAttrString, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, SVGNames::maskUnitsAttr, int, MaskUnits, maskUnits) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, SVGNames::maskContentUnitsAttr, int, MaskContentUnits, maskContentUnits) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, SVGNames::heightAttr, SVGLength, Height, height) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGMaskElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) - RefPtr<SVGResourceMasker> m_masker; + HashMap<const RenderObject*, RefPtr<SVGResourceMasker> > m_masker; }; } // namespace WebCore diff --git a/WebCore/svg/SVGNumberList.cpp b/WebCore/svg/SVGNumberList.cpp index c73e397..11aebde 100644 --- a/WebCore/svg/SVGNumberList.cpp +++ b/WebCore/svg/SVGNumberList.cpp @@ -28,7 +28,7 @@ namespace WebCore { SVGNumberList::SVGNumberList(const QualifiedName& attributeName) - : SVGList<float>(attributeName) + : SVGPODList<float>(attributeName) { } diff --git a/WebCore/svg/SVGNumberList.h b/WebCore/svg/SVGNumberList.h index 29de27e..329968b 100644 --- a/WebCore/svg/SVGNumberList.h +++ b/WebCore/svg/SVGNumberList.h @@ -29,7 +29,7 @@ namespace WebCore { class String; - class SVGNumberList : public SVGList<float> { + class SVGNumberList : public SVGPODList<float> { public: static PassRefPtr<SVGNumberList> create(const QualifiedName& attributeName) { return adoptRef(new SVGNumberList(attributeName)); } virtual ~SVGNumberList(); diff --git a/WebCore/svg/SVGPaint.idl b/WebCore/svg/SVGPaint.idl index 7799aa3..392ae33 100644 --- a/WebCore/svg/SVGPaint.idl +++ b/WebCore/svg/SVGPaint.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGPaint : SVGColor { + interface [Conditional=SVG] SVGPaint : SVGColor { // SVGPaintType const unsigned short SVG_PAINTTYPE_UNKNOWN = 0; const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1; diff --git a/WebCore/svg/SVGPathElement.cpp b/WebCore/svg/SVGPathElement.cpp index d53fbb2..f6e7867 100644 --- a/WebCore/svg/SVGPathElement.cpp +++ b/WebCore/svg/SVGPathElement.cpp @@ -47,8 +47,6 @@ SVGPathElement::SVGPathElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_pathLength(this, SVGNames::pathLengthAttr, 0.0f) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -206,6 +204,22 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGPathElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizePathLength(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::pathLengthAttr) + synchronizePathLength(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + SVGPathSegList* SVGPathElement::pathSegList() const { if (!m_pathSegList) diff --git a/WebCore/svg/SVGPathElement.h b/WebCore/svg/SVGPathElement.h index 266bfdd..e46ed92 100644 --- a/WebCore/svg/SVGPathElement.h +++ b/WebCore/svg/SVGPathElement.h @@ -92,6 +92,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual Path toPathData() const; @@ -100,12 +101,10 @@ namespace WebCore { private: mutable RefPtr<SVGPathSegList> m_pathSegList; - ANIMATED_PROPERTY_DECLARATIONS(SVGPathElement, SVGNames::pathTagString, SVGNames::pathLengthAttrString, float, PathLength, pathLength) + DECLARE_ANIMATED_PROPERTY(SVGPathElement, SVGNames::pathLengthAttr, float, PathLength, pathLength) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGPathElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGPathElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSeg.idl b/WebCore/svg/SVGPathSeg.idl index 6754d2a..afabb41 100644 --- a/WebCore/svg/SVGPathSeg.idl +++ b/WebCore/svg/SVGPathSeg.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, CustomToJS, GenerateConstructor, Polymorphic] SVGPathSeg { + interface [Conditional=SVG, CustomToJS, Polymorphic] SVGPathSeg { // Path Segment Types const unsigned short PATHSEG_UNKNOWN = 0; const unsigned short PATHSEG_CLOSEPATH = 1; diff --git a/WebCore/svg/SVGPatternElement.cpp b/WebCore/svg/SVGPatternElement.cpp index a10c2c2..b3c040b 100644 --- a/WebCore/svg/SVGPatternElement.cpp +++ b/WebCore/svg/SVGPatternElement.cpp @@ -55,17 +55,13 @@ SVGPatternElement::SVGPatternElement(const QualifiedName& tagName, Document* doc , SVGLangSpace() , SVGExternalResourcesRequired() , SVGFitToViewBox() - , m_x(this, SVGNames::xAttr, LengthModeWidth) - , m_y(this, SVGNames::yAttr, LengthModeHeight) - , m_width(this, SVGNames::widthAttr, LengthModeWidth) - , m_height(this, SVGNames::heightAttr, LengthModeHeight) - , m_patternUnits(this, SVGNames::patternUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_patternContentUnits(this, SVGNames::patternContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_patternTransform(this, SVGNames::patternTransformAttr, SVGTransformList::create(SVGNames::patternTransformAttr)) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) - , m_viewBox(this, SVGNames::viewBoxAttr) - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) + , m_x(LengthModeWidth) + , m_y(LengthModeHeight) + , m_width(LengthModeWidth) + , m_height(LengthModeHeight) + , m_patternUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_patternContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + , m_patternTransform(SVGTransformList::create(SVGNames::patternTransformAttr)) { } @@ -138,6 +134,48 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName) m_resource->invalidate(); } +void SVGPatternElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizePatternUnits(); + synchronizePatternContentUnits(); + synchronizePatternTransform(); + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizeExternalResourcesRequired(); + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::patternUnitsAttr) + synchronizePatternUnits(); + else if (attrName == SVGNames::patternContentUnitsAttr) + synchronizePatternContentUnits(); + else if (attrName == SVGNames::patternTransformAttr) + synchronizePatternTransform(); + else if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGFitToViewBox::isKnownAttribute(attrName)) { + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + } else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + void SVGPatternElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); @@ -263,7 +301,7 @@ RenderObject* SVGPatternElement::createRenderer(RenderArena* arena, RenderStyle* return patternContainer; } -SVGResource* SVGPatternElement::canvasResource() +SVGResource* SVGPatternElement::canvasResource(const RenderObject*) { if (!m_resource) m_resource = SVGPaintServerPattern::create(this); diff --git a/WebCore/svg/SVGPatternElement.h b/WebCore/svg/SVGPatternElement.h index 6a679af..fffbbca 100644 --- a/WebCore/svg/SVGPatternElement.h +++ b/WebCore/svg/SVGPatternElement.h @@ -22,6 +22,7 @@ #define SVGPatternElement_h #if ENABLE(SVG) +#include "RenderObject.h" #include "SVGExternalResourcesRequired.h" #include "SVGFitToViewBox.h" #include "SVGLangSpace.h" @@ -51,31 +52,30 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - virtual SVGResource* canvasResource(); + virtual SVGResource* canvasResource(const RenderObject*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::heightAttrString, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::patternUnitsAttrString, int, PatternUnits, patternUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::patternContentUnitsAttrString, int, PatternContentUnits, patternContentUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::patternTransformAttrString, SVGTransformList, PatternTransform, patternTransform) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::heightAttr, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::patternUnitsAttr, int, PatternUnits, patternUnits) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::patternContentUnitsAttr, int, PatternContentUnits, patternContentUnits) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::patternTransformAttr, SVGTransformList*, PatternTransform, patternTransform) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) // SVGPatternElement - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGFitToViewBoxIdentifier, SVGNames::viewBoxAttrString, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGFitToViewBoxIdentifier, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) + DECLARE_ANIMATED_PROPERTY(SVGPatternElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) mutable RefPtr<SVGPaintServerPattern> m_resource; diff --git a/WebCore/svg/SVGPointList.idl b/WebCore/svg/SVGPointList.idl index cf82dff..24b1042 100644 --- a/WebCore/svg/SVGPointList.idl +++ b/WebCore/svg/SVGPointList.idl @@ -28,19 +28,19 @@ module svg { interface [Conditional=SVG] SVGPointList { readonly attribute unsigned long numberOfItems; - [JSCCustom] void clear() + void clear() raises(DOMException); - [JSCCustom] SVGPoint initialize(in SVGPoint item) + SVGPoint initialize(in SVGPoint item) raises(DOMException, SVGException); - [JSCCustom] SVGPoint getItem(in unsigned long index) + SVGPoint getItem(in unsigned long index) raises(DOMException); - [JSCCustom] SVGPoint insertItemBefore(in SVGPoint item, in unsigned long index) + SVGPoint insertItemBefore(in SVGPoint item, in unsigned long index) raises(DOMException, SVGException); - [JSCCustom] SVGPoint replaceItem(in SVGPoint item, in unsigned long index) + SVGPoint replaceItem(in SVGPoint item, in unsigned long index) raises(DOMException, SVGException); - [JSCCustom] SVGPoint removeItem(in unsigned long index) + SVGPoint removeItem(in unsigned long index) raises(DOMException); - [JSCCustom] SVGPoint appendItem(in SVGPoint item) + SVGPoint appendItem(in SVGPoint item) raises(DOMException, SVGException); }; diff --git a/WebCore/svg/SVGPolyElement.cpp b/WebCore/svg/SVGPolyElement.cpp index 61725b5..800bdfa 100644 --- a/WebCore/svg/SVGPolyElement.cpp +++ b/WebCore/svg/SVGPolyElement.cpp @@ -27,7 +27,6 @@ #include "FloatPoint.h" #include "MappedAttribute.h" #include "RenderPath.h" -#include "SVGAnimatedProperty.h" #include "SVGNames.h" #include "SVGParserUtilities.h" #include "SVGPointList.h" @@ -40,7 +39,6 @@ SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGAnimatedPoints() - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -88,41 +86,35 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); - if (!renderer()) - return; - - if (attrName == SVGNames::pointsAttr) { + // The points property is not a regular SVGAnimatedProperty, still we use the same SVG<->XML DOM synchronization framework. + if (attrName == SVGNames::pointsAttr) setSynchronizedSVGAttributes(false); - renderer()->setNeedsLayout(true); + + if (!renderer()) return; - } - if (SVGTests::isKnownAttribute(attrName) || - SVGLangSpace::isKnownAttribute(attrName) || - SVGExternalResourcesRequired::isKnownAttribute(attrName) || - SVGStyledTransformableElement::isKnownAttribute(attrName)) + if (attrName == SVGNames::pointsAttr + || SVGTests::isKnownAttribute(attrName) + || SVGLangSpace::isKnownAttribute(attrName) + || SVGExternalResourcesRequired::isKnownAttribute(attrName) + || SVGStyledTransformableElement::isKnownAttribute(attrName)) renderer()->setNeedsLayout(true); } -// Custom SVG<->XML synchronization logic, as SVGPoly*Element doesn't use animated -// properties for this, but a special solution: SVGAnimatedPoints inheritance. -void SVGPolyElement::updateAnimatedSVGAttribute(const String& name) const +void SVGPolyElement::synchronizeProperty(const QualifiedName& attrName) { - ASSERT(!m_areSVGAttributesValid); - - if (m_synchronizingSVGAttributes) - return; - - if (name == SVGNames::pointsAttr.localName()) { - m_synchronizingSVGAttributes = true; + SVGStyledTransformableElement::synchronizeProperty(attrName); - PropertySynchronizer<SVGPolyElement, SVGPointList*, true>::synchronize(this, SVGNames::pointsAttr, m_points.get()); - setSynchronizedSVGAttributes(true); - m_synchronizingSVGAttributes = false; + if (attrName == anyQName()) { + synchronizeExternalResourcesRequired(); + SVGAnimatedPropertySynchronizer<true>::synchronize(this, SVGNames::pointsAttr, points()->valueAsString()); return; } - SVGStyledTransformableElement::updateAnimatedSVGAttribute(name); + if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (attrName == SVGNames::pointsAttr) + SVGAnimatedPropertySynchronizer<true>::synchronize(this, attrName, points()->valueAsString()); } } diff --git a/WebCore/svg/SVGPolyElement.h b/WebCore/svg/SVGPolyElement.h index 2ffd150..b881ca2 100644 --- a/WebCore/svg/SVGPolyElement.h +++ b/WebCore/svg/SVGPolyElement.h @@ -46,17 +46,14 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual bool rendererIsNeeded(RenderStyle* style) { return StyledElement::rendererIsNeeded(style); } virtual bool supportsMarkers() const { return true; } - virtual void updateAnimatedSVGAttribute(const String&) const; - private: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGPolyElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGPolyElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) mutable RefPtr<SVGPointList> m_points; }; diff --git a/WebCore/svg/SVGPreserveAspectRatio.cpp b/WebCore/svg/SVGPreserveAspectRatio.cpp index e6452c3..be07a26 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.cpp +++ b/WebCore/svg/SVGPreserveAspectRatio.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + 2010 Dirk Schulze <krit@webkit.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -60,11 +61,12 @@ unsigned short SVGPreserveAspectRatio::meetOrSlice() const return m_meetOrSlice; } -bool SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate) +SVGPreserveAspectRatio SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate, bool& result) { - SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_NONE; - SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET; - bool ret = false; + SVGPreserveAspectRatio aspectRatio; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_NONE; + aspectRatio.m_meetOrSlice = SVG_MEETORSLICE_MEET; + result = false; if (!skipOptionalSpaces(currParam, end)) goto bail_out; @@ -90,25 +92,25 @@ bool SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, c if (currParam[3] == 'n') { if (currParam[6] == 'i') { if (currParam[7] == 'n') - align = SVG_PRESERVEASPECTRATIO_XMINYMIN; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMINYMIN; else if (currParam[7] == 'd') - align = SVG_PRESERVEASPECTRATIO_XMINYMID; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMINYMID; else goto bail_out; } else if (currParam[6] == 'a' && currParam[7] == 'x') - align = SVG_PRESERVEASPECTRATIO_XMINYMAX; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMINYMAX; else goto bail_out; } else if (currParam[3] == 'd') { if (currParam[6] == 'i') { if (currParam[7] == 'n') - align = SVG_PRESERVEASPECTRATIO_XMIDYMIN; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMIDYMIN; else if (currParam[7] == 'd') - align = SVG_PRESERVEASPECTRATIO_XMIDYMID; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID; else goto bail_out; } else if (currParam[6] == 'a' && currParam[7] == 'x') - align = SVG_PRESERVEASPECTRATIO_XMIDYMAX; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMIDYMAX; else goto bail_out; } else @@ -116,13 +118,13 @@ bool SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, c } else if (currParam[2] == 'a' && currParam[3] == 'x') { if (currParam[6] == 'i') { if (currParam[7] == 'n') - align = SVG_PRESERVEASPECTRATIO_XMAXYMIN; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMAXYMIN; else if (currParam[7] == 'd') - align = SVG_PRESERVEASPECTRATIO_XMAXYMID; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMAXYMID; else goto bail_out; } else if (currParam[6] == 'a' && currParam[7] == 'x') - align = SVG_PRESERVEASPECTRATIO_XMAXYMAX; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_XMAXYMAX; else goto bail_out; } else @@ -141,31 +143,102 @@ bool SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, c if (!skipString(currParam, end, "slice")) goto bail_out; skipOptionalSpaces(currParam, end); - if (align != SVG_PRESERVEASPECTRATIO_NONE) - meetOrSlice = SVG_MEETORSLICE_SLICE; + if (aspectRatio.m_align != SVG_PRESERVEASPECTRATIO_NONE) + aspectRatio.m_meetOrSlice = SVG_MEETORSLICE_SLICE; } } if (end != currParam && validate) { bail_out: // FIXME: Should the two values be set to UNKNOWN instead? - align = SVG_PRESERVEASPECTRATIO_NONE; - meetOrSlice = SVG_MEETORSLICE_MEET; + aspectRatio.m_align = SVG_PRESERVEASPECTRATIO_NONE; + aspectRatio.m_meetOrSlice = SVG_MEETORSLICE_MEET; } else - ret = true; + result = true; - if (m_align == align && m_meetOrSlice == meetOrSlice) - return ret; + return aspectRatio; +} - m_align = align; - m_meetOrSlice = meetOrSlice; - return ret; +void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRect) +{ + FloatSize imageSize = srcRect.size(); + float origDestWidth = destRect.width(); + float origDestHeight = destRect.height(); + if (meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET) { + float widthToHeightMultiplier = srcRect.height() / srcRect.width(); + if (origDestHeight > (origDestWidth * widthToHeightMultiplier)) { + destRect.setHeight(origDestWidth * widthToHeightMultiplier); + switch (align()) { + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + destRect.setY(destRect.y() + origDestHeight / 2.0f - destRect.height() / 2.0f); + break; + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + destRect.setY(destRect.y() + origDestHeight - destRect.height()); + break; + } + } + if (origDestWidth > (origDestHeight / widthToHeightMultiplier)) { + destRect.setWidth(origDestHeight / widthToHeightMultiplier); + switch (align()) { + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + destRect.setX(destRect.x() + origDestWidth / 2.0f - destRect.width() / 2.0f); + break; + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + destRect.setX(destRect.x() + origDestWidth - destRect.width()); + break; + } + } + } else if (meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE) { + float widthToHeightMultiplier = srcRect.height() / srcRect.width(); + // if the destination height is less than the height of the image we'll be drawing + if (origDestHeight < (origDestWidth * widthToHeightMultiplier)) { + float destToSrcMultiplier = srcRect.width() / destRect.width(); + srcRect.setHeight(destRect.height() * destToSrcMultiplier); + switch (align()) { + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + srcRect.setY(destRect.y() + imageSize.height() / 2.0f - srcRect.height() / 2.0f); + break; + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + srcRect.setY(destRect.y() + imageSize.height() - srcRect.height()); + break; + } + } + // if the destination width is less than the width of the image we'll be drawing + if (origDestWidth < (origDestHeight / widthToHeightMultiplier)) { + float destToSrcMultiplier = srcRect.height() / destRect.height(); + srcRect.setWidth(destRect.width() * destToSrcMultiplier); + switch (align()) { + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + srcRect.setX(destRect.x() + imageSize.width() / 2.0f - srcRect.width() / 2.0f); + break; + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + srcRect.setX(destRect.x() + imageSize.width() - srcRect.width()); + break; + } + } + } } TransformationMatrix SVGPreserveAspectRatio::getCTM(double logicX, double logicY, double logicWidth, double logicHeight, double /*physX*/, double /*physY*/, - double physWidth, double physHeight) + double physWidth, double physHeight) const { TransformationMatrix temp; diff --git a/WebCore/svg/SVGPreserveAspectRatio.h b/WebCore/svg/SVGPreserveAspectRatio.h index 18a89dd..2be053c 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.h +++ b/WebCore/svg/SVGPreserveAspectRatio.h @@ -22,21 +22,17 @@ #define SVGPreserveAspectRatio_h #if ENABLE(SVG) +#include "FloatRect.h" #include "PlatformString.h" #include "SVGNames.h" -#include <wtf/RefCounted.h> - namespace WebCore { class String; class TransformationMatrix; - class SVGStyledElement; - class SVGPreserveAspectRatio : public RefCounted<SVGPreserveAspectRatio> { + class SVGPreserveAspectRatio { public: - static PassRefPtr<SVGPreserveAspectRatio> create() { return adoptRef(new SVGPreserveAspectRatio); } - enum SVGPreserveAspectRatioType { SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, SVG_PRESERVEASPECTRATIO_NONE = 1, @@ -57,6 +53,7 @@ namespace WebCore { SVG_MEETORSLICE_SLICE = 2 }; + SVGPreserveAspectRatio(); virtual ~SVGPreserveAspectRatio(); void setAlign(unsigned short); @@ -64,21 +61,30 @@ namespace WebCore { void setMeetOrSlice(unsigned short); unsigned short meetOrSlice() const; + + void transformRect(FloatRect& destRect, FloatRect& srcRect); TransformationMatrix getCTM(double logicX, double logicY, double logicWidth, double logicHeight, double physX, double physY, - double physWidth, double physHeight); + double physWidth, double physHeight) const; - // Helper - bool parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate = true); - String valueAsString() const; + template<class Consumer> + static bool parsePreserveAspectRatio(Consumer* consumer, const String& value, bool validate = true) + { + bool result = false; + const UChar* begin = value.characters(); + const UChar* end = begin + value.length(); + consumer->setPreserveAspectRatioBaseValue(parsePreserveAspectRatio(begin, end, validate, result)); + return result; + } - const QualifiedName& associatedAttributeName() const { return SVGNames::preserveAspectRatioAttr; } + // It's recommended to use the method above, only SVGViewSpec needs this parsing method + static SVGPreserveAspectRatio parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate, bool& result); + + String valueAsString() const; private: - SVGPreserveAspectRatio(); - unsigned short m_align; unsigned short m_meetOrSlice; }; @@ -87,4 +93,3 @@ namespace WebCore { #endif // ENABLE(SVG) #endif // SVGPreserveAspectRatio_h - diff --git a/WebCore/svg/SVGPreserveAspectRatio.idl b/WebCore/svg/SVGPreserveAspectRatio.idl index 066353e..b21daba 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.idl +++ b/WebCore/svg/SVGPreserveAspectRatio.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGPreserveAspectRatio { + interface [Conditional=SVG, PODType=SVGPreserveAspectRatio] SVGPreserveAspectRatio { // Alignment Types const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0; const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1; diff --git a/WebCore/svg/SVGRadialGradientElement.cpp b/WebCore/svg/SVGRadialGradientElement.cpp index 270de6f..b153c0f 100644 --- a/WebCore/svg/SVGRadialGradientElement.cpp +++ b/WebCore/svg/SVGRadialGradientElement.cpp @@ -42,11 +42,11 @@ namespace WebCore { SVGRadialGradientElement::SVGRadialGradientElement(const QualifiedName& tagName, Document* doc) : SVGGradientElement(tagName, doc) - , m_cx(this, SVGNames::cxAttr, LengthModeWidth, "50%") - , m_cy(this, SVGNames::cyAttr, LengthModeHeight, "50%") - , m_r(this, SVGNames::rAttr, LengthModeOther, "50%") - , m_fx(this, SVGNames::fxAttr, LengthModeWidth) - , m_fy(this, SVGNames::fyAttr, LengthModeHeight) + , m_cx(LengthModeWidth, "50%") + , m_cy(LengthModeHeight, "50%") + , m_r(LengthModeOther, "50%") + , m_fx(LengthModeWidth) + , m_fy(LengthModeHeight) { // Spec: If the cx/cy/r attribute is not specified, the effect is as if a value of "50%" were specified. } @@ -86,6 +86,31 @@ void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName m_resource->invalidate(); } +void SVGRadialGradientElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGGradientElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeCx(); + synchronizeCy(); + synchronizeFx(); + synchronizeFy(); + synchronizeR(); + return; + } + + if (attrName == SVGNames::cxAttr) + synchronizeCx(); + else if (attrName == SVGNames::cyAttr) + synchronizeCy(); + else if (attrName == SVGNames::fxAttr) + synchronizeFx(); + else if (attrName == SVGNames::fyAttr) + synchronizeFy(); + else if (attrName == SVGNames::rAttr) + synchronizeR(); +} + void SVGRadialGradientElement::buildGradient() const { RadialGradientAttributes attributes = collectGradientProperties(); @@ -108,29 +133,17 @@ void SVGRadialGradientElement::buildGradient() const FloatPoint adjustedFocalPoint = focalPoint; float dfx = focalPoint.x() - centerPoint.x(); float dfy = focalPoint.y() - centerPoint.y(); + float rMax = 0.99f * radius; // Spec: If (fx, fy) lies outside the circle defined by (cx, cy) and // r, set (fx, fy) to the point of intersection of the line through // (fx, fy) and the circle. - if (sqrt(dfx * dfx + dfy * dfy) >= radius) { - float angle = atan2f(dfx, dfy); - - // The maximum deviation of 0.2% is needed on Cairo, since Cairo - // is working with fixed point numbers. -#if PLATFORM(CAIRO) - if (focalPoint.x() < centerPoint.x()) - dfx = cosf(angle) * radius + 0.002f; - else - dfx = cosf(angle) * radius - 0.002f; - if (focalPoint.y() < centerPoint.y()) - dfy = sinf(angle) * radius + 0.002f; - else - dfy = sinf(angle) * radius - 0.002f; -#else - dfx = cosf(angle) * radius; - dfy = sinf(angle) * radius; -#endif + // We scale the radius by 0.99 to match the behavior of FireFox. + if (sqrt(dfx * dfx + dfy * dfy) > rMax) { + float angle = atan2f(dfy, dfx); + dfx = cosf(angle) * rMax; + dfy = sinf(angle) * rMax; adjustedFocalPoint = FloatPoint(dfx + centerPoint.x(), dfy + centerPoint.y()); } diff --git a/WebCore/svg/SVGRadialGradientElement.h b/WebCore/svg/SVGRadialGradientElement.h index 61f56f5..180948f 100644 --- a/WebCore/svg/SVGRadialGradientElement.h +++ b/WebCore/svg/SVGRadialGradientElement.h @@ -36,6 +36,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); protected: virtual void buildGradient() const; @@ -44,11 +45,11 @@ namespace WebCore { RadialGradientAttributes collectGradientProperties() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::cxAttrString, SVGLength, Cx, cx) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::cyAttrString, SVGLength, Cy, cy) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::rAttrString, SVGLength, R, r) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::fxAttrString, SVGLength, Fx, fx) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::fyAttrString, SVGLength, Fy, fy) + DECLARE_ANIMATED_PROPERTY(SVGRadialGradientElement, SVGNames::cxAttr, SVGLength, Cx, cx) + DECLARE_ANIMATED_PROPERTY(SVGRadialGradientElement, SVGNames::cyAttr, SVGLength, Cy, cy) + DECLARE_ANIMATED_PROPERTY(SVGRadialGradientElement, SVGNames::rAttr, SVGLength, R, r) + DECLARE_ANIMATED_PROPERTY(SVGRadialGradientElement, SVGNames::fxAttr, SVGLength, Fx, fx) + DECLARE_ANIMATED_PROPERTY(SVGRadialGradientElement, SVGNames::fyAttr, SVGLength, Fy, fy) }; } // namespace WebCore diff --git a/WebCore/svg/SVGRectElement.cpp b/WebCore/svg/SVGRectElement.cpp index f9b04c8..014c42f 100644 --- a/WebCore/svg/SVGRectElement.cpp +++ b/WebCore/svg/SVGRectElement.cpp @@ -35,13 +35,12 @@ SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document *doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_x(this, SVGNames::xAttr, LengthModeWidth) - , m_y(this, SVGNames::yAttr, LengthModeHeight) - , m_width(this, SVGNames::widthAttr, LengthModeWidth) - , m_height(this, SVGNames::heightAttr, LengthModeHeight) - , m_rx(this, SVGNames::rxAttr, LengthModeWidth) - , m_ry(this, SVGNames::ryAttr, LengthModeHeight) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_x(LengthModeWidth) + , m_y(LengthModeHeight) + , m_width(LengthModeWidth) + , m_height(LengthModeHeight) + , m_rx(LengthModeWidth) + , m_ry(LengthModeHeight) { } @@ -99,6 +98,37 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGRectElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizeRx(); + synchronizeRy(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (attrName == SVGNames::rxAttr) + synchronizeRx(); + else if (attrName == SVGNames::ryAttr) + synchronizeRy(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + Path SVGRectElement::toPathData() const { FloatRect rect(x().value(this), y().value(this), width().value(this), height().value(this)); diff --git a/WebCore/svg/SVGRectElement.h b/WebCore/svg/SVGRectElement.h index a4d859e..df382f9 100644 --- a/WebCore/svg/SVGRectElement.h +++ b/WebCore/svg/SVGRectElement.h @@ -41,6 +41,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual Path toPathData() const; @@ -48,17 +49,15 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::heightAttrString, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::rxAttrString, SVGLength, Rx, rx) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::ryAttrString, SVGLength, Ry, ry) + DECLARE_ANIMATED_PROPERTY(SVGRectElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGRectElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGRectElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGRectElement, SVGNames::heightAttr, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY(SVGRectElement, SVGNames::rxAttr, SVGLength, Rx, rx) + DECLARE_ANIMATED_PROPERTY(SVGRectElement, SVGNames::ryAttr, SVGLength, Ry, ry) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGRectElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGRenderingIntent.idl b/WebCore/svg/SVGRenderingIntent.idl index fc21549..ff2f6ce 100644 --- a/WebCore/svg/SVGRenderingIntent.idl +++ b/WebCore/svg/SVGRenderingIntent.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGRenderingIntent { + interface [Conditional=SVG] SVGRenderingIntent { // Rendering Intent Types const unsigned short RENDERING_INTENT_UNKNOWN = 0; const unsigned short RENDERING_INTENT_AUTO = 1; diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp index 2d5008b..eed8b54 100644 --- a/WebCore/svg/SVGSVGElement.cpp +++ b/WebCore/svg/SVGSVGElement.cpp @@ -63,15 +63,13 @@ SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document* doc) , SVGExternalResourcesRequired() , SVGFitToViewBox() , SVGZoomAndPan() - , m_x(this, SVGNames::xAttr, LengthModeWidth) - , m_y(this, SVGNames::yAttr, LengthModeHeight) - , m_width(this, SVGNames::widthAttr, LengthModeWidth, "100%") - , m_height(this, SVGNames::heightAttr, LengthModeHeight, "100%") - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) - , m_viewBox(this, SVGNames::viewBoxAttr) - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) + , m_x(LengthModeWidth) + , m_y(LengthModeHeight) + , m_width(LengthModeWidth, "100%") + , m_height(LengthModeHeight, "100%") , m_useCurrentView(false) , m_timeContainer(SMILTimeContainer::create(this)) + , m_scale(1) , m_viewSpec(0) , m_containerSize(300, 150) , m_hasSetContainerSize(false) @@ -85,12 +83,6 @@ SVGSVGElement::~SVGSVGElement() // There are cases where removedFromDocument() is not called. // see ContainerNode::removeAllChildren, called by its destructor. document()->accessSVGExtensions()->removeTimeContainer(this); - - // Call detach() here because if we wait until ~Node() calls it, we crash during - // RenderSVGViewportContainer destruction, as the renderer assumes that the element - // is still fully constructed. See <https://bugs.webkit.org/show_bug.cgi?id=21293>. - if (renderer()) - detach(); } const AtomicString& SVGSVGElement::contentScriptType() const @@ -195,15 +187,22 @@ SVGViewSpec* SVGSVGElement::currentView() const float SVGSVGElement::currentScale() const { - if (document() && document()->frame()) - return document()->frame()->zoomFactor(); - return 1.0f; + if (document() && parentNode() == document()) + return document()->frame() ? document()->frame()->zoomFactor() : 1; + return m_scale; } void SVGSVGElement::setCurrentScale(float scale) { - if (document() && document()->frame()) - document()->frame()->setZoomFactor(scale, true); + if (document() && parentNode() == document()) { + if (document()->frame()) + document()->frame()->setZoomFactor(scale, true); + return; + } + + m_scale = scale; + if (renderer()) + renderer()->setNeedsLayout(true); } FloatPoint SVGSVGElement::currentTranslate() const @@ -310,6 +309,37 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +void SVGSVGElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizeExternalResourcesRequired(); + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGFitToViewBox::isKnownAttribute(attrName)) { + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + } +} + unsigned SVGSVGElement::suspendRedraw(unsigned /* maxWaitMilliseconds */) { // FIXME: Implement me (see bug 11275) @@ -374,9 +404,9 @@ SVGLength SVGSVGElement::createSVGLength() return SVGLength(); } -PassRefPtr<SVGAngle> SVGSVGElement::createSVGAngle() +SVGAngle SVGSVGElement::createSVGAngle() { - return SVGAngle::create(); + return SVGAngle(); } FloatPoint SVGSVGElement::createSVGPoint() @@ -531,13 +561,14 @@ void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) currentView()->setViewBox(viewElement->viewBox()); else currentView()->setViewBox(viewBox()); - if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) { - currentView()->preserveAspectRatio()->setAlign(viewElement->preserveAspectRatio()->align()); - currentView()->preserveAspectRatio()->setMeetOrSlice(viewElement->preserveAspectRatio()->meetOrSlice()); - } else { - currentView()->preserveAspectRatio()->setAlign(preserveAspectRatio()->align()); - currentView()->preserveAspectRatio()->setMeetOrSlice(preserveAspectRatio()->meetOrSlice()); - } + + SVGPreserveAspectRatio aspectRatio; + if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) + aspectRatio = viewElement->preserveAspectRatioBaseValue(); + else + aspectRatio = preserveAspectRatioBaseValue(); + currentView()->setPreserveAspectRatioBaseValue(aspectRatio); + if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr)) currentView()->setZoomAndPan(viewElement->zoomAndPan()); renderer()->setNeedsLayout(true); diff --git a/WebCore/svg/SVGSVGElement.h b/WebCore/svg/SVGSVGElement.h index f30e8f6..3d6f109 100644 --- a/WebCore/svg/SVGSVGElement.h +++ b/WebCore/svg/SVGSVGElement.h @@ -105,7 +105,7 @@ namespace WebCore { static float createSVGNumber(); static SVGLength createSVGLength(); - static PassRefPtr<SVGAngle> createSVGAngle(); + static SVGAngle createSVGAngle(); static FloatPoint createSVGPoint(); static TransformationMatrix createSVGMatrix(); static FloatRect createSVGRect(); @@ -125,33 +125,27 @@ namespace WebCore { virtual void removedFromDocument(); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); TransformationMatrix viewBoxToViewTransform(float viewWidth, float viewHeight) const; void inheritViewAttributes(SVGViewElement*); - protected: - friend class RenderSVGRoot; - friend class RenderSVGViewportContainer; - - virtual bool hasRelativeValues() const; - bool isOutermostSVG() const; + virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::heightAttrString, SVGLength, Height, height) + DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::heightAttr, SVGLength, Height, height) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) // SVGFitToViewBox - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGFitToViewBoxIdentifier, SVGNames::viewBoxAttrString, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGFitToViewBoxIdentifier, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) + DECLARE_ANIMATED_PROPERTY(SVGSVGElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) virtual void documentWillBecomeInactive(); virtual void documentDidBecomeActive(); @@ -159,6 +153,7 @@ namespace WebCore { bool m_useCurrentView; RefPtr<SMILTimeContainer> m_timeContainer; FloatPoint m_translation; + float m_scale; mutable OwnPtr<SVGViewSpec> m_viewSpec; IntSize m_containerSize; bool m_hasSetContainerSize; diff --git a/WebCore/svg/SVGScriptElement.cpp b/WebCore/svg/SVGScriptElement.cpp index 7be72dc..299ab8d 100644 --- a/WebCore/svg/SVGScriptElement.cpp +++ b/WebCore/svg/SVGScriptElement.cpp @@ -35,8 +35,6 @@ SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* doc, : SVGElement(tagName, doc) , SVGURIReference() , SVGExternalResourcesRequired() - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) , m_data(this, this) { m_data.setCreatedByParser(createdByParser); @@ -86,6 +84,22 @@ void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName) } } +void SVGScriptElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeExternalResourcesRequired(); + synchronizeHref(); + return; + } + + if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + void SVGScriptElement::insertedIntoDocument() { SVGElement::insertedIntoDocument(); diff --git a/WebCore/svg/SVGScriptElement.h b/WebCore/svg/SVGScriptElement.h index 699c535..396907c 100644 --- a/WebCore/svg/SVGScriptElement.h +++ b/WebCore/svg/SVGScriptElement.h @@ -45,6 +45,7 @@ namespace WebCore { virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual bool isURLAttribute(Attribute*) const; virtual void finishParsingChildren(); @@ -71,12 +72,10 @@ namespace WebCore { private: // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGScriptElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGScriptElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGScriptElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) private: ScriptElementData m_data; diff --git a/WebCore/svg/SVGStopElement.cpp b/WebCore/svg/SVGStopElement.cpp index 0549031..3c97827 100644 --- a/WebCore/svg/SVGStopElement.cpp +++ b/WebCore/svg/SVGStopElement.cpp @@ -33,7 +33,7 @@ namespace WebCore { SVGStopElement::SVGStopElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) - , m_offset(this, SVGNames::offsetAttr, 0.0f) + , m_offset(0.0f) { } @@ -55,6 +55,14 @@ void SVGStopElement::parseMappedAttribute(MappedAttribute* attr) SVGStyledElement::parseMappedAttribute(attr); } +void SVGStopElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || attrName == SVGNames::offsetAttr) + synchronizeOffset(); +} + RenderObject* SVGStopElement::createRenderer(RenderArena* arena, RenderStyle*) { return new (arena) RenderSVGGradientStop(this); diff --git a/WebCore/svg/SVGStopElement.h b/WebCore/svg/SVGStopElement.h index 5d14a40..23c09bb 100644 --- a/WebCore/svg/SVGStopElement.h +++ b/WebCore/svg/SVGStopElement.h @@ -32,6 +32,8 @@ namespace WebCore { SVGStopElement(const QualifiedName&, Document*); virtual ~SVGStopElement(); + virtual void synchronizeProperty(const QualifiedName&); + private: virtual bool isGradientStop() const { return true; } @@ -39,7 +41,7 @@ namespace WebCore { virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - ANIMATED_PROPERTY_DECLARATIONS(SVGStopElement, SVGNames::stopTagString, SVGNames::offsetAttrString, float, Offset, offset) + DECLARE_ANIMATED_PROPERTY(SVGStopElement, SVGNames::offsetAttr, float, Offset, offset) }; } // namespace WebCore diff --git a/WebCore/svg/SVGStylable.idl b/WebCore/svg/SVGStylable.idl index 731d818..2da2b77 100644 --- a/WebCore/svg/SVGStylable.idl +++ b/WebCore/svg/SVGStylable.idl @@ -27,7 +27,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGStylable { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGStylable { readonly attribute SVGAnimatedString className; readonly attribute css::CSSStyleDeclaration style; diff --git a/WebCore/svg/SVGStyleElement.cpp b/WebCore/svg/SVGStyleElement.cpp index 0a2195a..2a21670 100644 --- a/WebCore/svg/SVGStyleElement.cpp +++ b/WebCore/svg/SVGStyleElement.cpp @@ -46,40 +46,40 @@ SVGStyleElement::SVGStyleElement(const QualifiedName& tagName, Document* doc, bo const AtomicString& SVGStyleElement::type() const { DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("text/css")); - const AtomicString& n = getAttribute(typeAttr); + const AtomicString& n = getAttribute(SVGNames::typeAttr); return n.isNull() ? defaultValue : n; } void SVGStyleElement::setType(const AtomicString& type, ExceptionCode& ec) { - setAttribute(typeAttr, type, ec); + setAttribute(SVGNames::typeAttr, type, ec); } const AtomicString& SVGStyleElement::media() const { DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("all")); - const AtomicString& n = getAttribute(mediaAttr); + const AtomicString& n = getAttribute(SVGNames::mediaAttr); return n.isNull() ? defaultValue : n; } void SVGStyleElement::setMedia(const AtomicString& media, ExceptionCode& ec) { - setAttribute(mediaAttr, media, ec); + setAttribute(SVGNames::mediaAttr, media, ec); } String SVGStyleElement::title() const { - return getAttribute(titleAttr); + return getAttribute(SVGNames::titleAttr); } void SVGStyleElement::setTitle(const AtomicString& title, ExceptionCode& ec) { - setAttribute(titleAttr, title, ec); + setAttribute(SVGNames::titleAttr, title, ec); } void SVGStyleElement::parseMappedAttribute(MappedAttribute* attr) { - if (attr->name() == titleAttr && m_sheet) + if (attr->name() == SVGNames::titleAttr && m_sheet) m_sheet->setTitle(attr->value()); else { if (SVGLangSpace::parseMappedAttribute(attr)) diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp index 6960519..4228a4c 100644 --- a/WebCore/svg/SVGStyledElement.cpp +++ b/WebCore/svg/SVGStyledElement.cpp @@ -34,9 +34,12 @@ #include "RenderObject.h" #include "SVGElement.h" #include "SVGElementInstance.h" +#include "SVGElementRareData.h" #include "SVGNames.h" #include "SVGRenderStyle.h" -#include "SVGResource.h" +#include "SVGResourceClipper.h" +#include "SVGResourceFilter.h" +#include "SVGResourceMasker.h" #include "SVGSVGElement.h" #include <wtf/Assertions.h> @@ -44,12 +47,15 @@ namespace WebCore { using namespace SVGNames; -char SVGStyledElementIdentifier[] = "SVGStyledElement"; -static HashSet<const SVGStyledElement*>* gElementsWithInstanceUpdatesBlocked = 0; +void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName) +{ + int propertyId = cssPropertyID(attrName.localName()); + ASSERT(propertyId > 0); + propertyNameToIdMap->set(attrName.localName().impl(), propertyId); +} SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) - , m_className(this, HTMLNames::classAttr) { } @@ -71,13 +77,6 @@ bool SVGStyledElement::rendererIsNeeded(RenderStyle* style) return false; } -static void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName) -{ - int propertyId = cssPropertyID(attrName.localName()); - ASSERT(propertyId > 0); - propertyNameToIdMap->set(attrName.localName().impl(), propertyId); -} - int SVGStyledElement::cssPropertyIdForSVGAttributeName(const QualifiedName& attrName) { if (!attrName.namespaceURI().isNull()) @@ -92,13 +91,13 @@ int SVGStyledElement::cssPropertyIdForSVGAttributeName(const QualifiedName& attr mapAttributeToCSSProperty(propertyNameToIdMap, clipAttr); mapAttributeToCSSProperty(propertyNameToIdMap, clip_pathAttr); mapAttributeToCSSProperty(propertyNameToIdMap, clip_ruleAttr); - mapAttributeToCSSProperty(propertyNameToIdMap, colorAttr); + mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::colorAttr); mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolationAttr); mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolation_filtersAttr); mapAttributeToCSSProperty(propertyNameToIdMap, color_profileAttr); mapAttributeToCSSProperty(propertyNameToIdMap, color_renderingAttr); mapAttributeToCSSProperty(propertyNameToIdMap, cursorAttr); - mapAttributeToCSSProperty(propertyNameToIdMap, directionAttr); + mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::directionAttr); mapAttributeToCSSProperty(propertyNameToIdMap, displayAttr); mapAttributeToCSSProperty(propertyNameToIdMap, dominant_baselineAttr); mapAttributeToCSSProperty(propertyNameToIdMap, enable_backgroundAttr); @@ -176,7 +175,7 @@ void SVGStyledElement::parseMappedAttribute(MappedAttribute* attr) // style updates (instead of StyledElement::parseMappedAttribute). We don't // tell StyledElement about the change to avoid parsing the class list twice if (attrName.matches(HTMLNames::classAttr)) - setClassName(attr->value()); + setClassNameBaseValue(attr->value()); else // id is handled by StyledElement which SVGElement inherits from SVGElement::parseMappedAttribute(attr); @@ -189,7 +188,7 @@ bool SVGStyledElement::isKnownAttribute(const QualifiedName& attrName) if (propId > 0) return true; - return (attrName == HTMLNames::idAttr || attrName == HTMLNames::styleAttr); + return (attrName == idAttributeName() || attrName == HTMLNames::styleAttr); } void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName) @@ -202,10 +201,48 @@ void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName) // If we're the child of a resource element, be sure to invalidate it. invalidateResourcesInAncestorChain(); + // If the element is using resources, invalidate them. + invalidateResources(); + // Invalidate all SVGElementInstances associated with us SVGElementInstance::invalidateAllInstancesOfElement(this); } +void SVGStyledElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || attrName.matches(HTMLNames::classAttr)) + synchronizeClassName(); +} + +void SVGStyledElement::invalidateResources() +{ + RenderObject* object = renderer(); + if (!object) + return; + + const SVGRenderStyle* svgStyle = object->style()->svgStyle(); + Document* document = this->document(); + + if (document->parsing()) + return; + +#if ENABLE(FILTERS) + SVGResourceFilter* filter = getFilterById(document, svgStyle->filter(), object); + if (filter) + filter->invalidate(); +#endif + + SVGResourceMasker* masker = getMaskerById(document, svgStyle->maskElement(), object); + if (masker) + masker->invalidate(); + + SVGResourceClipper* clipper = getClipperById(document, svgStyle->clipPath(), object); + if (clipper) + clipper->invalidate(); +} + void SVGStyledElement::invalidateResourcesInAncestorChain() const { Node* node = parentNode(); @@ -215,7 +252,7 @@ void SVGStyledElement::invalidateResourcesInAncestorChain() const SVGElement* element = static_cast<SVGElement*>(node); if (SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element->isStyled() ? element : 0)) { - if (SVGResource* resource = styledElement->canvasResource()) + if (SVGResource* resource = styledElement->canvasResource(node->renderer())) resource->invalidate(); } @@ -226,8 +263,6 @@ void SVGStyledElement::invalidateResourcesInAncestorChain() const void SVGStyledElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); - if (document()->parsing()) - return; // Invalidate all SVGElementInstances associated with us SVGElementInstance::invalidateAllInstancesOfElement(this); @@ -271,19 +306,17 @@ void SVGStyledElement::detach() SVGElement::detach(); } -void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates) +bool SVGStyledElement::instanceUpdatesBlocked() const { - if (blockUpdates) { - if (!gElementsWithInstanceUpdatesBlocked) - gElementsWithInstanceUpdatesBlocked = new HashSet<const SVGStyledElement*>; - gElementsWithInstanceUpdatesBlocked->add(this); - } else { - ASSERT(gElementsWithInstanceUpdatesBlocked); - ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this)); - gElementsWithInstanceUpdatesBlocked->remove(this); - } + return hasRareSVGData() && rareSVGData()->instanceUpdatesBlocked(); } - + +void SVGStyledElement::setInstanceUpdatesBlocked(bool value) +{ + if (hasRareSVGData()) + rareSVGData()->setInstanceUpdatesBlocked(value); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGStyledElement.h b/WebCore/svg/SVGStyledElement.h index 9cc21c5..9f76c68 100644 --- a/WebCore/svg/SVGStyledElement.h +++ b/WebCore/svg/SVGStyledElement.h @@ -28,15 +28,17 @@ namespace WebCore { - extern char SVGStyledElementIdentifier[]; class SVGResource; + void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName); + class SVGStyledElement : public SVGElement, public SVGStylable { public: SVGStyledElement(const QualifiedName&, Document*); virtual ~SVGStyledElement(); - + + virtual bool hasRelativeValues() const { return false; } virtual bool isStyled() const { return true; } virtual bool supportsMarkers() const { return false; } @@ -46,30 +48,31 @@ namespace WebCore { bool isKnownAttribute(const QualifiedName&); virtual bool rendererIsNeeded(RenderStyle*); - virtual SVGResource* canvasResource() { return 0; } - + virtual SVGResource* canvasResource(const RenderObject*) { return 0; } + virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const; virtual void parseMappedAttribute(MappedAttribute*); - virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); // Centralized place to force a manual style resolution. Hacky but needed for now. PassRefPtr<RenderStyle> resolveStyle(RenderStyle* parentStyle); - void invalidateResourcesInAncestorChain() const; + void invalidateResourcesInAncestorChain() const; + void invalidateResources(); + virtual void detach(); - + + bool instanceUpdatesBlocked() const; void setInstanceUpdatesBlocked(bool); - - protected: - virtual bool hasRelativeValues() const { return true; } - + + protected: static int cssPropertyIdForSVGAttributeName(const QualifiedName&); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGStyledElement, SVGStyledElementIdentifier, HTMLNames::classAttrString, String, ClassName, className) + DECLARE_ANIMATED_PROPERTY(SVGStyledElement, HTMLNames::classAttr, String, ClassName, className) }; } // namespace WebCore diff --git a/WebCore/svg/SVGStyledTransformableElement.cpp b/WebCore/svg/SVGStyledTransformableElement.cpp index 4e97c83..6815914 100644 --- a/WebCore/svg/SVGStyledTransformableElement.cpp +++ b/WebCore/svg/SVGStyledTransformableElement.cpp @@ -33,12 +33,10 @@ namespace WebCore { -char SVGStyledTransformableElementIdentifier[] = "SVGStyledTransformableElement"; - SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* doc) : SVGStyledLocatableElement(tagName, doc) , SVGTransformable() - , m_transform(this, SVGNames::transformAttr, SVGTransformList::create(SVGNames::transformAttr)) + , m_transform(SVGTransformList::create(SVGNames::transformAttr)) { } @@ -70,20 +68,24 @@ TransformationMatrix* SVGStyledTransformableElement::supplementalTransform() void SVGStyledTransformableElement::parseMappedAttribute(MappedAttribute* attr) { - if (attr->name() == SVGNames::transformAttr) { + if (SVGTransformable::isKnownAttribute(attr->name())) { SVGTransformList* localTransforms = transformBaseValue(); - - ExceptionCode ec = 0; - localTransforms->clear(ec); - - if (!SVGTransformable::parseTransformAttribute(localTransforms, attr->value())) + if (!SVGTransformable::parseTransformAttribute(localTransforms, attr->value())) { + ExceptionCode ec = 0; localTransforms->clear(ec); - else - setTransformBaseValue(localTransforms); - } else + } + } else SVGStyledLocatableElement::parseMappedAttribute(attr); } +void SVGStyledTransformableElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledLocatableElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGTransformable::isKnownAttribute(attrName)) + synchronizeTransform(); +} + bool SVGStyledTransformableElement::isKnownAttribute(const QualifiedName& attrName) { return SVGTransformable::isKnownAttribute(attrName) || diff --git a/WebCore/svg/SVGStyledTransformableElement.h b/WebCore/svg/SVGStyledTransformableElement.h index 3145e6f..b6ab6dd 100644 --- a/WebCore/svg/SVGStyledTransformableElement.h +++ b/WebCore/svg/SVGStyledTransformableElement.h @@ -28,8 +28,6 @@ namespace WebCore { - extern char SVGStyledTransformableElementIdentifier[]; - class TransformationMatrix; class SVGStyledTransformableElement : public SVGStyledLocatableElement, @@ -51,6 +49,7 @@ namespace WebCore { virtual FloatRect getBBox() const; virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); bool isKnownAttribute(const QualifiedName&); // "base class" methods for all the elements which render as paths @@ -59,8 +58,7 @@ namespace WebCore { virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); protected: - ANIMATED_PROPERTY_DECLARATIONS(SVGStyledTransformableElement, SVGStyledTransformableElementIdentifier, - SVGNames::transformAttrString, SVGTransformList, Transform, transform) + DECLARE_ANIMATED_PROPERTY(SVGStyledTransformableElement, SVGNames::transformAttr, SVGTransformList*, Transform, transform) private: // Used by <animateMotion> diff --git a/WebCore/svg/SVGSwitchElement.cpp b/WebCore/svg/SVGSwitchElement.cpp index 6d0f5d1..3268b9a 100644 --- a/WebCore/svg/SVGSwitchElement.cpp +++ b/WebCore/svg/SVGSwitchElement.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This library is free software; you can redistribute it and/or @@ -32,7 +32,6 @@ SVGSwitchElement::SVGSwitchElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -58,8 +57,14 @@ RenderObject* SVGSwitchElement::createRenderer(RenderArena* arena, RenderStyle*) return new (arena) RenderSVGTransformableContainer(this); } +void SVGSwitchElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); } -// vim:ts=4:noet -#endif // ENABLE(SVG) +} +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGSwitchElement.h b/WebCore/svg/SVGSwitchElement.h index f5e9a0d..4d6491a 100644 --- a/WebCore/svg/SVGSwitchElement.h +++ b/WebCore/svg/SVGSwitchElement.h @@ -41,12 +41,11 @@ namespace WebCore { virtual bool childShouldCreateRenderer(Node*) const; virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + virtual void synchronizeProperty(const QualifiedName&); private: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGSwitchElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGSwitchElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGSymbolElement.cpp b/WebCore/svg/SVGSymbolElement.cpp index 6f3a644..c7edae1 100644 --- a/WebCore/svg/SVGSymbolElement.cpp +++ b/WebCore/svg/SVGSymbolElement.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This library is free software; you can redistribute it and/or @@ -32,9 +32,6 @@ SVGSymbolElement::SVGSymbolElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGFitToViewBox() - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) - , m_viewBox(this, SVGNames::viewBoxAttr) - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) { } @@ -54,8 +51,31 @@ void SVGSymbolElement::parseMappedAttribute(MappedAttribute* attr) SVGStyledElement::parseMappedAttribute(attr); } +void SVGSymbolElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizePreserveAspectRatio(); + synchronizeViewBox(); + synchronizeExternalResourcesRequired(); + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + return; + } + + if (attrName == SVGNames::preserveAspectRatioAttr) + synchronizePreserveAspectRatio(); + else if (attrName == SVGNames::viewBoxAttr) + synchronizeViewBox(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGFitToViewBox::isKnownAttribute(attrName)) { + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + } } -// vim:ts=4:noet -#endif // ENABLE(SVG) +} +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGSymbolElement.h b/WebCore/svg/SVGSymbolElement.h index 5c68202..907bf0f 100644 --- a/WebCore/svg/SVGSymbolElement.h +++ b/WebCore/svg/SVGSymbolElement.h @@ -38,19 +38,16 @@ namespace WebCore { virtual ~SVGSymbolElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual bool shouldAttachChild(Element*) const { return false; } - + virtual void synchronizeProperty(const QualifiedName&); virtual bool rendererIsNeeded(RenderStyle*) { return false; } private: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGSymbolElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGSymbolElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) // SVGFitToViewBox - ANIMATED_PROPERTY_DECLARATIONS(SVGSymbolElement, SVGFitToViewBoxIdentifier, SVGNames::viewBoxAttrString, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_DECLARATIONS(SVGSymbolElement, SVGFitToViewBoxIdentifier, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY(SVGSymbolElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) + DECLARE_ANIMATED_PROPERTY(SVGSymbolElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTRefElement.cpp b/WebCore/svg/SVGTRefElement.cpp index 1f32e90..06ae896 100644 --- a/WebCore/svg/SVGTRefElement.cpp +++ b/WebCore/svg/SVGTRefElement.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This library is free software; you can redistribute it and/or @@ -19,6 +19,7 @@ */ #include "config.h" + #if ENABLE(SVG) #include "SVGTRefElement.h" @@ -33,7 +34,6 @@ namespace WebCore { SVGTRefElement::SVGTRefElement(const QualifiedName& tagName, Document* doc) : SVGTextPositioningElement(tagName, doc) , SVGURIReference() - , m_href(this, XLinkNames::hrefAttr) { } @@ -61,6 +61,25 @@ void SVGTRefElement::parseMappedAttribute(MappedAttribute* attr) SVGTextPositioningElement::parseMappedAttribute(attr); } +void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGTextPositioningElement::svgAttributeChanged(attrName); + + if (!renderer()) + return; + + if (SVGURIReference::isKnownAttribute(attrName)) + renderer()->setNeedsLayout(true); +} + +void SVGTRefElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGTextPositioningElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + bool SVGTRefElement::childShouldCreateRenderer(Node* child) const { if (child->isTextNode() || child->hasTagName(SVGNames::tspanTag) || @@ -76,6 +95,4 @@ RenderObject* SVGTRefElement::createRenderer(RenderArena* arena, RenderStyle*) } -// vim:ts=4:noet #endif // ENABLE(SVG) - diff --git a/WebCore/svg/SVGTRefElement.h b/WebCore/svg/SVGTRefElement.h index 71d40a0..ff6eac0 100644 --- a/WebCore/svg/SVGTRefElement.h +++ b/WebCore/svg/SVGTRefElement.h @@ -34,6 +34,8 @@ namespace WebCore { virtual ~SVGTRefElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); bool childShouldCreateRenderer(Node*) const; @@ -42,7 +44,7 @@ namespace WebCore { void updateReferencedText(); // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGTRefElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGTRefElement, XLinkNames::hrefAttr, String, Href, href) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTests.idl b/WebCore/svg/SVGTests.idl index fe20a04..8a5f7c2 100644 --- a/WebCore/svg/SVGTests.idl +++ b/WebCore/svg/SVGTests.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGTests { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGTests { readonly attribute SVGStringList requiredFeatures; readonly attribute SVGStringList requiredExtensions; readonly attribute SVGStringList systemLanguage; diff --git a/WebCore/svg/SVGTextContentElement.cpp b/WebCore/svg/SVGTextContentElement.cpp index 9334304..167d241 100644 --- a/WebCore/svg/SVGTextContentElement.cpp +++ b/WebCore/svg/SVGTextContentElement.cpp @@ -43,16 +43,13 @@ namespace WebCore { -char SVGTextContentElementIdentifier[] = "SVGTextContentElement"; - SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_textLength(this, SVGNames::textLengthAttr, LengthModeOther) - , m_lengthAdjust(this, SVGNames::lengthAdjustAttr, LENGTHADJUST_SPACING) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_textLength(LengthModeOther) + , m_lengthAdjust(LENGTHADJUST_SPACING) { } @@ -517,6 +514,25 @@ void SVGTextContentElement::parseMappedAttribute(MappedAttribute* attr) } } +void SVGTextContentElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeLengthAdjust(); + synchronizeTextLength(); + synchronizeExternalResourcesRequired(); + return; + } + + if (attrName == SVGNames::lengthAdjustAttr) + synchronizeLengthAdjust(); + else if (attrName == SVGNames::textLengthAttr) + synchronizeTextLength(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); +} + bool SVGTextContentElement::isKnownAttribute(const QualifiedName& attrName) { return (attrName.matches(SVGNames::lengthAdjustAttr) || diff --git a/WebCore/svg/SVGTextContentElement.h b/WebCore/svg/SVGTextContentElement.h index 9b2c938..7dff3d5 100644 --- a/WebCore/svg/SVGTextContentElement.h +++ b/WebCore/svg/SVGTextContentElement.h @@ -29,8 +29,6 @@ namespace WebCore { - extern char SVGTextContentElementIdentifier[]; - class SVGLength; class SVGTextContentElement : public SVGStyledElement, @@ -61,17 +59,16 @@ namespace WebCore { void selectSubString(unsigned charnum, unsigned nchars, ExceptionCode&) const; virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); bool isKnownAttribute(const QualifiedName&); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGTextContentElement, SVGTextContentElementIdentifier, SVGNames::textLengthAttrString, SVGLength, TextLength, textLength) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextContentElement, SVGTextContentElementIdentifier, SVGNames::lengthAdjustAttrString, int, LengthAdjust, lengthAdjust) + DECLARE_ANIMATED_PROPERTY(SVGTextContentElement, SVGNames::textLengthAttr, SVGLength, TextLength, textLength) + DECLARE_ANIMATED_PROPERTY(SVGTextContentElement, SVGNames::lengthAdjustAttr, int, LengthAdjust, lengthAdjust) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGTextContentElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGTextContentElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTextContentElement.idl b/WebCore/svg/SVGTextContentElement.idl index 394b398..9cf1748 100644 --- a/WebCore/svg/SVGTextContentElement.idl +++ b/WebCore/svg/SVGTextContentElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGTextContentElement : SVGElement, + interface [Conditional=SVG] SVGTextContentElement : SVGElement, SVGTests, SVGLangSpace, SVGExternalResourcesRequired, diff --git a/WebCore/svg/SVGTextElement.cpp b/WebCore/svg/SVGTextElement.cpp index c1481cf..7de34fe 100644 --- a/WebCore/svg/SVGTextElement.cpp +++ b/WebCore/svg/SVGTextElement.cpp @@ -37,7 +37,7 @@ namespace WebCore { SVGTextElement::SVGTextElement(const QualifiedName& tagName, Document* doc) : SVGTextPositioningElement(tagName, doc) , SVGTransformable() - , m_transform(this, SVGNames::transformAttr, SVGTransformList::create(SVGNames::transformAttr)) + , m_transform(SVGTransformList::create(SVGNames::transformAttr)) { } @@ -47,18 +47,11 @@ SVGTextElement::~SVGTextElement() void SVGTextElement::parseMappedAttribute(MappedAttribute* attr) { - if (attr->name() == SVGNames::transformAttr) { + if (SVGTransformable::isKnownAttribute(attr->name())) { SVGTransformList* localTransforms = transformBaseValue(); - - ExceptionCode ec = 0; - localTransforms->clear(ec); - - if (!SVGTransformable::parseTransformAttribute(localTransforms, attr->value())) + if (!SVGTransformable::parseTransformAttribute(localTransforms, attr->value())) { + ExceptionCode ec = 0; localTransforms->clear(ec); - else { - setTransformBaseValue(localTransforms); - if (renderer()) - renderer()->setNeedsLayout(true); // should be in setTransformBaseValue } } else SVGTextPositioningElement::parseMappedAttribute(attr); @@ -124,10 +117,28 @@ void SVGTextElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer()) return; - if (SVGTextPositioningElement::isKnownAttribute(attrName)) + if (SVGTransformable::isKnownAttribute(attrName)) renderer()->setNeedsLayout(true); } +void SVGTextElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGTextPositioningElement::synchronizeProperty(attrName); + + if (attrName == anyQName() || SVGTransformable::isKnownAttribute(attrName)) + synchronizeTransform(); +} + +void SVGTextElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +{ + SVGTextPositioningElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + + if (!renderer()) + return; + + renderer()->setNeedsLayout(true); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTextElement.h b/WebCore/svg/SVGTextElement.h index 400aa47..217964a 100644 --- a/WebCore/svg/SVGTextElement.h +++ b/WebCore/svg/SVGTextElement.h @@ -48,9 +48,11 @@ namespace WebCore { virtual bool childShouldCreateRenderer(Node*) const; virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGTextElement, SVGNames::textTagString, SVGNames::transformAttrString, SVGTransformList, Transform, transform) + DECLARE_ANIMATED_PROPERTY(SVGTextElement, SVGNames::transformAttr, SVGTransformList*, Transform, transform) // Used by <animateMotion> OwnPtr<TransformationMatrix> m_supplementalTransform; diff --git a/WebCore/svg/SVGTextPathElement.cpp b/WebCore/svg/SVGTextPathElement.cpp index 8a01ad9..eec6fc8 100644 --- a/WebCore/svg/SVGTextPathElement.cpp +++ b/WebCore/svg/SVGTextPathElement.cpp @@ -36,10 +36,9 @@ namespace WebCore { SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Document* doc) : SVGTextContentElement(tagName, doc) , SVGURIReference() - , m_startOffset(this, SVGNames::startOffsetAttr, LengthModeOther) - , m_method(this, SVGNames::methodAttr, SVG_TEXTPATH_METHODTYPE_ALIGN) - , m_spacing(this, SVGNames::spacingAttr, SVG_TEXTPATH_SPACINGTYPE_EXACT) - , m_href(this, XLinkNames::hrefAttr) + , m_startOffset(LengthModeOther) + , m_method(SVG_TEXTPATH_METHODTYPE_ALIGN) + , m_spacing(SVG_TEXTPATH_SPACINGTYPE_EXACT) { } @@ -70,6 +69,28 @@ void SVGTextPathElement::parseMappedAttribute(MappedAttribute* attr) } } +void SVGTextPathElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGTextContentElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeStartOffset(); + synchronizeMethod(); + synchronizeSpacing(); + synchronizeHref(); + return; + } + + if (attrName == SVGNames::startOffsetAttr) + synchronizeStartOffset(); + else if (attrName == SVGNames::methodAttr) + synchronizeMethod(); + else if (attrName == SVGNames::spacingAttr) + synchronizeSpacing(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} + RenderObject* SVGTextPathElement::createRenderer(RenderArena* arena, RenderStyle*) { return new (arena) RenderSVGTextPath(this); @@ -102,5 +123,3 @@ void SVGTextPathElement::insertedIntoDocument() } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTextPathElement.h b/WebCore/svg/SVGTextPathElement.h index 1bfcc8b..ff09ed2 100644 --- a/WebCore/svg/SVGTextPathElement.h +++ b/WebCore/svg/SVGTextPathElement.h @@ -57,18 +57,19 @@ namespace WebCore { virtual void insertedIntoDocument(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); virtual bool rendererIsNeeded(RenderStyle* style) { return StyledElement::rendererIsNeeded(style); } virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); bool childShouldCreateRenderer(Node*) const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGNames::textPathTagString, SVGNames::startOffsetAttrString, SVGLength, StartOffset, startOffset) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGNames::textPathTagString, SVGNames::methodAttrString, int, Method, method) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGNames::textPathTagString, SVGNames::spacingAttrString, int, Spacing, spacing) + DECLARE_ANIMATED_PROPERTY(SVGTextPathElement, SVGNames::startOffsetAttr, SVGLength, StartOffset, startOffset) + DECLARE_ANIMATED_PROPERTY(SVGTextPathElement, SVGNames::methodAttr, int, Method, method) + DECLARE_ANIMATED_PROPERTY(SVGTextPathElement, SVGNames::spacingAttr, int, Spacing, spacing) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGTextPathElement, XLinkNames::hrefAttr, String, Href, href) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTextPathElement.idl b/WebCore/svg/SVGTextPathElement.idl index 0183def..511f792 100644 --- a/WebCore/svg/SVGTextPathElement.idl +++ b/WebCore/svg/SVGTextPathElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGTextPathElement : SVGTextContentElement, + interface [Conditional=SVG] SVGTextPathElement : SVGTextContentElement, SVGURIReference { // textPath Method Types const unsigned short TEXTPATH_METHODTYPE_UNKNOWN = 0; diff --git a/WebCore/svg/SVGTextPositioningElement.cpp b/WebCore/svg/SVGTextPositioningElement.cpp index fd7c8aa..dd99b49 100644 --- a/WebCore/svg/SVGTextPositioningElement.cpp +++ b/WebCore/svg/SVGTextPositioningElement.cpp @@ -24,21 +24,20 @@ #include "SVGTextPositioningElement.h" #include "MappedAttribute.h" +#include "RenderObject.h" #include "SVGLengthList.h" #include "SVGNames.h" #include "SVGNumberList.h" namespace WebCore { -char SVGTextPositioningElementIdentifier[] = "SVGTextPositioningElement"; - SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document* doc) : SVGTextContentElement(tagName, doc) - , m_x(this, SVGNames::xAttr, SVGLengthList::create(SVGNames::xAttr)) - , m_y(this, SVGNames::yAttr, SVGLengthList::create(SVGNames::yAttr)) - , m_dx(this, SVGNames::dxAttr, SVGLengthList::create(SVGNames::dxAttr)) - , m_dy(this, SVGNames::dyAttr, SVGLengthList::create(SVGNames::dyAttr)) - , m_rotate(this, SVGNames::rotateAttr, SVGNumberList::create(SVGNames::rotateAttr)) + , m_x(SVGLengthList::create(SVGNames::xAttr)) + , m_y(SVGLengthList::create(SVGNames::yAttr)) + , m_dx(SVGLengthList::create(SVGNames::dxAttr)) + , m_dy(SVGLengthList::create(SVGNames::dyAttr)) + , m_rotate(SVGNumberList::create(SVGNames::rotateAttr)) { } @@ -62,6 +61,42 @@ void SVGTextPositioningElement::parseMappedAttribute(MappedAttribute* attr) SVGTextContentElement::parseMappedAttribute(attr); } +void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGTextContentElement::svgAttributeChanged(attrName); + + if (!renderer()) + return; + + if (isKnownAttribute(attrName)) + renderer()->setNeedsLayout(true); +} + +void SVGTextPositioningElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGTextContentElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeDx(); + synchronizeDy(); + synchronizeRotate(); + return; + } + + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::dxAttr) + synchronizeDx(); + else if (attrName == SVGNames::dyAttr) + synchronizeDy(); + else if (attrName == SVGNames::rotateAttr) + synchronizeRotate(); +} + bool SVGTextPositioningElement::isKnownAttribute(const QualifiedName& attrName) { return (attrName.matches(SVGNames::xAttr) || diff --git a/WebCore/svg/SVGTextPositioningElement.h b/WebCore/svg/SVGTextPositioningElement.h index 2b07d09..71e8900 100644 --- a/WebCore/svg/SVGTextPositioningElement.h +++ b/WebCore/svg/SVGTextPositioningElement.h @@ -28,23 +28,23 @@ namespace WebCore { - extern char SVGTextPositioningElementIdentifier[]; - class SVGTextPositioningElement : public SVGTextContentElement { public: SVGTextPositioningElement(const QualifiedName&, Document*); virtual ~SVGTextPositioningElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void svgAttributeChanged(const QualifiedName&); + virtual void synchronizeProperty(const QualifiedName&); bool isKnownAttribute(const QualifiedName&); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::xAttrString, SVGLengthList, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::yAttrString, SVGLengthList, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::dxAttrString, SVGLengthList, Dx, dx) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::dyAttrString, SVGLengthList, Dy, dy) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::rotateAttrString, SVGNumberList, Rotate, rotate) + DECLARE_ANIMATED_PROPERTY(SVGTextPositioningElement, SVGNames::xAttr, SVGLengthList*, X, x) + DECLARE_ANIMATED_PROPERTY(SVGTextPositioningElement, SVGNames::yAttr, SVGLengthList*, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGTextPositioningElement, SVGNames::dxAttr, SVGLengthList*, Dx, dx) + DECLARE_ANIMATED_PROPERTY(SVGTextPositioningElement, SVGNames::dyAttr, SVGLengthList*, Dy, dy) + DECLARE_ANIMATED_PROPERTY(SVGTextPositioningElement, SVGNames::rotateAttr, SVGNumberList*, Rotate, rotate) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTransform.h b/WebCore/svg/SVGTransform.h index 1e15468..aad7a60 100644 --- a/WebCore/svg/SVGTransform.h +++ b/WebCore/svg/SVGTransform.h @@ -54,7 +54,6 @@ namespace WebCore { float angle() const; FloatPoint rotationCenter() const; -// void setMatrix(const TransformationMatrix&); void setMatrix(TransformationMatrix); void setTranslate(float tx, float ty); @@ -69,9 +68,6 @@ namespace WebCore { bool isValid(); - // Throughout SVG 1.1 'SVGTransform' is only used for the 'transform' attribute - const QualifiedName& associatedAttributeName() const { return SVGNames::transformAttr; } - private: SVGTransformType m_type; float m_angle; @@ -93,5 +89,3 @@ namespace WebCore { #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTransform.idl b/WebCore/svg/SVGTransform.idl index 0fd3a1e..fc153a7 100644 --- a/WebCore/svg/SVGTransform.idl +++ b/WebCore/svg/SVGTransform.idl @@ -21,7 +21,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor, PODType=SVGTransform] SVGTransform { + interface [Conditional=SVG, PODType=SVGTransform] SVGTransform { // Transform Types const unsigned short SVG_TRANSFORM_UNKNOWN = 0; const unsigned short SVG_TRANSFORM_MATRIX = 1; diff --git a/WebCore/svg/SVGTransformList.idl b/WebCore/svg/SVGTransformList.idl index 8c9c86e..d03351a 100644 --- a/WebCore/svg/SVGTransformList.idl +++ b/WebCore/svg/SVGTransformList.idl @@ -29,19 +29,19 @@ module svg { interface [Conditional=SVG] SVGTransformList { readonly attribute unsigned long numberOfItems; - [JSCCustom] void clear() + void clear() raises(DOMException); - [JSCCustom] SVGTransform initialize(in SVGTransform item) + SVGTransform initialize(in SVGTransform item) raises(DOMException, SVGException); - [JSCCustom] SVGTransform getItem(in unsigned long index) + SVGTransform getItem(in unsigned long index) raises(DOMException); - [JSCCustom] SVGTransform insertItemBefore(in SVGTransform item, in unsigned long index) + SVGTransform insertItemBefore(in SVGTransform item, in unsigned long index) raises(DOMException, SVGException); - [JSCCustom] SVGTransform replaceItem(in SVGTransform item, in unsigned long index) + SVGTransform replaceItem(in SVGTransform item, in unsigned long index) raises(DOMException, SVGException); - [JSCCustom] SVGTransform removeItem(in unsigned long index) + SVGTransform removeItem(in unsigned long index) raises(DOMException); - [JSCCustom] SVGTransform appendItem(in SVGTransform item) + SVGTransform appendItem(in SVGTransform item) raises(DOMException, SVGException); SVGTransform createSVGTransformFromMatrix(in SVGMatrix matrix); SVGTransform consolidate(); diff --git a/WebCore/svg/SVGTransformable.cpp b/WebCore/svg/SVGTransformable.cpp index 17344ea..78afbc8 100644 --- a/WebCore/svg/SVGTransformable.cpp +++ b/WebCore/svg/SVGTransformable.cpp @@ -190,18 +190,23 @@ static inline bool parseAndSkipType(const UChar*& currTransform, const UChar* en bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const AtomicString& transform) { const UChar* start = transform.characters(); - const UChar* end = start + transform.length(); - return parseTransformAttribute(list, start, end); + return parseTransformAttribute(list, start, start + transform.length()); } -bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const UChar*& currTransform, const UChar* end) +bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const UChar*& currTransform, const UChar* end, TransformParsingMode mode) { + ExceptionCode ec = 0; + if (mode == ClearList) { + list->clear(ec); + ASSERT(!ec); + } + bool delimParsed = false; while (currTransform < end) { delimParsed = false; unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN; skipOptionalSpaces(currTransform, end); - + if (!parseAndSkipType(currTransform, end, type)) return false; @@ -209,12 +214,11 @@ bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const UCh if (!parseTransformValue(type, currTransform, end, t)) return false; - ExceptionCode ec = 0; list->appendItem(t, ec); skipOptionalSpaces(currTransform, end); if (currTransform < end && *currTransform == ',') { delimParsed = true; - currTransform++; + ++currTransform; } skipOptionalSpaces(currTransform, end); } diff --git a/WebCore/svg/SVGTransformable.h b/WebCore/svg/SVGTransformable.h index 1e87b78..a74eff7 100644 --- a/WebCore/svg/SVGTransformable.h +++ b/WebCore/svg/SVGTransformable.h @@ -38,8 +38,13 @@ namespace WebCore { SVGTransformable(); virtual ~SVGTransformable(); + enum TransformParsingMode { + ClearList, + DoNotClearList + }; + static bool parseTransformAttribute(SVGTransformList*, const AtomicString& transform); - static bool parseTransformAttribute(SVGTransformList*, const UChar*& ptr, const UChar* end); + static bool parseTransformAttribute(SVGTransformList*, const UChar*& ptr, const UChar* end, TransformParsingMode mode = ClearList); static bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform&); TransformationMatrix getCTM(const SVGElement*) const; diff --git a/WebCore/svg/SVGTransformable.idl b/WebCore/svg/SVGTransformable.idl index 02a4336..13a4520 100644 --- a/WebCore/svg/SVGTransformable.idl +++ b/WebCore/svg/SVGTransformable.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGTransformable : SVGLocatable { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGTransformable : SVGLocatable { readonly attribute SVGAnimatedTransformList transform; }; diff --git a/WebCore/svg/SVGURIReference.cpp b/WebCore/svg/SVGURIReference.cpp index 24febc3..5fe71ab 100644 --- a/WebCore/svg/SVGURIReference.cpp +++ b/WebCore/svg/SVGURIReference.cpp @@ -27,8 +27,6 @@ namespace WebCore { -char SVGURIReferenceIdentifier[] = "SVGURIReference"; - SVGURIReference::SVGURIReference() { } diff --git a/WebCore/svg/SVGURIReference.h b/WebCore/svg/SVGURIReference.h index 7f91b72..ea09f2e 100644 --- a/WebCore/svg/SVGURIReference.h +++ b/WebCore/svg/SVGURIReference.h @@ -27,7 +27,6 @@ namespace WebCore { - extern char SVGURIReferenceIdentifier[]; class MappedAttribute; class SVGURIReference { @@ -41,7 +40,7 @@ namespace WebCore { static String getTarget(const String& url); protected: - virtual void setHrefBaseValue(SVGAnimatedTypeValue<String>::DecoratedType type) = 0; + virtual void setHrefBaseValue(SVGAnimatedPropertyTraits<String>::PassType) = 0; }; } // namespace WebCore diff --git a/WebCore/svg/SVGURIReference.idl b/WebCore/svg/SVGURIReference.idl index 72bd9c8..4981eb1 100644 --- a/WebCore/svg/SVGURIReference.idl +++ b/WebCore/svg/SVGURIReference.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, ObjCProtocol] SVGURIReference { + interface [Conditional=SVG, ObjCProtocol, OmitConstructor] SVGURIReference { readonly attribute SVGAnimatedString href; }; diff --git a/WebCore/svg/SVGUnitTypes.idl b/WebCore/svg/SVGUnitTypes.idl index 0c3791e..9095e7a 100644 --- a/WebCore/svg/SVGUnitTypes.idl +++ b/WebCore/svg/SVGUnitTypes.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor] SVGUnitTypes { + interface [Conditional=SVG] SVGUnitTypes { // Unit Types const unsigned short SVG_UNIT_TYPE_UNKNOWN = 0; const unsigned short SVG_UNIT_TYPE_USERSPACEONUSE = 1; diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp index a566992..2ce1bd1 100644 --- a/WebCore/svg/SVGUseElement.cpp +++ b/WebCore/svg/SVGUseElement.cpp @@ -1,7 +1,7 @@ /* Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - Copyright (C) Research In Motion Limited 2009. All rights reserved. + Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -33,12 +33,13 @@ #include "MappedAttribute.h" #include "NodeRenderStyle.h" #include "RegisteredEventListener.h" -#include "RenderSVGTransformableContainer.h" +#include "RenderSVGShadowTreeRootContainer.h" #include "SVGElementInstance.h" #include "SVGElementInstanceList.h" #include "SVGGElement.h" #include "SVGLength.h" #include "SVGPreserveAspectRatio.h" +#include "SVGShadowTreeElements.h" #include "SVGSMILElement.h" #include "SVGSVGElement.h" #include "SVGSymbolElement.h" @@ -59,12 +60,12 @@ SVGUseElement::SVGUseElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGURIReference() - , m_x(this, SVGNames::xAttr, LengthModeWidth) - , m_y(this, SVGNames::yAttr, LengthModeHeight) - , m_width(this, SVGNames::widthAttr, LengthModeWidth) - , m_height(this, SVGNames::heightAttr, LengthModeHeight) - , m_href(this, XLinkNames::hrefAttr) - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) + , m_x(LengthModeWidth) + , m_y(LengthModeHeight) + , m_width(LengthModeWidth) + , m_height(LengthModeHeight) + , m_isPendingResource(false) + , m_needsShadowTreeRecreation(false) { } @@ -74,6 +75,13 @@ SVGUseElement::~SVGUseElement() SVGElementInstance* SVGUseElement::instanceRoot() const { + // If there is no element instance tree, force immediate SVGElementInstance tree + // creation by asking the document to invoke our recalcStyle function - as we can't + // wait for the lazy creation to happen if e.g. JS wants to access the instanceRoot + // object right after creating the element on-the-fly + if (!m_targetElementInstance) + document()->updateLayoutIgnorePendingStylesheets(); + return m_targetElementInstance.get(); } @@ -112,14 +120,15 @@ void SVGUseElement::parseMappedAttribute(MappedAttribute* attr) void SVGUseElement::insertedIntoDocument() { + // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied. SVGElement::insertedIntoDocument(); - buildPendingResource(); + ASSERT(!m_targetElementInstance); + ASSERT(!m_isPendingResource); } void SVGUseElement::removedFromDocument() { m_targetElementInstance = 0; - m_shadowTreeRootElement = 0; SVGElement::removedFromDocument(); } @@ -127,87 +136,198 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { SVGStyledTransformableElement::svgAttributeChanged(attrName); - if (!attached()) + if (!renderer()) return; - if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || - attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || - SVGTests::isKnownAttribute(attrName) || - SVGLangSpace::isKnownAttribute(attrName) || - SVGExternalResourcesRequired::isKnownAttribute(attrName) || - SVGURIReference::isKnownAttribute(attrName) || - SVGStyledTransformableElement::isKnownAttribute(attrName)) { - buildPendingResource(); - - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->setNeedsStyleRecalc(); + if (SVGURIReference::isKnownAttribute(attrName)) { + if (m_isPendingResource) { + document()->accessSVGExtensions()->removePendingResource(m_resourceId); + m_resourceId = String(); + m_isPendingResource = false; + } + + invalidateShadowTree(); + return; + } + + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { + updateContainerOffsets(); + return; + } + + if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { + updateContainerSizes(); + return; + } + + // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree! + if (SVGStyledElement::isKnownAttribute(attrName)) { + setNeedsStyleRecalc(); + return; + } + + if (SVGTests::isKnownAttribute(attrName) + || SVGLangSpace::isKnownAttribute(attrName) + || SVGExternalResourcesRequired::isKnownAttribute(attrName) + || SVGStyledTransformableElement::isKnownAttribute(attrName)) { + invalidateShadowTree(); } } -void SVGUseElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +void SVGUseElement::synchronizeProperty(const QualifiedName& attrName) { - SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + SVGStyledTransformableElement::synchronizeProperty(attrName); - if (!attached()) + if (attrName == anyQName()) { + synchronizeX(); + synchronizeY(); + synchronizeWidth(); + synchronizeHeight(); + synchronizeExternalResourcesRequired(); + synchronizeHref(); return; + } - buildPendingResource(); + if (attrName == SVGNames::xAttr) + synchronizeX(); + else if (attrName == SVGNames::yAttr) + synchronizeY(); + else if (attrName == SVGNames::widthAttr) + synchronizeWidth(); + else if (attrName == SVGNames::heightAttr) + synchronizeHeight(); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGURIReference::isKnownAttribute(attrName)) + synchronizeHref(); +} - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->setNeedsStyleRecalc(); +static void updateContainerSize(SVGUseElement* useElement, SVGElementInstance* targetInstance) +{ + // Depth-first used to write the method in early exit style, no particular other reason. + for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) + updateContainerSize(useElement, instance); + + SVGElement* correspondingElement = targetInstance->correspondingElement(); + ASSERT(correspondingElement); + + bool isSymbolTag = correspondingElement->hasTagName(SVGNames::symbolTag); + if (!correspondingElement->hasTagName(SVGNames::svgTag) && !isSymbolTag) + return; + + SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); + ASSERT(shadowTreeElement); + ASSERT(shadowTreeElement->hasTagName(SVGNames::svgTag)); + + // Spec (<use> on <symbol>): This generated 'svg' will always have explicit values for attributes width and height. + // If attributes width and/or height are provided on the 'use' element, then these attributes + // will be transferred to the generated 'svg'. If attributes width and/or height are not specified, + // the generated 'svg' element will use values of 100% for these attributes. + + // Spec (<use> on <svg>): If attributes width and/or height are provided on the 'use' element, then these + // values will override the corresponding attributes on the 'svg' in the generated tree. + + if (useElement->hasAttribute(SVGNames::widthAttr)) + shadowTreeElement->setAttribute(SVGNames::widthAttr, useElement->getAttribute(SVGNames::widthAttr)); + else if (isSymbolTag && shadowTreeElement->hasAttribute(SVGNames::widthAttr)) + shadowTreeElement->setAttribute(SVGNames::widthAttr, "100%"); + + if (useElement->hasAttribute(SVGNames::heightAttr)) + shadowTreeElement->setAttribute(SVGNames::heightAttr, useElement->getAttribute(SVGNames::heightAttr)); + else if (isSymbolTag && shadowTreeElement->hasAttribute(SVGNames::heightAttr)) + shadowTreeElement->setAttribute(SVGNames::heightAttr, "100%"); +} + +void SVGUseElement::updateContainerSizes() +{ + if (!m_targetElementInstance) + return; + + // Update whole subtree, scanning for shadow container elements, that correspond to <svg>/<symbol> tags + updateContainerSize(this, m_targetElementInstance.get()); + + if (renderer()) + renderer()->setNeedsLayout(true); } - -static bool shadowTreeContainsChangedNodes(SVGElementInstance* target) + +static void updateContainerOffset(SVGElementInstance* targetInstance) { - if (!target) // when use is referencing an non-existing element, there will be no Instance tree built - return false; + // Depth-first used to write the method in early exit style, no particular other reason. + for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) + updateContainerOffset(instance); - if (target->needsUpdate()) - return true; + SVGElement* correspondingElement = targetInstance->correspondingElement(); + ASSERT(correspondingElement); - for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling()) - if (shadowTreeContainsChangedNodes(instance)) - return true; + if (!correspondingElement->hasTagName(SVGNames::useTag)) + return; - return false; + SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); + ASSERT(shadowTreeElement); + ASSERT(shadowTreeElement->hasTagName(SVGNames::gTag)); + + if (!static_cast<SVGGElement*>(shadowTreeElement)->isShadowTreeContainerElement()) + return; + + // Spec: An additional transformation translate(x,y) is appended to the end + // (i.e., right-side) of the transform attribute on the generated 'g', where x + // and y represent the values of the x and y attributes on the 'use' element. + SVGUseElement* useElement = static_cast<SVGUseElement*>(correspondingElement); + SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(shadowTreeElement); + containerElement->setContainerOffset(useElement->x(), useElement->y()); } -void SVGUseElement::recalcStyle(StyleChange change) +void SVGUseElement::updateContainerOffsets() { - if (attached() && needsStyleRecalc() && shadowTreeContainsChangedNodes(m_targetElementInstance.get())) { - buildPendingResource(); + if (!m_targetElementInstance) + return; + + // Update root container offset (not reachable through instance tree) + SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement(); + ASSERT(shadowRoot); - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->setNeedsStyleRecalc(); + Node* parentNode = shadowRoot->parentNode(); + ASSERT(parentNode); + ASSERT(parentNode->isSVGElement()); + ASSERT(parentNode->hasTagName(SVGNames::gTag)); + ASSERT(static_cast<SVGGElement*>(parentNode)->isShadowTreeContainerElement()); + + SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(parentNode); + containerElement->setContainerOffset(x(), y()); + + // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree + updateContainerOffset(m_targetElementInstance.get()); + + if (renderer()) + renderer()->setNeedsLayout(true); +} + +void SVGUseElement::recalcStyle(StyleChange change) +{ + // Eventually mark shadow root element needing style recalc + if (needsStyleRecalc() && m_targetElementInstance) { + if (SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement()) + shadowRoot->setNeedsStyleRecalc(); } - SVGStyledElement::recalcStyle(change); + SVGStyledTransformableElement::recalcStyle(change); + + bool needsStyleUpdate = !m_needsShadowTreeRecreation; + if (m_needsShadowTreeRecreation) { + static_cast<RenderSVGShadowTreeRootContainer*>(renderer())->markShadowTreeForRecreation(); + m_needsShadowTreeRecreation = false; + } - // The shadow tree root element is NOT a direct child element of us. - // So we have to take care it receives style updates, manually. - if (!m_shadowTreeRootElement || !m_shadowTreeRootElement->attached()) + RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer()); + if (!shadowRoot) return; - // Mimic Element::recalcStyle(). The main difference is that we don't call attach() on the - // shadow tree root element, but call attachShadowTree() here. Calling attach() will crash - // as the shadow tree root element has no (direct) parent node. Yes, shadow trees are tricky. - if (change >= Inherit || m_shadowTreeRootElement->needsStyleRecalc()) { - RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(m_shadowTreeRootElement.get()); - StyleChange ch = Node::diff(m_shadowTreeRootElement->renderStyle(), newStyle.get()); - if (ch == Detach) { - ASSERT(m_shadowTreeRootElement->attached()); - m_shadowTreeRootElement->detach(); - attachShadowTree(); - - // attach recalulates the style for all children. No need to do it twice. - m_shadowTreeRootElement->setNeedsStyleRecalc(NoStyleChange); - m_shadowTreeRootElement->setChildNeedsStyleRecalc(false); - return; - } - } + shadowRoot->updateFromElement(); - // Only change==Detach needs special treatment, for anything else recalcStyle() works. - m_shadowTreeRootElement->recalcStyle(change); + if (!needsStyleUpdate) + return; + + shadowRoot->updateStyle(change); } #ifdef DUMP_INSTANCE_TREE @@ -216,26 +336,30 @@ void dumpInstanceTree(unsigned int& depth, String& text, SVGElementInstance* tar SVGElement* element = targetInstance->correspondingElement(); ASSERT(element); + SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); + ASSERT(shadowTreeElement); + String elementId = element->getIDAttribute(); String elementNodeName = element->nodeName(); + String shadowTreeElementNodeName = shadowTreeElement->nodeName(); String parentNodeName = element->parentNode() ? element->parentNode()->nodeName() : "null"; String firstChildNodeName = element->firstChild() ? element->firstChild()->nodeName() : "null"; for (unsigned int i = 0; i < depth; ++i) text += " "; - text += String::format("SVGElementInstance this=%p, (parentNode=%s, firstChild=%s, correspondingElement=%s (%p), shadowTreeElement=%p, id=%s)\n", - targetInstance, parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(), - element, targetInstance->shadowTreeElement(), elementId.latin1().data()); + text += String::format("SVGElementInstance this=%p, (parentNode=%s (%p), firstChild=%s (%p), correspondingElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n", + targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(), + elementNodeName.latin1().data(), element, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data()); for (unsigned int i = 0; i < depth; ++i) text += " "; - HashSet<SVGElementInstance*> elementInstances = element->instancesForElement(); + const HashSet<SVGElementInstance*>& elementInstances = element->instancesForElement(); text += String::format("Corresponding element is associated with %i instance(s):\n", elementInstances.size()); - HashSet<SVGElementInstance*>::iterator end = elementInstances.end(); - for (HashSet<SVGElementInstance*>::iterator it = elementInstances.begin(); it != end; ++it) { + const HashSet<SVGElementInstance*>::const_iterator end = elementInstances.end(); + for (HashSet<SVGElementInstance*>::const_iterator it = elementInstances.begin(); it != end; ++it) { for (unsigned int i = 0; i < depth; ++i) text += " "; @@ -282,16 +406,36 @@ static bool subtreeContainsDisallowedElement(Node* start) void SVGUseElement::buildPendingResource() { + // If we're called the first time (during shadow tree root creation from RenderSVGShadowTreeRootContainer) + // we either determine that our target is available or not - then we add ourselves to the pending resource list + // Once the pending resource appears, it will call buildPendingResource(), so we're called a second time. String id = SVGURIReference::getTarget(href()); Element* targetElement = document()->getElementById(id); + ASSERT(!m_targetElementInstance); if (!targetElement) { - // TODO: We want to deregister as pending resource, if our href() changed! - // TODO: Move to svgAttributeChanged, once we're fixing use & the new dynamic update concept. + if (m_isPendingResource) + return; + + m_isPendingResource = true; + m_resourceId = id; document()->accessSVGExtensions()->addPendingResource(id, this); return; } + if (m_isPendingResource) { + ASSERT(!m_targetElementInstance); + m_isPendingResource = false; + invalidateShadowTree(); + } +} + +void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowRoot) +{ + String id = SVGURIReference::getTarget(href()); + Element* targetElement = document()->getElementById(id); + ASSERT(targetElement); + // Do not build the shadow/instance tree for <use> elements living in a shadow tree. // The will be expanded soon anyway - see expandUseElementsInShadowTree(). Node* parent = parentNode(); @@ -306,17 +450,13 @@ void SVGUseElement::buildPendingResource() if (targetElement && targetElement->isSVGElement()) target = static_cast<SVGElement*>(targetElement); - if (m_targetElementInstance) { - m_targetElementInstance->forgetWrapper(); + if (m_targetElementInstance) m_targetElementInstance = 0; - } // Do not allow self-referencing. // 'target' may be null, if it's a non SVG namespaced element. - if (!target || target == this) { - m_shadowTreeRootElement = 0; + if (!target || target == this) return; - } // Why a seperated instance/shadow tree? SVG demands it: // The instance tree is accesable from JavaScript, and has to @@ -338,45 +478,44 @@ void SVGUseElement::buildPendingResource() // Non-appearing <use> content is easier to debug, then half-appearing content. if (foundProblem) { m_targetElementInstance = 0; - m_shadowTreeRootElement = 0; return; } // Assure instance tree building was successfull ASSERT(m_targetElementInstance); + ASSERT(!m_targetElementInstance->shadowTreeElement()); ASSERT(m_targetElementInstance->correspondingUseElement() == this); - - // Setup shadow tree root node - m_shadowTreeRootElement = new SVGGElement(SVGNames::gTag, document()); - m_shadowTreeRootElement->setInDocument(); - m_shadowTreeRootElement->setShadowParentNode(this); - - // Spec: An additional transformation translate(x,y) is appended to the end - // (i.e., right-side) of the transform attribute on the generated 'g', where x - // and y represent the values of the x and y attributes on the 'use' element. - if (x().value(this) != 0.0 || y().value(this) != 0.0) { - String transformString = String::format("translate(%f, %f)", x().value(this), y().value(this)); - m_shadowTreeRootElement->setAttribute(SVGNames::transformAttr, transformString); - } + ASSERT(m_targetElementInstance->correspondingElement() == target); // Build shadow tree from instance tree // This also handles the special cases: <use> on <symbol>, <use> on <svg>. - buildShadowTree(target, m_targetElementInstance.get()); + buildShadowTree(shadowRoot, target, m_targetElementInstance.get()); #if ENABLE(SVG) && ENABLE(SVG_USE) // Expand all <use> elements in the shadow tree. // Expand means: replace the actual <use> element by what it references. - expandUseElementsInShadowTree(m_shadowTreeRootElement.get()); + expandUseElementsInShadowTree(shadowRoot, shadowRoot); // Expand all <symbol> elements in the shadow tree. // Expand means: replace the actual <symbol> element by the <svg> element. - expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get()); - + expandSymbolElementsInShadowTree(shadowRoot, shadowRoot); #endif // Now that the shadow tree is completly expanded, we can associate // shadow tree elements <-> instances in the instance tree. - associateInstancesWithShadowTreeElements(m_shadowTreeRootElement->firstChild(), m_targetElementInstance.get()); + associateInstancesWithShadowTreeElements(shadowRoot->firstChild(), m_targetElementInstance.get()); + + // If no shadow tree element is present, this means that the reference root + // element was removed, as it is disallowed (ie. <use> on <foreignObject>) + // Do NOT leave an inconsistent instance tree around, instead destruct it. + if (!m_targetElementInstance->shadowTreeElement()) { + shadowRoot->removeAllChildren(); + m_targetElementInstance = 0; + return; + } + + // Consistency checks - this is assumed in updateContainerOffset(). + ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowRoot); // Eventually dump instance tree #ifdef DUMP_INSTANCE_TREE @@ -393,8 +532,8 @@ void SVGUseElement::buildPendingResource() PassRefPtr<XMLSerializer> serializer = XMLSerializer::create(); - String markup = serializer->serializeToString(m_shadowTreeRootElement.get(), ec); - ASSERT(ec == 0); + String markup = serializer->serializeToString(shadowRoot, ec); + ASSERT(!ec); fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data()); #endif @@ -402,30 +541,34 @@ void SVGUseElement::buildPendingResource() // Transfer event listeners assigned to the referenced element to our shadow tree elements. transferEventListenersToShadowTree(m_targetElementInstance.get()); - // The DOM side is setup properly. Now we have to attach the root shadow - // tree element manually - using attach() won't work for "shadow nodes". - attachShadowTree(); + // Update container offset/size + updateContainerOffsets(); + updateContainerSizes(); } RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*) { - return new (arena) RenderSVGTransformableContainer(this); + return new (arena) RenderSVGShadowTreeRootContainer(this); +} + +static void updateFromElementCallback(Node* node) +{ + if (RenderObject* renderer = node->renderer()) + renderer->updateFromElement(); } void SVGUseElement::attach() { SVGStyledTransformableElement::attach(); - // If we're a pending resource, this doesn't have any effect. - attachShadowTree(); + if (renderer()) + queuePostAttachCallback(updateFromElementCallback, this); } void SVGUseElement::detach() { SVGStyledTransformableElement::detach(); - - if (m_shadowTreeRootElement) - m_shadowTreeRootElement->detach(); + m_targetElementInstance = 0; } static bool isDirectReference(Node* n) @@ -441,13 +584,10 @@ static bool isDirectReference(Node* n) Path SVGUseElement::toClipPath() const { - if (!m_shadowTreeRootElement) - const_cast<SVGUseElement*>(this)->buildPendingResource(); - - if (!m_shadowTreeRootElement) + Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0; + if (!n) return Path(); - Node* n = m_shadowTreeRootElement->firstChild(); if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) { if (!isDirectReference(n)) // Spec: Indirect references are an error (14.3.5) @@ -481,11 +621,12 @@ void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* ta continue; // Create SVGElementInstance object, for both container/non-container nodes. - RefPtr<SVGElementInstance> instancePtr = SVGElementInstance::create(this, element); - targetInstance->appendChild(instancePtr.get()); + RefPtr<SVGElementInstance> instance = SVGElementInstance::create(this, element); + SVGElementInstance* instancePtr = instance.get(); + targetInstance->appendChild(instance.release()); // Enter recursion, appending new instance tree nodes to the "instance" object. - buildInstanceTree(element, instancePtr.get(), foundProblem); + buildInstanceTree(element, instancePtr, foundProblem); } // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced @@ -526,22 +667,11 @@ void SVGUseElement::handleDeepUseReferencing(SVGUseElement* use, SVGElementInsta // Create an instance object, even if we're dealing with a cycle RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, target); - targetInstance->appendChild(newInstance); + SVGElementInstance* newInstancePtr = newInstance.get(); + targetInstance->appendChild(newInstance.release()); // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children - buildInstanceTree(target, newInstance.get(), foundProblem); -} - -void SVGUseElement::alterShadowTreeForSVGTag(SVGElement* target) -{ - String widthString = String::number(width().value(this)); - String heightString = String::number(height().value(this)); - - if (hasAttribute(SVGNames::widthAttr)) - target->setAttribute(SVGNames::widthAttr, widthString); - - if (hasAttribute(SVGNames::heightAttr)) - target->setAttribute(SVGNames::heightAttr, heightString); + buildInstanceTree(target, newInstancePtr, foundProblem); } void SVGUseElement::removeDisallowedElementsFromSubtree(Node* subtree) @@ -560,7 +690,7 @@ void SVGUseElement::removeDisallowedElementsFromSubtree(Node* subtree) } } -void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance) +void SVGUseElement::buildShadowTree(SVGShadowTreeRootElement* shadowRoot, SVGElement* target, SVGElementInstance* targetInstance) { // For instance <use> on <foreignObject> (direct case). if (isDisallowedElement(target)) @@ -582,16 +712,12 @@ void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targ ASSERT(newChildPtr); ExceptionCode ec = 0; - m_shadowTreeRootElement->appendChild(newChild.release(), ec); - ASSERT(ec == 0); - - // Handle use referencing <svg> special case - if (target->hasTagName(SVGNames::svgTag)) - alterShadowTreeForSVGTag(newChildPtr); + shadowRoot->appendChild(newChild.release(), ec); + ASSERT(!ec); } #if ENABLE(SVG) && ENABLE(SVG_USE) -void SVGUseElement::expandUseElementsInShadowTree(Node* element) +void SVGUseElement::expandUseElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element) { // Why expand the <use> elements in the shadow tree here, and not just // do this directly in buildShadowTree, if we encounter a <use> element? @@ -612,28 +738,14 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element) // Don't ASSERT(target) here, it may be "pending", too. if (target) { // Setup sub-shadow tree root node - RefPtr<SVGElement> cloneParent = new SVGGElement(SVGNames::gTag, document()); + RefPtr<SVGShadowTreeContainerElement> cloneParent = new SVGShadowTreeContainerElement(document()); // Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the // 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element. transferUseAttributesToReplacedElement(use, cloneParent.get()); - // Spec: An additional transformation translate(x,y) is appended to the end - // (i.e., right-side) of the transform attribute on the generated 'g', where x - // and y represent the values of the x and y attributes on the 'use' element. - if (use->x().value(this) != 0.0 || use->y().value(this) != 0.0) { - if (!cloneParent->hasAttribute(SVGNames::transformAttr)) { - String transformString = String::format("translate(%f, %f)", use->x().value(this), use->y().value(this)); - cloneParent->setAttribute(SVGNames::transformAttr, transformString); - } else { - String transformString = String::format(" translate(%f, %f)", use->x().value(this), use->y().value(this)); - const AtomicString& transformAttribute = cloneParent->getAttribute(SVGNames::transformAttr); - cloneParent->setAttribute(SVGNames::transformAttr, transformAttribute + transformString); - } - } - ExceptionCode ec = 0; - + // For instance <use> on <foreignObject> (direct case). if (isDisallowedElement(target)) { // We still have to setup the <use> replacment (<g>). Otherwhise @@ -641,7 +753,7 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element) // Replace <use> with referenced content. ASSERT(use->parentNode()); use->parentNode()->replaceChild(cloneParent.release(), use, ec); - ASSERT(ec == 0); + ASSERT(!ec); return; } @@ -661,28 +773,24 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element) ASSERT(newChildPtr); cloneParent->appendChild(newChild.release(), ec); - ASSERT(ec == 0); + ASSERT(!ec); // Replace <use> with referenced content. ASSERT(use->parentNode()); use->parentNode()->replaceChild(cloneParent.release(), use, ec); - ASSERT(ec == 0); - - // Handle use referencing <svg> special case - if (target->hasTagName(SVGNames::svgTag)) - alterShadowTreeForSVGTag(newChildPtr); + ASSERT(!ec); // Immediately stop here, and restart expanding. - expandUseElementsInShadowTree(m_shadowTreeRootElement.get()); + expandUseElementsInShadowTree(shadowRoot, shadowRoot); return; } } for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling()) - expandUseElementsInShadowTree(child.get()); + expandUseElementsInShadowTree(shadowRoot, child.get()); } -void SVGUseElement::expandSymbolElementsInShadowTree(Node* element) +void SVGUseElement::expandSymbolElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element) { if (element->hasTagName(SVGNames::symbolTag)) { // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree, @@ -696,20 +804,12 @@ void SVGUseElement::expandSymbolElementsInShadowTree(Node* element) // Transfer all attributes from <symbol> to the new <svg> element svgElement->attributes()->setAttributes(*element->attributes()); - // Explicitly re-set width/height values - String widthString = String::number(width().value(this)); - String heightString = String::number(height().value(this)); - - svgElement->setAttribute(SVGNames::widthAttr, hasAttribute(SVGNames::widthAttr) ? widthString : "100%"); - svgElement->setAttribute(SVGNames::heightAttr, hasAttribute(SVGNames::heightAttr) ? heightString : "100%"); - - ExceptionCode ec = 0; - // Only clone symbol children, and add them to the new <svg> element + ExceptionCode ec = 0; for (Node* child = element->firstChild(); child; child = child->nextSibling()) { RefPtr<Node> newChild = child->cloneNode(true); svgElement->appendChild(newChild.release(), ec); - ASSERT(ec == 0); + ASSERT(!ec); } // We don't walk the target tree element-by-element, and clone each element, @@ -723,43 +823,19 @@ void SVGUseElement::expandSymbolElementsInShadowTree(Node* element) // Replace <symbol> with <svg>. ASSERT(element->parentNode()); element->parentNode()->replaceChild(svgElement.release(), element, ec); - ASSERT(ec == 0); + ASSERT(!ec); // Immediately stop here, and restart expanding. - expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get()); + expandSymbolElementsInShadowTree(shadowRoot, shadowRoot); return; } for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling()) - expandSymbolElementsInShadowTree(child.get()); + expandSymbolElementsInShadowTree(shadowRoot, child.get()); } #endif - -void SVGUseElement::attachShadowTree() -{ - if (!m_shadowTreeRootElement || m_shadowTreeRootElement->attached() || !document()->shouldCreateRenderers() || !attached() || !renderer()) - return; - // Inspired by RenderTextControl::createSubtreeIfNeeded(). - if (renderer()->canHaveChildren() && childShouldCreateRenderer(m_shadowTreeRootElement.get())) { - RefPtr<RenderStyle> style = m_shadowTreeRootElement->styleForRenderer(); - - if (m_shadowTreeRootElement->rendererIsNeeded(style.get())) { - m_shadowTreeRootElement->setRenderer(m_shadowTreeRootElement->createRenderer(document()->renderArena(), style.get())); - if (RenderObject* shadowRenderer = m_shadowTreeRootElement->renderer()) { - shadowRenderer->setStyle(style.release()); - renderer()->addChild(shadowRenderer, m_shadowTreeRootElement->nextRenderer()); - m_shadowTreeRootElement->setAttached(); - } - } - - // This will take care of attaching all shadow tree child nodes. - for (Node* child = m_shadowTreeRootElement->firstChild(); child; child = child->nextSibling()) - child->attach(); - } -} - void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target) { if (!target) @@ -830,6 +906,11 @@ void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGEl SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element) const { + if (!m_targetElementInstance) { + ASSERT(!inDocument()); + return 0; + } + return instanceForShadowTreeElement(element, m_targetElementInstance.get()); } @@ -847,14 +928,19 @@ SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element, S return instance; for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) { - SVGElementInstance* search = instanceForShadowTreeElement(element, current); - if (search) + if (SVGElementInstance* search = instanceForShadowTreeElement(element, current)) return search; } return 0; } +void SVGUseElement::invalidateShadowTree() +{ + m_needsShadowTreeRecreation = true; + setNeedsStyleRecalc(); +} + void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const { ASSERT(from); @@ -865,19 +951,24 @@ void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVG ExceptionCode ec = 0; to->removeAttribute(SVGNames::xAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(SVGNames::yAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(SVGNames::widthAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(SVGNames::heightAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); to->removeAttribute(XLinkNames::hrefAttr, ec); - ASSERT(ec == 0); + ASSERT(!ec); +} + +bool SVGUseElement::hasRelativeValues() const +{ + return x().isRelative() || y().isRelative() || width().isRelative() || height().isRelative(); } } diff --git a/WebCore/svg/SVGUseElement.h b/WebCore/svg/SVGUseElement.h index 45ca783..6fb3925 100644 --- a/WebCore/svg/SVGUseElement.h +++ b/WebCore/svg/SVGUseElement.h @@ -32,6 +32,7 @@ namespace WebCore { class SVGElementInstance; class SVGLength; + class SVGShadowTreeRootElement; class SVGUseElement : public SVGStyledTransformableElement, public SVGTests, @@ -52,11 +53,10 @@ namespace WebCore { virtual void buildPendingResource(); virtual void parseMappedAttribute(MappedAttribute*); - virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); - virtual void svgAttributeChanged(const QualifiedName&); - virtual void recalcStyle(StyleChange = NoChange); + virtual void synchronizeProperty(const QualifiedName&); + virtual void recalcStyle(StyleChange = NoChange); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual void attach(); virtual void detach(); @@ -65,20 +65,26 @@ namespace WebCore { static void removeDisallowedElementsFromSubtree(Node* element); SVGElementInstance* instanceForShadowTreeElement(Node* element) const; + void invalidateShadowTree(); + + private: + friend class RenderSVGShadowTreeRootContainer; + bool isPendingResource() const { return m_isPendingResource; } + void buildShadowAndInstanceTree(SVGShadowTreeRootElement*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::xAttrString, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::yAttrString, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::widthAttrString, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::heightAttrString, SVGLength, Height, height) + virtual bool hasRelativeValues() const; + + DECLARE_ANIMATED_PROPERTY(SVGUseElement, SVGNames::xAttr, SVGLength, X, x) + DECLARE_ANIMATED_PROPERTY(SVGUseElement, SVGNames::yAttr, SVGLength, Y, y) + DECLARE_ANIMATED_PROPERTY(SVGUseElement, SVGNames::widthAttr, SVGLength, Width, width) + DECLARE_ANIMATED_PROPERTY(SVGUseElement, SVGNames::heightAttr, SVGLength, Height, height) // SVGURIReference - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) + DECLARE_ANIMATED_PROPERTY(SVGUseElement, XLinkNames::hrefAttr, String, Href, href) // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGUseElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) private: // Instance tree handling @@ -86,18 +92,13 @@ namespace WebCore { void handleDeepUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, bool& foundCycle); // Shadow tree handling - PassRefPtr<SVGSVGElement> buildShadowTreeForSymbolTag(SVGElement* target, SVGElementInstance* targetInstance); - void alterShadowTreeForSVGTag(SVGElement* target); - - void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance); + void buildShadowTree(SVGShadowTreeRootElement*, SVGElement* target, SVGElementInstance* targetInstance); #if ENABLE(SVG) && ENABLE(SVG_USE) - void expandUseElementsInShadowTree(Node* element); - void expandSymbolElementsInShadowTree(Node* element); + void expandUseElementsInShadowTree(SVGShadowTreeRootElement*, Node* element); + void expandSymbolElementsInShadowTree(SVGShadowTreeRootElement*, Node* element); #endif - void attachShadowTree(); - // "Tree connector" void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance); SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const; @@ -105,11 +106,16 @@ namespace WebCore { void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const; void transferEventListenersToShadowTree(SVGElementInstance* target); - RefPtr<SVGElement> m_shadowTreeRootElement; + void updateContainerOffsets(); + void updateContainerSizes(); + + bool m_isPendingResource; + bool m_needsShadowTreeRecreation; + String m_resourceId; RefPtr<SVGElementInstance> m_targetElementInstance; }; -} // namespace WebCore +} -#endif // ENABLE(SVG) +#endif #endif diff --git a/WebCore/svg/SVGViewElement.cpp b/WebCore/svg/SVGViewElement.cpp index 0fe6a90..aba7283 100644 --- a/WebCore/svg/SVGViewElement.cpp +++ b/WebCore/svg/SVGViewElement.cpp @@ -38,9 +38,6 @@ SVGViewElement::SVGViewElement(const QualifiedName& tagName, Document* doc) , SVGExternalResourcesRequired() , SVGFitToViewBox() , SVGZoomAndPan() - , m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) - , m_viewBox(this, SVGNames::viewBoxAttr) - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) { } @@ -70,6 +67,25 @@ void SVGViewElement::parseMappedAttribute(MappedAttribute* attr) } } +void SVGViewElement::synchronizeProperty(const QualifiedName& attrName) +{ + SVGStyledElement::synchronizeProperty(attrName); + + if (attrName == anyQName()) { + synchronizeExternalResourcesRequired(); + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + return; + } + + if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) + synchronizeExternalResourcesRequired(); + else if (SVGFitToViewBox::isKnownAttribute(attrName)) { + synchronizeViewBox(); + synchronizePreserveAspectRatio(); + } +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGViewElement.h b/WebCore/svg/SVGViewElement.h index 33d0ae3..f913fcd 100644 --- a/WebCore/svg/SVGViewElement.h +++ b/WebCore/svg/SVGViewElement.h @@ -39,6 +39,7 @@ namespace WebCore { virtual ~SVGViewElement(); virtual void parseMappedAttribute(MappedAttribute*); + virtual void synchronizeProperty(const QualifiedName&); SVGStringList* viewTarget() const; @@ -46,13 +47,11 @@ namespace WebCore { private: // SVGExternalResourcesRequired - ANIMATED_PROPERTY_DECLARATIONS(SVGViewElement, SVGExternalResourcesRequiredIdentifier, - SVGNames::externalResourcesRequiredAttrString, bool, - ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_PROPERTY(SVGViewElement, SVGNames::externalResourcesRequiredAttr, bool, ExternalResourcesRequired, externalResourcesRequired) // SVGFitToViewBox - ANIMATED_PROPERTY_DECLARATIONS(SVGViewElement, SVGFitToViewBoxIdentifier, SVGNames::viewBoxAttrString, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_DECLARATIONS(SVGViewElement, SVGFitToViewBoxIdentifier, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY(SVGViewElement, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) + DECLARE_ANIMATED_PROPERTY(SVGViewElement, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) mutable RefPtr<SVGStringList> m_viewTarget; }; diff --git a/WebCore/svg/SVGViewSpec.cpp b/WebCore/svg/SVGViewSpec.cpp index e6ded33..608bdbf 100644 --- a/WebCore/svg/SVGViewSpec.cpp +++ b/WebCore/svg/SVGViewSpec.cpp @@ -35,8 +35,6 @@ SVGViewSpec::SVGViewSpec(const SVGSVGElement* contextElement) : SVGFitToViewBox() , SVGZoomAndPan() , m_contextElement(contextElement) - , m_viewBox(this, SVGNames::viewBoxAttr) - , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) , m_transform(SVGTransformList::create(SVGNames::transformAttr)) { } @@ -62,9 +60,7 @@ void SVGViewSpec::setViewBoxString(const String& viewBox) void SVGViewSpec::setPreserveAspectRatioString(const String& preserve) { - const UChar* c = preserve.characters(); - const UChar* end = c + preserve.length(); - preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end); + SVGPreserveAspectRatio::parsePreserveAspectRatio(this, preserve); } void SVGViewSpec::setViewTargetString(const String& viewTargetString) @@ -141,7 +137,9 @@ bool SVGViewSpec::parseViewSpec(const String& viewSpec) if (currViewSpec >= end || *currViewSpec != '(') return false; currViewSpec++; - if (!preserveAspectRatioBaseValue()->parsePreserveAspectRatio(currViewSpec, end, false)) + bool result = false; + setPreserveAspectRatioBaseValue(SVGPreserveAspectRatio::parsePreserveAspectRatio(currViewSpec, end, false, result)); + if (!result) return false; if (currViewSpec >= end || *currViewSpec != ')') return false; @@ -152,7 +150,7 @@ bool SVGViewSpec::parseViewSpec(const String& viewSpec) if (currViewSpec >= end || *currViewSpec != '(') return false; currViewSpec++; - SVGTransformable::parseTransformAttribute(m_transform.get(), currViewSpec, end); + SVGTransformable::parseTransformAttribute(m_transform.get(), currViewSpec, end, SVGTransformable::DoNotClearList); if (currViewSpec >= end || *currViewSpec != ')') return false; currViewSpec++; diff --git a/WebCore/svg/SVGViewSpec.h b/WebCore/svg/SVGViewSpec.h index 5f963af..12358dc 100644 --- a/WebCore/svg/SVGViewSpec.h +++ b/WebCore/svg/SVGViewSpec.h @@ -52,14 +52,14 @@ namespace WebCore { String viewTargetString() const { return m_viewTargetString; } SVGElement* viewTarget() const; - const SVGSVGElement* contextElement() const { return m_contextElement; } + SVGSVGElement* contextElement() const { return const_cast<SVGSVGElement*>(m_contextElement); } private: const SVGSVGElement* m_contextElement; // SVGFitToViewBox - ANIMATED_PROPERTY_DECLARATIONS(SVGViewSpec, SVGFitToViewBoxIdentifier, SVGNames::viewBoxAttrString, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_DECLARATIONS(SVGViewSpec, SVGFitToViewBoxIdentifier, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) + DECLARE_ANIMATED_PROPERTY(SVGViewSpec, SVGNames::viewBoxAttr, FloatRect, ViewBox, viewBox) + DECLARE_ANIMATED_PROPERTY(SVGViewSpec, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) mutable RefPtr<SVGTransformList> m_transform; String m_viewTargetString; diff --git a/WebCore/svg/SVGZoomAndPan.idl b/WebCore/svg/SVGZoomAndPan.idl index 6d69583..bd738f3 100644 --- a/WebCore/svg/SVGZoomAndPan.idl +++ b/WebCore/svg/SVGZoomAndPan.idl @@ -26,7 +26,7 @@ module svg { - interface [Conditional=SVG, GenerateConstructor, ObjCProtocol] SVGZoomAndPan { + interface [Conditional=SVG, ObjCProtocol] SVGZoomAndPan { // Zoom and Pan Types const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0; const unsigned short SVG_ZOOMANDPAN_DISABLE = 1; diff --git a/WebCore/svg/SynchronizablePropertyController.cpp b/WebCore/svg/SynchronizablePropertyController.cpp deleted file mode 100644 index be8ab78..0000000 --- a/WebCore/svg/SynchronizablePropertyController.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - Copyright (C) Research In Motion Limited 2009. All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) -#include "SynchronizablePropertyController.h" - -#include "NamedNodeMap.h" -#include "Node.h" -#include "SVGAnimatedProperty.h" - -namespace WebCore { - -void SynchronizableProperties::addProperty(SVGAnimatedPropertyBase* base) -{ - m_bases.add(base); -} - -void SynchronizableProperties::synchronize() -{ - ASSERT(!m_bases.isEmpty()); - if (m_shouldSynchronize) { - BaseSet::iterator it = m_bases.begin(); - BaseSet::iterator end = m_bases.end(); - - for (; it != end; ++it) { - SVGAnimatedPropertyBase* base = *it; - ASSERT(base); - base->synchronize(); - } - } -} - -void SynchronizableProperties::startAnimation() -{ - ASSERT(!m_bases.isEmpty()); - BaseSet::iterator it = m_bases.begin(); - BaseSet::iterator end = m_bases.end(); - - for (; it != end; ++it) { - SVGAnimatedPropertyBase* base = *it; - ASSERT(base); - base->startAnimation(); - } -} - -void SynchronizableProperties::stopAnimation() -{ - ASSERT(!m_bases.isEmpty()); - BaseSet::iterator it = m_bases.begin(); - BaseSet::iterator end = m_bases.end(); - - for (; it != end; ++it) { - SVGAnimatedPropertyBase* base = *it; - ASSERT(base); - base->stopAnimation(); - } -} - -SynchronizablePropertyController::SynchronizablePropertyController() -{ -} - -void SynchronizablePropertyController::registerProperty(const QualifiedName& attrName, SVGAnimatedPropertyBase* base) -{ - // 'attrName' is ambigious. For instance in SVGMarkerElement both 'orientType' / 'orientAngle' - // SVG DOM objects are synchronized with the 'orient' attribute. This why we need a HashSet. - PropertyMap::iterator it = m_map.find(attrName.localName()); - if (it == m_map.end()) { - SynchronizableProperties properties; - properties.addProperty(base); - m_map.set(attrName.localName(), properties); - return; - } - - it->second.addProperty(base); -} - -void SynchronizablePropertyController::setPropertyNeedsSynchronization(const QualifiedName& attrName) -{ - PropertyMap::iterator itProp = m_map.find(attrName.localName()); - ASSERT(itProp != m_map.end()); - - itProp->second.setNeedsSynchronization(); -} - -void SynchronizablePropertyController::synchronizeProperty(const String& name) -{ - PropertyMap::iterator itProp = m_map.find(name); - if (itProp == m_map.end()) - return; - - itProp->second.synchronize(); -} - -void SynchronizablePropertyController::synchronizeAllProperties() -{ - if (m_map.isEmpty()) - return; - - PropertyMap::iterator itProp = m_map.begin(); - PropertyMap::iterator endProp = m_map.end(); - - for (; itProp != endProp; ++itProp) - itProp->second.synchronize(); -} - -void SynchronizablePropertyController::startAnimation(const String& name) -{ - PropertyMap::iterator itProp = m_map.find(name); - if (itProp == m_map.end()) - return; - - itProp->second.startAnimation(); -} - -void SynchronizablePropertyController::stopAnimation(const String& name) -{ - PropertyMap::iterator itProp = m_map.find(name); - if (itProp == m_map.end()) - return; - - itProp->second.stopAnimation(); -} - -} - -#endif // ENABLE(SVG) diff --git a/WebCore/svg/SynchronizablePropertyController.h b/WebCore/svg/SynchronizablePropertyController.h deleted file mode 100644 index 1ec5026..0000000 --- a/WebCore/svg/SynchronizablePropertyController.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) Research In Motion Limited 2009. All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SynchronizablePropertyController_h -#define SynchronizablePropertyController_h - -#if ENABLE(SVG) -#include "StringHash.h" -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> -#include <wtf/Noncopyable.h> - -namespace WebCore { - -class QualifiedName; -class SVGAnimatedPropertyBase; - -class SynchronizableProperties { -public: - SynchronizableProperties() - : m_shouldSynchronize(false) - { - } - - void setNeedsSynchronization() - { - m_shouldSynchronize = true; - } - - void addProperty(SVGAnimatedPropertyBase*); - void synchronize(); - void startAnimation(); - void stopAnimation(); - -private: - typedef HashSet<SVGAnimatedPropertyBase*> BaseSet; - - BaseSet m_bases; - bool m_shouldSynchronize; -}; - -// Helper class used exclusively by SVGElement to keep track of all animatable properties within a SVGElement, -// and wheter they are supposed to be synchronized or not (depending wheter AnimatedPropertyTearOff's have been created) -class SynchronizablePropertyController : public Noncopyable { -public: - void registerProperty(const QualifiedName&, SVGAnimatedPropertyBase*); - void setPropertyNeedsSynchronization(const QualifiedName&); - - void synchronizeProperty(const String&); - void synchronizeAllProperties(); - - void startAnimation(const String&); - void stopAnimation(const String&); - -private: - friend class SVGElement; - SynchronizablePropertyController(); - -private: - typedef HashMap<String, SynchronizableProperties> PropertyMap; - - PropertyMap m_map; -}; - -}; - -#endif // ENABLE(SVG) -#endif // SynchronizablePropertyController_h diff --git a/WebCore/svg/SynchronizableTypeWrapper.h b/WebCore/svg/SynchronizableTypeWrapper.h deleted file mode 100644 index 12f8426..0000000 --- a/WebCore/svg/SynchronizableTypeWrapper.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SynchronizableTypeWrapper_h -#define SynchronizableTypeWrapper_h - -#if ENABLE(SVG) -#include <wtf/Noncopyable.h> - -namespace WebCore { - - template<typename StoredType> - class SynchronizableTypeWrapperBase : public Noncopyable { - protected: - SynchronizableTypeWrapperBase(); - - template<typename AssignableType> - void assign(AssignableType type); - - bool needsSynchronization() const; - void setSynchronized(); - - protected: - StoredType m_value; - bool m_needsSynchronization; - }; - - template<typename StoredType> - class SynchronizableTypeWrapper : private SynchronizableTypeWrapperBase<StoredType> { - public: - typedef SynchronizableTypeWrapperBase<StoredType> Base; - SynchronizableTypeWrapper(); - - // "Forwarding constructors" for primitive type assignment with more than one argument, for exampe SVGLength - template<typename T1> SynchronizableTypeWrapper(const T1&); - template<typename T1, typename T2> SynchronizableTypeWrapper(const T1&, const T2&); - template<typename T1, typename T2, typename T3> SynchronizableTypeWrapper(const T1&, const T2&, const T3&); - - SynchronizableTypeWrapper& operator=(const StoredType&); - operator StoredType() const; - - using Base::needsSynchronization; - using Base::setSynchronized; - - private: - using Base::m_value; - }; - - template<typename StoredPointerType> - class SynchronizableTypeWrapper<RefPtr<StoredPointerType> > : private SynchronizableTypeWrapperBase<RefPtr<StoredPointerType> > { - public: - typedef SynchronizableTypeWrapperBase<RefPtr<StoredPointerType> > Base; - SynchronizableTypeWrapper(); - SynchronizableTypeWrapper(const PassRefPtr<StoredPointerType>&); - - SynchronizableTypeWrapper& operator=(StoredPointerType*); - operator StoredPointerType*() const; - - using Base::needsSynchronization; - using Base::setSynchronized; - - private: - using Base::m_value; - }; - - // SynchronizableTypeWrapperBase implementation - template<typename StoredType> - inline SynchronizableTypeWrapperBase<StoredType>::SynchronizableTypeWrapperBase() - : m_value() - , m_needsSynchronization(false) - { - } - - template<typename StoredType> template<typename AssignableType> - inline void SynchronizableTypeWrapperBase<StoredType>::assign(AssignableType type) - { - m_value = type; - m_needsSynchronization = true; - } - - template<typename StoredType> - inline bool SynchronizableTypeWrapperBase<StoredType>::needsSynchronization() const - { - return m_needsSynchronization; - } - - template<typename StoredType> - inline void SynchronizableTypeWrapperBase<StoredType>::setSynchronized() - { - m_needsSynchronization = false; - } - - // SynchronizableTypeWrapper implementation for primitive types - template<typename StoredType> - inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper() - : Base() - { - } - - template<typename StoredType> template<typename T1> - inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper(const T1& arg1) - : Base() - { - m_value = StoredType(arg1); - } - - template<typename StoredType> template<typename T1, typename T2> - inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper(const T1& arg1, const T2& arg2) - : Base() - { - m_value = StoredType(arg1, arg2); - } - - template<typename StoredType> template<typename T1, typename T2, typename T3> - inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper(const T1& arg1, const T2& arg2, const T3& arg3) - : Base() - { - m_value = StoredType(arg1, arg2, arg3); - } - - template<typename StoredType> - inline SynchronizableTypeWrapper<StoredType>& SynchronizableTypeWrapper<StoredType>::operator=(const StoredType& other) - { - Base::assign(other); - return (*this); - } - - template<typename StoredType> - inline SynchronizableTypeWrapper<StoredType>::operator StoredType() const - { - return m_value; - } - - // SynchronizableTypeWrapper implementation for refcounted types - template<typename StoredPointerType> - inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::SynchronizableTypeWrapper() - : Base() - { - } - - template<typename StoredPointerType> - inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::SynchronizableTypeWrapper(const PassRefPtr<StoredPointerType>& type) - : Base() - { - Base::m_value = type; - } - - template<typename StoredPointerType> - inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >& SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::operator=(StoredPointerType* other) - { - Base::assign(other); - return (*this); - } - - template<typename StoredPointerType> - inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::operator StoredPointerType*() const - { - return Base::m_value.get(); - } - -}; - -#endif -#endif diff --git a/WebCore/svg/animation/SMILTimeContainer.h b/WebCore/svg/animation/SMILTimeContainer.h index a6a61c0..e11cc6f 100644 --- a/WebCore/svg/animation/SMILTimeContainer.h +++ b/WebCore/svg/animation/SMILTimeContainer.h @@ -32,6 +32,7 @@ #include "SMILTime.h" #include "StringHash.h" #include "Timer.h" +#include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> diff --git a/WebCore/svg/graphics/SVGImage.cpp b/WebCore/svg/graphics/SVGImage.cpp index 5f050a4..348df4f 100644 --- a/WebCore/svg/graphics/SVGImage.cpp +++ b/WebCore/svg/graphics/SVGImage.cpp @@ -30,6 +30,7 @@ #include "CachedPage.h" #include "DocumentLoader.h" +#include "FileChooser.h" #include "FloatRect.h" #include "Frame.h" #include "FrameLoader.h" @@ -54,7 +55,7 @@ namespace WebCore { -class SVGImageChromeClient : public EmptyChromeClient { +class SVGImageChromeClient : public EmptyChromeClient, public Noncopyable { public: SVGImageChromeClient(SVGImage* image) : m_image(image) @@ -192,7 +193,7 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl if (view->needsLayout()) view->layout(); - view->paint(context, enclosingIntRect(srcRect)); + view->paint(context, IntRect(0, 0, view->width(), view->height())); if (compositeOp != CompositeSourceOver) context->endTransparencyLayer(); @@ -267,6 +268,11 @@ bool SVGImage::dataChanged(bool allDataReceived) return m_page; } +String SVGImage::filenameExtension() const +{ + return "svg"; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/graphics/SVGImage.h b/WebCore/svg/graphics/SVGImage.h index 10f39ba..a0414fe 100644 --- a/WebCore/svg/graphics/SVGImage.h +++ b/WebCore/svg/graphics/SVGImage.h @@ -47,6 +47,8 @@ namespace WebCore { private: virtual ~SVGImage(); + virtual String filenameExtension() const; + virtual void setContainerSize(const IntSize&); virtual bool usesContainerSize() const; virtual bool hasRelativeWidth() const; diff --git a/WebCore/svg/graphics/SVGPaintServer.cpp b/WebCore/svg/graphics/SVGPaintServer.cpp index 6b81f72..9d84b0e 100644 --- a/WebCore/svg/graphics/SVGPaintServer.cpp +++ b/WebCore/svg/graphics/SVGPaintServer.cpp @@ -57,9 +57,9 @@ TextStream& operator<<(TextStream& ts, const SVGPaintServer& paintServer) return paintServer.externalRepresentation(ts); } -SVGPaintServer* getPaintServerById(Document* document, const AtomicString& id) +SVGPaintServer* getPaintServerById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isPaintServer()) return static_cast<SVGPaintServer*>(resource); @@ -85,7 +85,7 @@ SVGPaintServer* SVGPaintServer::fillPaintServer(const RenderStyle* style, const if (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) { AtomicString id(SVGURIReference::getTarget(fill->uri())); - fillPaintServer = getPaintServerById(item->document(), id); + fillPaintServer = getPaintServerById(item->document(), id, item); SVGElement* svgElement = static_cast<SVGElement*>(item->node()); ASSERT(svgElement && svgElement->document() && svgElement->isStyled()); @@ -126,7 +126,7 @@ SVGPaintServer* SVGPaintServer::strokePaintServer(const RenderStyle* style, cons if (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) { AtomicString id(SVGURIReference::getTarget(stroke->uri())); - strokePaintServer = getPaintServerById(item->document(), id); + strokePaintServer = getPaintServerById(item->document(), id, item); SVGElement* svgElement = static_cast<SVGElement*>(item->node()); ASSERT(svgElement && svgElement->document() && svgElement->isStyled()); diff --git a/WebCore/svg/graphics/SVGPaintServer.h b/WebCore/svg/graphics/SVGPaintServer.h index 244243c..6e8997c 100644 --- a/WebCore/svg/graphics/SVGPaintServer.h +++ b/WebCore/svg/graphics/SVGPaintServer.h @@ -29,6 +29,7 @@ #if ENABLE(SVG) #include "DashArray.h" +#include "RenderObject.h" #include "SVGResource.h" #if PLATFORM(CG) @@ -82,7 +83,7 @@ namespace WebCore { TextStream& operator<<(TextStream&, const SVGPaintServer&); - SVGPaintServer* getPaintServerById(Document*, const AtomicString&); + SVGPaintServer* getPaintServerById(Document*, const AtomicString&, const RenderObject*); void applyStrokeStyleToContext(GraphicsContext*, RenderStyle*, const RenderObject*); DashArray dashArrayFromRenderingStyle(const RenderStyle* style, RenderStyle* rootStyle); diff --git a/WebCore/svg/graphics/SVGPaintServerGradient.cpp b/WebCore/svg/graphics/SVGPaintServerGradient.cpp index 74e3c22..6c58a82 100644 --- a/WebCore/svg/graphics/SVGPaintServerGradient.cpp +++ b/WebCore/svg/graphics/SVGPaintServerGradient.cpp @@ -193,7 +193,7 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject bool isFilled = (type & ApplyToFillTargetType) && style->hasFill(); bool isStroked = (type & ApplyToStrokeTargetType) && style->hasStroke(); - ASSERT(isFilled && !isStroked || !isFilled && isStroked); + ASSERT((isFilled && !isStroked) || (!isFilled && isStroked)); context->save(); diff --git a/WebCore/svg/graphics/SVGPaintServerPattern.cpp b/WebCore/svg/graphics/SVGPaintServerPattern.cpp index 289c40c..28706ba 100644 --- a/WebCore/svg/graphics/SVGPaintServerPattern.cpp +++ b/WebCore/svg/graphics/SVGPaintServerPattern.cpp @@ -103,7 +103,7 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* bool isFilled = (type & ApplyToFillTargetType) && style->hasFill(); bool isStroked = (type & ApplyToStrokeTargetType) && style->hasStroke(); - ASSERT(isFilled && !isStroked || !isFilled && isStroked); + ASSERT((isFilled && !isStroked) || (!isFilled && isStroked)); m_ownerElement->buildPattern(targetRect); if (!tile()) diff --git a/WebCore/svg/graphics/SVGResource.cpp b/WebCore/svg/graphics/SVGResource.cpp index 514b70d..a071996 100644 --- a/WebCore/svg/graphics/SVGResource.cpp +++ b/WebCore/svg/graphics/SVGResource.cpp @@ -31,61 +31,30 @@ #include "RenderPath.h" #include "SVGElement.h" #include "SVGStyledElement.h" +#include <wtf/HashSet.h> #include <wtf/StdLibExtras.h> namespace WebCore { -SVGResource::SVGResource() +typedef HashSet<SVGResource*> ResourceSet; + +static ResourceSet& resourceSet() { + DEFINE_STATIC_LOCAL(ResourceSet, set, ()); + return set; } -struct ResourceSet : Noncopyable { - ResourceSet() - { - for (int i = 0; i < _ResourceTypeCount; i++) - resources[i] = 0; - } - SVGResource* resources[_ResourceTypeCount]; -}; - -typedef HashMap<SVGStyledElement*, ResourceSet*> ResourceClientMap; - -static ResourceClientMap& clientMap() +SVGResource::SVGResource() { - DEFINE_STATIC_LOCAL(ResourceClientMap, map, ()); - return map; + ASSERT(!resourceSet().contains(this)); + resourceSet().add(this); } + SVGResource::~SVGResource() { - int type = -1; - HashSet<SVGStyledElement*>::iterator itr = m_clients.begin(); - - for (; type < 0 && itr != m_clients.end(); ++itr) { - ResourceSet* target = clientMap().get(*itr); - if (!target) - continue; - - for (int i = 0; i < _ResourceTypeCount; i++) { - if (target->resources[i] != this) - continue; - type = i; - target->resources[i] = 0; - break; - } - } - - if (type < 0) - return; - - for (; itr != m_clients.end(); ++itr) { - ResourceSet* target = clientMap().get(*itr); - if (!target) - continue; - - if (target->resources[type] == this) - target->resources[type] = 0; - } + ASSERT(resourceSet().contains(this)); + resourceSet().remove(this); } void SVGResource::invalidate() @@ -120,20 +89,15 @@ void SVGResource::invalidateClients(HashSet<SVGStyledElement*> clients) void SVGResource::removeClient(SVGStyledElement* item) { - ResourceClientMap::iterator resourcePtr = clientMap().find(item); - if (resourcePtr == clientMap().end()) - return; - - ResourceSet* set = resourcePtr->second; - ASSERT(set); - - clientMap().remove(resourcePtr); - - for (int i = 0; i < _ResourceTypeCount; i++) - if (set->resources[i]) - set->resources[i]->m_clients.remove(item); - - delete set; + ResourceSet::iterator it = resourceSet().begin(); + ResourceSet::iterator end = resourceSet().end(); + + for (; it != end; ++it) { + SVGResource* resource = *it; + if (!resource->m_clients.contains(item)) + continue; + resource->m_clients.remove(item); + } } void SVGResource::addClient(SVGStyledElement* item) @@ -142,17 +106,6 @@ void SVGResource::addClient(SVGStyledElement* item) return; m_clients.add(item); - - ResourceSet* target = clientMap().get(item); - if (!target) - target = new ResourceSet; - - SVGResourceType type = resourceType(); - if (SVGResource* oldResource = target->resources[type]) - oldResource->m_clients.remove(item); - - target->resources[type] = this; - clientMap().set(item, target); } TextStream& SVGResource::externalRepresentation(TextStream& ts) const @@ -160,7 +113,7 @@ TextStream& SVGResource::externalRepresentation(TextStream& ts) const return ts; } -SVGResource* getResourceById(Document* document, const AtomicString& id) +SVGResource* getResourceById(Document* document, const AtomicString& id, const RenderObject* object) { if (id.isEmpty()) return 0; @@ -171,7 +124,7 @@ SVGResource* getResourceById(Document* document, const AtomicString& id) svgElement = static_cast<SVGElement*>(element); if (svgElement && svgElement->isStyled()) - return static_cast<SVGStyledElement*>(svgElement)->canvasResource(); + return static_cast<SVGStyledElement*>(svgElement)->canvasResource(object); return 0; } diff --git a/WebCore/svg/graphics/SVGResource.h b/WebCore/svg/graphics/SVGResource.h index 7ee98f6..8f303b5 100644 --- a/WebCore/svg/graphics/SVGResource.h +++ b/WebCore/svg/graphics/SVGResource.h @@ -28,6 +28,7 @@ #if ENABLE(SVG) #include "PlatformString.h" +#include "RenderObject.h" #include "StringHash.h" #include <wtf/HashMap.h> @@ -91,7 +92,7 @@ namespace WebCore { HashSet<SVGStyledElement*> m_clients; }; - SVGResource* getResourceById(Document*, const AtomicString&); + SVGResource* getResourceById(Document*, const AtomicString&, const RenderObject*); TextStream& operator<<(TextStream&, const SVGResource&); diff --git a/WebCore/svg/graphics/SVGResourceClipper.cpp b/WebCore/svg/graphics/SVGResourceClipper.cpp index 5998afb..c0fccaf 100644 --- a/WebCore/svg/graphics/SVGResourceClipper.cpp +++ b/WebCore/svg/graphics/SVGResourceClipper.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * (C) 2009 Dirk Schulze <krit@webkit.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,9 +29,9 @@ #if ENABLE(SVG) #include "SVGResourceClipper.h" -#include "TransformationMatrix.h" #include "GraphicsContext.h" #include "SVGRenderTreeAsText.h" +#include "TransformationMatrix.h" #if PLATFORM(CG) #include <ApplicationServices/ApplicationServices.h> @@ -50,6 +51,36 @@ SVGResourceClipper::~SVGResourceClipper() void SVGResourceClipper::resetClipData() { m_clipData.clear(); + m_clipperBoundingBox = FloatRect(); +} + +void SVGResourceClipper::invalidate() +{ + SVGResource::invalidate(); + resetClipData(); +} + +FloatRect SVGResourceClipper::clipperBoundingBox(const FloatRect& objectBoundingBox) +{ + // FIXME: We need a different calculation for other clip content than paths. + if (!m_clipperBoundingBox.isEmpty()) + return m_clipperBoundingBox; + + if (m_clipData.clipData().isEmpty()) + return FloatRect(); + + for (unsigned x = 0; x < m_clipData.clipData().size(); x++) { + ClipData clipData = m_clipData.clipData()[x]; + + FloatRect clipPathRect = clipData.path.boundingRect(); + if (clipData.bboxUnits) { + clipPathRect.scale(objectBoundingBox.width(), objectBoundingBox.height()); + clipPathRect.move(objectBoundingBox.x(), objectBoundingBox.y()); + } + m_clipperBoundingBox.unite(clipPathRect); + } + + return m_clipperBoundingBox; } void SVGResourceClipper::applyClip(GraphicsContext* context, const FloatRect& boundingBox) const @@ -125,9 +156,9 @@ TextStream& operator<<(TextStream& ts, const ClipData& d) return ts; } -SVGResourceClipper* getClipperById(Document* document, const AtomicString& id) +SVGResourceClipper* getClipperById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isClipper()) return static_cast<SVGResourceClipper*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceClipper.h b/WebCore/svg/graphics/SVGResourceClipper.h index 98c295f..df5562d 100644 --- a/WebCore/svg/graphics/SVGResourceClipper.h +++ b/WebCore/svg/graphics/SVGResourceClipper.h @@ -27,9 +27,10 @@ #define SVGResourceClipper_h #if ENABLE(SVG) - -#include "SVGResource.h" +#include "FloatRect.h" #include "Path.h" +#include "RenderObject.h" +#include "SVGResource.h" namespace WebCore { @@ -65,7 +66,9 @@ namespace WebCore { public: static PassRefPtr<SVGResourceClipper> create() { return adoptRef(new SVGResourceClipper); } virtual ~SVGResourceClipper(); - + + virtual void invalidate(); + void resetClipData(); void addClipData(const Path&, WindRule, bool bboxUnits); @@ -76,15 +79,17 @@ namespace WebCore { // To be implemented by the specific rendering devices void applyClip(GraphicsContext*, const FloatRect& boundingBox) const; + FloatRect clipperBoundingBox(const FloatRect& oob); private: SVGResourceClipper(); ClipDataList m_clipData; + FloatRect m_clipperBoundingBox; }; TextStream& operator<<(TextStream&, WindRule); TextStream& operator<<(TextStream&, const ClipData&); - SVGResourceClipper* getClipperById(Document*, const AtomicString&); + SVGResourceClipper* getClipperById(Document*, const AtomicString&, const RenderObject*); } // namespace WebCore diff --git a/WebCore/svg/graphics/SVGResourceFilter.cpp b/WebCore/svg/graphics/SVGResourceFilter.cpp index fcf0e40..72ae203 100644 --- a/WebCore/svg/graphics/SVGResourceFilter.cpp +++ b/WebCore/svg/graphics/SVGResourceFilter.cpp @@ -32,6 +32,7 @@ #include "SVGFilter.h" #include "SVGFilterBuilder.h" #include "SVGFilterElement.h" +#include "SVGRenderSupport.h" #include "SVGRenderTreeAsText.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -52,17 +53,21 @@ SVGResourceFilter::SVGResourceFilter(const SVGFilterElement* ownerElement) , m_savedContext(0) , m_sourceGraphicBuffer(0) { - m_filterBuilder.set(new SVGFilterBuilder()); + m_filterBuilder.set(new SVGFilterBuilder()); } SVGResourceFilter::~SVGResourceFilter() { } -static inline bool shouldProcessFilter(SVGResourceFilter* filter) +FloatRect SVGResourceFilter::filterBoundingBox(const FloatRect& obb) const { - return (!filter->scaleX() || !filter->scaleY() || !filter->filterBoundingBox().width() - || !filter->filterBoundingBox().height()); + return m_ownerElement->filterBoundingBox(obb); +} + +static inline bool shouldProcessFilter(SVGResourceFilter* filter, const FloatRect& filterRect) +{ + return (!filter->scaleX() || !filter->scaleY() || !filterRect.width() || !filterRect.height()); } void SVGResourceFilter::addFilterEffect(SVGFilterPrimitiveStandardAttributes* effectAttributes, PassRefPtr<FilterEffect> effect) @@ -86,16 +91,21 @@ bool SVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size) return matchesFilterSize; } -void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObject* object) +bool SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObject* object) { - FloatRect targetRect = object->objectBoundingBox(); - m_ownerElement->buildFilter(targetRect); + m_ownerElement->buildFilter(object->objectBoundingBox()); + const SVGRenderBase* renderer = object->toSVGRenderBase(); + if (!renderer) + return false; - if (shouldProcessFilter(this)) - return; + FloatRect paintRect = renderer->strokeBoundingBox(); + paintRect.unite(renderer->markerBoundingBox()); + + if (shouldProcessFilter(this, m_filterBBox)) + return false; // clip sourceImage to filterRegion - FloatRect clippedSourceRect = targetRect; + FloatRect clippedSourceRect = paintRect; clippedSourceRect.intersect(m_filterBBox); // scale filter size to filterRes @@ -110,7 +120,7 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj fitsInMaximumImageSize(tempSourceRect.size()); // prepare Filters - m_filter = SVGFilter::create(targetRect, m_filterBBox, m_effectBBoxMode); + m_filter = SVGFilter::create(paintRect, m_filterBBox, m_effectBBoxMode); m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY)); FilterEffect* lastEffect = m_filterBuilder->lastEffect(); @@ -122,7 +132,8 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY)); lastEffect->calculateEffectRect(m_filter.get()); } - } + } else + return false; clippedSourceRect.scale(m_scaleX, m_scaleY); @@ -132,23 +143,21 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj OwnPtr<ImageBuffer> sourceGraphic(ImageBuffer::create(bufferRect.size(), LinearRGB)); if (!sourceGraphic.get()) - return; + return false; GraphicsContext* sourceGraphicContext = sourceGraphic->context(); + sourceGraphicContext->translate(-clippedSourceRect.x(), -clippedSourceRect.y()); sourceGraphicContext->scale(FloatSize(m_scaleX, m_scaleY)); - sourceGraphicContext->translate(-targetRect.x(), -targetRect.y()); - sourceGraphicContext->clearRect(FloatRect(FloatPoint(), targetRect.size())); + sourceGraphicContext->clearRect(FloatRect(FloatPoint(), paintRect.size())); m_sourceGraphicBuffer.set(sourceGraphic.release()); m_savedContext = context; context = sourceGraphicContext; + return true; } void SVGResourceFilter::applyFilter(GraphicsContext*& context, const RenderObject* object) { - if (shouldProcessFilter(this)) - return; - if (!m_savedContext) return; @@ -204,9 +213,9 @@ TextStream& SVGResourceFilter::externalRepresentation(TextStream& ts) const return ts; } -SVGResourceFilter* getFilterById(Document* document, const AtomicString& id) +SVGResourceFilter* getFilterById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isFilter()) return static_cast<SVGResourceFilter*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceFilter.h b/WebCore/svg/graphics/SVGResourceFilter.h index ffd926d..ee8627c 100644 --- a/WebCore/svg/graphics/SVGResourceFilter.h +++ b/WebCore/svg/graphics/SVGResourceFilter.h @@ -68,10 +68,10 @@ public: float scaleX() const { return m_scaleX; } float scaleY() const { return m_scaleY; } - FloatRect filterBoundingBox() { return m_filterBBox; } + FloatRect filterBoundingBox(const FloatRect& obb) const; void setFilterBoundingBox(const FloatRect& rect) { m_filterBBox = rect; } - void prepareFilter(GraphicsContext*&, const RenderObject*); + bool prepareFilter(GraphicsContext*&, const RenderObject*); void applyFilter(GraphicsContext*&, const RenderObject*); bool fitsInMaximumImageSize(const FloatSize&); @@ -103,7 +103,7 @@ private: RefPtr<Filter> m_filter; }; -SVGResourceFilter* getFilterById(Document*, const AtomicString&); +SVGResourceFilter* getFilterById(Document*, const AtomicString&, const RenderObject*); } // namespace WebCore diff --git a/WebCore/svg/graphics/SVGResourceMarker.cpp b/WebCore/svg/graphics/SVGResourceMarker.cpp index 112e4d6..955c048 100644 --- a/WebCore/svg/graphics/SVGResourceMarker.cpp +++ b/WebCore/svg/graphics/SVGResourceMarker.cpp @@ -38,10 +38,8 @@ namespace WebCore { SVGResourceMarker::SVGResourceMarker() : SVGResource() - , m_refX(0.0) - , m_refY(0.0) , m_angle(-1) // just like using setAutoAngle() - , m_marker(0) + , m_renderer(0) , m_useStrokeWidth(true) { } @@ -50,20 +48,20 @@ SVGResourceMarker::~SVGResourceMarker() { } -void SVGResourceMarker::setMarker(RenderSVGViewportContainer* marker) +TransformationMatrix SVGResourceMarker::markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const { - m_marker = marker; -} + ASSERT(m_renderer); -void SVGResourceMarker::setRef(double refX, double refY) -{ - m_refX = refX; - m_refY = refY; + TransformationMatrix transform; + transform.translate(origin.x(), origin.y()); + transform.rotate(m_angle == -1 ? angle : m_angle); + transform = m_renderer->markerContentTransformation(transform, m_referencePoint, m_useStrokeWidth ? strokeWidth : -1); + return transform; } -void SVGResourceMarker::draw(GraphicsContext* context, const FloatRect& rect, double x, double y, double strokeWidth, double angle) +void SVGResourceMarker::draw(RenderObject::PaintInfo& paintInfo, const TransformationMatrix& transform) { - if (!m_marker) + if (!m_renderer) return; DEFINE_STATIC_LOCAL(HashSet<SVGResourceMarker*>, currentlyDrawingMarkers, ()); @@ -73,45 +71,18 @@ void SVGResourceMarker::draw(GraphicsContext* context, const FloatRect& rect, do return; currentlyDrawingMarkers.add(this); - - TransformationMatrix transform; - transform.translate(x, y); - transform.rotate(m_angle > -1 ? m_angle : angle); - - // refX and refY are given in coordinates relative to the viewport established by the marker, yet they affect - // the translation performed on the viewport itself. - TransformationMatrix viewportTransform; - if (m_useStrokeWidth) - viewportTransform.scaleNonUniform(strokeWidth, strokeWidth); - viewportTransform *= m_marker->viewportTransform(); - double refX, refY; - viewportTransform.map(m_refX, m_refY, refX, refY); - transform.translate(-refX, -refY); - - if (m_useStrokeWidth) - transform.scaleNonUniform(strokeWidth, strokeWidth); - - // FIXME: PaintInfo should be passed into this method instead of being created here - // FIXME: bounding box fractions are lost - RenderObject::PaintInfo info(context, enclosingIntRect(rect), PaintPhaseForeground, 0, 0, 0); - - context->save(); - context->concatCTM(transform); - m_marker->setDrawsContents(true); - m_marker->paint(info, 0, 0); - m_marker->setDrawsContents(false); - context->restore(); - - m_cachedBounds = transform.mapRect(m_marker->absoluteClippedOverflowRect()); + ASSERT(!m_renderer->drawsContents()); + RenderObject::PaintInfo info(paintInfo); + info.context->save(); + applyTransformToPaintInfo(info, transform); + m_renderer->setDrawsContents(true); + m_renderer->paint(info, 0, 0); + m_renderer->setDrawsContents(false); + info.context->restore(); currentlyDrawingMarkers.remove(this); } -FloatRect SVGResourceMarker::cachedBounds() const -{ - return m_cachedBounds; -} - TextStream& SVGResourceMarker::externalRepresentation(TextStream& ts) const { ts << "[type=MARKER]" @@ -122,13 +93,13 @@ TextStream& SVGResourceMarker::externalRepresentation(TextStream& ts) const else ts << angle() << "]"; - ts << " [ref x=" << refX() << " y=" << refY() << "]"; + ts << " [ref x=" << m_referencePoint.x() << " y=" << m_referencePoint.y() << "]"; return ts; } -SVGResourceMarker* getMarkerById(Document* document, const AtomicString& id) +SVGResourceMarker* getMarkerById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isMarker()) return static_cast<SVGResourceMarker*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceMarker.h b/WebCore/svg/graphics/SVGResourceMarker.h index bb4039c..5c98d2f 100644 --- a/WebCore/svg/graphics/SVGResourceMarker.h +++ b/WebCore/svg/graphics/SVGResourceMarker.h @@ -27,25 +27,26 @@ #define SVGResourceMarker_h #if ENABLE(SVG) - +#include "FloatPoint.h" #include "FloatRect.h" +#include "RenderObject.h" #include "SVGResource.h" namespace WebCore { - class GraphicsContext; class RenderSVGViewportContainer; + class TransformationMatrix; class SVGResourceMarker : public SVGResource { public: static PassRefPtr<SVGResourceMarker> create() { return adoptRef(new SVGResourceMarker); } virtual ~SVGResourceMarker(); - void setMarker(RenderSVGViewportContainer*); + RenderSVGViewportContainer* renderer() const { return m_renderer; } + void setRenderer(RenderSVGViewportContainer* marker) { m_renderer = marker; } - void setRef(double refX, double refY); - double refX() const { return m_refX; } - double refY() const { return m_refY; } + void setReferencePoint(const FloatPoint& point) { m_referencePoint = point; } + FloatPoint referencePoint() const { return m_referencePoint; } void setAngle(float angle) { m_angle = angle; } void setAutoAngle() { m_angle = -1; } @@ -54,22 +55,22 @@ namespace WebCore { void setUseStrokeWidth(bool useStrokeWidth = true) { m_useStrokeWidth = useStrokeWidth; } bool useStrokeWidth() const { return m_useStrokeWidth; } - FloatRect cachedBounds() const; - void draw(GraphicsContext*, const FloatRect&, double x, double y, double strokeWidth = 1, double angle = 0); - + TransformationMatrix markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const; + void draw(RenderObject::PaintInfo&, const TransformationMatrix&); + virtual SVGResourceType resourceType() const { return MarkerResourceType; } virtual TextStream& externalRepresentation(TextStream&) const; private: SVGResourceMarker(); - double m_refX, m_refY; - FloatRect m_cachedBounds; + + FloatPoint m_referencePoint; float m_angle; - RenderSVGViewportContainer* m_marker; + RenderSVGViewportContainer* m_renderer; bool m_useStrokeWidth; }; - SVGResourceMarker* getMarkerById(Document*, const AtomicString&); + SVGResourceMarker* getMarkerById(Document*, const AtomicString&, const RenderObject*); } // namespace WebCore diff --git a/WebCore/svg/graphics/SVGResourceMasker.cpp b/WebCore/svg/graphics/SVGResourceMasker.cpp index 97467c1..18bc71a 100644 --- a/WebCore/svg/graphics/SVGResourceMasker.cpp +++ b/WebCore/svg/graphics/SVGResourceMasker.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * 2009 Dirk Schulze <krit@webkit.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,13 +34,12 @@ #include "ImageBuffer.h" #include "ImageData.h" #include "GraphicsContext.h" +#include "RenderObject.h" #include "SVGMaskElement.h" #include "SVGRenderSupport.h" #include "SVGRenderStyle.h" #include "TextStream.h" -#include <wtf/ByteArray.h> - using namespace std; namespace WebCore { @@ -47,6 +47,7 @@ namespace WebCore { SVGResourceMasker::SVGResourceMasker(const SVGMaskElement* ownerElement) : SVGResource() , m_ownerElement(ownerElement) + , m_emptyMask(false) { } @@ -58,44 +59,24 @@ void SVGResourceMasker::invalidate() { SVGResource::invalidate(); m_mask.clear(); + m_emptyMask = false; } -void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& boundingBox) +FloatRect SVGResourceMasker::maskerBoundingBox(const FloatRect& objectBoundingBox) const { - if (!m_mask) - m_mask = m_ownerElement->drawMaskerContent(boundingBox, m_maskRect); - - if (!m_mask) - return; - - IntSize imageSize(m_mask->size()); - IntRect intImageRect(0, 0, imageSize.width(), imageSize.height()); - - // Create new ImageBuffer to apply luminance - OwnPtr<ImageBuffer> luminancedImage = ImageBuffer::create(imageSize); - if (!luminancedImage) - return; - - PassRefPtr<CanvasPixelArray> srcPixelArray(m_mask->getUnmultipliedImageData(intImageRect)->data()); - PassRefPtr<ImageData> destImageData(luminancedImage->getUnmultipliedImageData(intImageRect)); - - for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset++) { - unsigned pixelByteOffset = pixelOffset * 4; - - unsigned char r = 0, g = 0, b = 0, a = 0; - srcPixelArray->get(pixelByteOffset, r); - srcPixelArray->get(pixelByteOffset + 1, g); - srcPixelArray->get(pixelByteOffset + 2, b); - srcPixelArray->get(pixelByteOffset + 3, a); - - double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); + return m_ownerElement->maskBoundingBox(objectBoundingBox); +} - destImageData->data()->set(pixelByteOffset + 3, luma); - } +bool SVGResourceMasker::applyMask(GraphicsContext* context, const RenderObject* object) +{ + if (!m_mask && !m_emptyMask) + m_mask = m_ownerElement->drawMaskerContent(object, m_maskRect, m_emptyMask); - luminancedImage->putUnmultipliedImageData(destImageData.get(), intImageRect, IntPoint(0, 0)); + if (!m_mask) + return false; - context->clipToImageBuffer(m_maskRect, luminancedImage.get()); + context->clipToImageBuffer(m_maskRect, m_mask.get()); + return true; } TextStream& SVGResourceMasker::externalRepresentation(TextStream& ts) const @@ -104,9 +85,9 @@ TextStream& SVGResourceMasker::externalRepresentation(TextStream& ts) const return ts; } -SVGResourceMasker* getMaskerById(Document* document, const AtomicString& id) +SVGResourceMasker* getMaskerById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isMasker()) return static_cast<SVGResourceMasker*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceMasker.h b/WebCore/svg/graphics/SVGResourceMasker.h index f945f56..27364c2 100644 --- a/WebCore/svg/graphics/SVGResourceMasker.h +++ b/WebCore/svg/graphics/SVGResourceMasker.h @@ -29,6 +29,8 @@ #if ENABLE(SVG) #include "GraphicsContext.h" +#include "RenderObject.h" +#include "SVGMaskElement.h" #include "SVGResource.h" #include <memory> @@ -52,8 +54,8 @@ namespace WebCore { virtual SVGResourceType resourceType() const { return MaskerResourceType; } virtual TextStream& externalRepresentation(TextStream&) const; - // To be implemented by the specific rendering devices - void applyMask(GraphicsContext*, const FloatRect& boundingBox); + FloatRect maskerBoundingBox(const FloatRect&) const; + bool applyMask(GraphicsContext*, const RenderObject*); private: SVGResourceMasker(const SVGMaskElement*); @@ -62,9 +64,10 @@ namespace WebCore { OwnPtr<ImageBuffer> m_mask; FloatRect m_maskRect; + bool m_emptyMask; }; - SVGResourceMasker* getMaskerById(Document*, const AtomicString&); + SVGResourceMasker* getMaskerById(Document*, const AtomicString&, const RenderObject* object); } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEImage.cpp b/WebCore/svg/graphics/filters/SVGFEImage.cpp index e82328a..331de4f 100644 --- a/WebCore/svg/graphics/filters/SVGFEImage.cpp +++ b/WebCore/svg/graphics/filters/SVGFEImage.cpp @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> + 2010 Dirk Schulze <krit@webkit.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -23,50 +24,42 @@ #if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEImage.h" -#include "SVGRenderTreeAsText.h" + #include "Filter.h" +#include "GraphicsContext.h" +#include "SVGPreserveAspectRatio.h" +#include "SVGRenderTreeAsText.h" +#include "TransformationMatrix.h" namespace WebCore { -FEImage::FEImage(CachedImage* cachedImage) +FEImage::FEImage(RefPtr<Image> image, SVGPreserveAspectRatio preserveAspectRatio) : FilterEffect() - , m_cachedImage(cachedImage) + , m_image(image) + , m_preserveAspectRatio(preserveAspectRatio) { - m_cachedImage->addClient(this); } -PassRefPtr<FEImage> FEImage::create(CachedImage* cachedImage) +PassRefPtr<FEImage> FEImage::create(RefPtr<Image> image, SVGPreserveAspectRatio preserveAspectRatio) { - return adoptRef(new FEImage(cachedImage)); + return adoptRef(new FEImage(image, preserveAspectRatio)); } -FEImage::~FEImage() -{ - if (m_cachedImage) - m_cachedImage->removeClient(this); -} - -CachedImage* FEImage::cachedImage() const +void FEImage::apply(Filter*) { - return m_cachedImage.get(); -} + if (!m_image.get()) + return; -void FEImage::setCachedImage(CachedImage* image) -{ - if (m_cachedImage == image) + GraphicsContext* filterContext = getEffectContext(); + if (!filterContext) return; - - if (m_cachedImage) - m_cachedImage->removeClient(this); - m_cachedImage = image; + FloatRect srcRect(FloatPoint(), m_image->size()); + FloatRect destRect(FloatPoint(), subRegion().size()); - if (m_cachedImage) - m_cachedImage->addClient(this); -} + m_preserveAspectRatio.transformRect(destRect, srcRect); -void FEImage::apply(Filter*) -{ + filterContext->drawImage(m_image.get(), DeviceColorSpace, destRect, srcRect); } void FEImage::dump() diff --git a/WebCore/svg/graphics/filters/SVGFEImage.h b/WebCore/svg/graphics/filters/SVGFEImage.h index f29d266..0883aad 100644 --- a/WebCore/svg/graphics/filters/SVGFEImage.h +++ b/WebCore/svg/graphics/filters/SVGFEImage.h @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> + 2010 Dirk Schulze <krit@webkit.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -23,33 +24,26 @@ #define SVGFEImage_h #if ENABLE(SVG) && ENABLE(FILTERS) -#include "CachedImage.h" -#include "CachedResourceClient.h" -#include "CachedResourceHandle.h" +#include "Image.h" #include "FilterEffect.h" #include "Filter.h" +#include "SVGPreserveAspectRatio.h" namespace WebCore { - class FEImage : public FilterEffect - , public CachedResourceClient { + class FEImage : public FilterEffect { public: - static PassRefPtr<FEImage> create(CachedImage*); - virtual ~FEImage(); - - // FIXME: We need to support <svg> (RenderObject*) as well as image data. - - CachedImage* cachedImage() const; - void setCachedImage(CachedImage*); + static PassRefPtr<FEImage> create(RefPtr<Image>, SVGPreserveAspectRatio); void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream& ts) const; private: - FEImage(CachedImage*); + FEImage(RefPtr<Image>, SVGPreserveAspectRatio); - CachedResourceHandle<CachedImage> m_cachedImage; + RefPtr<Image> m_image; + SVGPreserveAspectRatio m_preserveAspectRatio; }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.cpp b/WebCore/svg/graphics/filters/SVGFEMerge.cpp index 3f9ad38..6ea0fb9 100644 --- a/WebCore/svg/graphics/filters/SVGFEMerge.cpp +++ b/WebCore/svg/graphics/filters/SVGFEMerge.cpp @@ -30,23 +30,23 @@ namespace WebCore { -FEMerge::FEMerge(const Vector<FilterEffect*>& mergeInputs) +FEMerge::FEMerge(const Vector<RefPtr<FilterEffect> >& mergeInputs) : FilterEffect() , m_mergeInputs(mergeInputs) { } -PassRefPtr<FEMerge> FEMerge::create(const Vector<FilterEffect*>& mergeInputs) +PassRefPtr<FEMerge> FEMerge::create(const Vector<RefPtr<FilterEffect> >& mergeInputs) { return adoptRef(new FEMerge(mergeInputs)); } -const Vector<FilterEffect*>& FEMerge::mergeInputs() const +const Vector<RefPtr<FilterEffect> >& FEMerge::mergeInputs() const { return m_mergeInputs; } -void FEMerge::setMergeInputs(const Vector<FilterEffect*>& mergeInputs) +void FEMerge::setMergeInputs(const Vector<RefPtr<FilterEffect> >& mergeInputs) { m_mergeInputs = mergeInputs; } diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.h b/WebCore/svg/graphics/filters/SVGFEMerge.h index 02fbfac..7653be3 100644 --- a/WebCore/svg/graphics/filters/SVGFEMerge.h +++ b/WebCore/svg/graphics/filters/SVGFEMerge.h @@ -31,10 +31,10 @@ namespace WebCore { class FEMerge : public FilterEffect { public: - static PassRefPtr<FEMerge> create(const Vector<FilterEffect*>&); + static PassRefPtr<FEMerge> create(const Vector<RefPtr<FilterEffect> >&); - const Vector<FilterEffect*>& mergeInputs() const; - void setMergeInputs(const Vector<FilterEffect*>& mergeInputs); + const Vector<RefPtr<FilterEffect> >& mergeInputs() const; + void setMergeInputs(const Vector<RefPtr<FilterEffect> >& mergeInputs); virtual FloatRect uniteChildEffectSubregions(Filter*); void apply(Filter*); @@ -42,9 +42,9 @@ namespace WebCore { TextStream& externalRepresentation(TextStream& ts) const; private: - FEMerge(const Vector<FilterEffect*>&); + FEMerge(const Vector<RefPtr<FilterEffect> >&); - Vector<FilterEffect*> m_mergeInputs; + Vector<RefPtr<FilterEffect> > m_mergeInputs; }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp index 20d109a..987350d 100644 --- a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp +++ b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp @@ -90,6 +90,8 @@ void FEMorphology::apply(Filter* filter) if (!getEffectContext()) return; + setIsAlphaImage(m_in->isAlphaImage()); + if (!m_radiusX || !m_radiusY) return; diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.cpp b/WebCore/svg/graphics/filters/SVGFEOffset.cpp index 9fd50ed..0066c3e 100644 --- a/WebCore/svg/graphics/filters/SVGFEOffset.cpp +++ b/WebCore/svg/graphics/filters/SVGFEOffset.cpp @@ -74,6 +74,8 @@ void FEOffset::apply(Filter* filter) if (!filterContext) return; + setIsAlphaImage(m_in->isAlphaImage()); + FloatRect sourceImageRect = filter->sourceImageRect(); sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); diff --git a/WebCore/svg/graphics/filters/SVGFETile.cpp b/WebCore/svg/graphics/filters/SVGFETile.cpp index e97f68f..42da34d 100644 --- a/WebCore/svg/graphics/filters/SVGFETile.cpp +++ b/WebCore/svg/graphics/filters/SVGFETile.cpp @@ -58,6 +58,8 @@ void FETile::apply(Filter* filter) if (!filterContext) return; + setIsAlphaImage(m_in->isAlphaImage()); + IntRect tileRect = enclosingIntRect(m_in->scaledSubRegion()); // Source input needs more attention. It has the size of the filterRegion but gives the diff --git a/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp b/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp index 67668d6..fc6924a 100644 --- a/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp +++ b/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp @@ -42,14 +42,14 @@ SVGFilterBuilder::SVGFilterBuilder() void SVGFilterBuilder::add(const AtomicString& id, RefPtr<FilterEffect> effect) { if (id.isEmpty()) { - m_lastEffect = effect.get(); + m_lastEffect = effect; return; } if (m_builtinEffects.contains(id)) return; - m_lastEffect = effect.get(); + m_lastEffect = effect; m_namedEffects.set(id, m_lastEffect); } diff --git a/WebCore/svg/svgattrs.in b/WebCore/svg/svgattrs.in index 1ab5b06..6081039 100644 --- a/WebCore/svg/svgattrs.in +++ b/WebCore/svg/svgattrs.in @@ -2,7 +2,6 @@ namespace="SVG" namespaceURI="http://www.w3.org/2000/svg" guardFactoryWith="ENABLE(SVG)" attrsNullNamespace -exportStrings accent-height accumulate diff --git a/WebCore/svg/svgtags.in b/WebCore/svg/svgtags.in index ca1ea89..adc05f2 100644 --- a/WebCore/svg/svgtags.in +++ b/WebCore/svg/svgtags.in @@ -1,7 +1,6 @@ namespace="SVG" namespaceURI="http://www.w3.org/2000/svg" guardFactoryWith="ENABLE(SVG)" -exportStrings a createWithNew #if ENABLE_SVG_FONTS diff --git a/WebCore/svg/xlinkattrs.in b/WebCore/svg/xlinkattrs.in index 2e48903..6e7fef1 100644 --- a/WebCore/svg/xlinkattrs.in +++ b/WebCore/svg/xlinkattrs.in @@ -1,6 +1,5 @@ namespace="XLink" namespaceURI="http://www.w3.org/1999/xlink" -exportStrings actuate arcrole |