diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/svg | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/svg')
564 files changed, 13537 insertions, 15991 deletions
diff --git a/Source/WebCore/svg/ColorDistance.cpp b/Source/WebCore/svg/ColorDistance.cpp deleted file mode 100644 index c0e04fd50..000000000 --- a/Source/WebCore/svg/ColorDistance.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2007 Eric Seidel <eric@webkit.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. - */ - -#include "config.h" -#if ENABLE(SVG) -#include "ColorDistance.h" - -#include "Color.h" -#include <wtf/MathExtras.h> - -namespace WebCore { - -ColorDistance::ColorDistance() - : m_redDiff(0) - , m_greenDiff(0) - , m_blueDiff(0) -{ -} - -ColorDistance::ColorDistance(const Color& fromColor, const Color& toColor) - : m_redDiff(toColor.red() - fromColor.red()) - , m_greenDiff(toColor.green() - fromColor.green()) - , m_blueDiff(toColor.blue() - fromColor.blue()) -{ -} - -ColorDistance::ColorDistance(int redDiff, int greenDiff, int blueDiff) - : m_redDiff(redDiff) - , m_greenDiff(greenDiff) - , m_blueDiff(blueDiff) -{ -} - -static inline int clampColorValue(int v) -{ - if (v > 255) - v = 255; - else if (v < 0) - v = 0; - return v; -} - -ColorDistance ColorDistance::scaledDistance(float scaleFactor) const -{ - return ColorDistance(static_cast<int>(scaleFactor * m_redDiff), - static_cast<int>(scaleFactor * m_greenDiff), - static_cast<int>(scaleFactor * m_blueDiff)); -} - -Color ColorDistance::clampColor(int red, int green, int blue, int alpha) -{ - return Color(clampColorValue(red), clampColorValue(green), clampColorValue(blue), clampColorValue(alpha)); -} - -Color ColorDistance::addColors(const Color& first, const Color& second) -{ - return Color(first.red() + second.red(), first.green() + second.green(), first.blue() + second.blue()); -} - -Color ColorDistance::addToColor(const Color& color) const -{ - return Color(color.red() + m_redDiff, color.green() + m_greenDiff, color.blue() + m_blueDiff); -} - -bool ColorDistance::isZero() const -{ - return !m_redDiff && !m_blueDiff && !m_greenDiff; -} - -float ColorDistance::distance() const -{ - // This is just a simple distance calculation, not respecting color spaces - return sqrtf(m_redDiff * m_redDiff + m_blueDiff * m_blueDiff + m_greenDiff * m_greenDiff); -} - -} - -#endif diff --git a/Source/WebCore/svg/GradientAttributes.h b/Source/WebCore/svg/GradientAttributes.h index 084a42710..e01f1fa16 100644 --- a/Source/WebCore/svg/GradientAttributes.h +++ b/Source/WebCore/svg/GradientAttributes.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef GradientAttributes_h -#define GradientAttributes_h +#pragma once -#if ENABLE(SVG) #include "SVGGradientElement.h" #include "SVGUnitTypes.h" @@ -95,6 +93,3 @@ struct SameSizeAsGradientAttributes { COMPILE_ASSERT(sizeof(GradientAttributes) == sizeof(SameSizeAsGradientAttributes), GradientAttributes_size_guard); } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/LinearGradientAttributes.h b/Source/WebCore/svg/LinearGradientAttributes.h index 6ff28f1fe..f52019fff 100644 --- a/Source/WebCore/svg/LinearGradientAttributes.h +++ b/Source/WebCore/svg/LinearGradientAttributes.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef LinearGradientAttributes_h -#define LinearGradientAttributes_h +#pragma once -#if ENABLE(SVG) #include "GradientAttributes.h" namespace WebCore { @@ -37,15 +35,15 @@ struct LinearGradientAttributes : GradientAttributes { { } - SVGLength x1() const { return m_x1; } - SVGLength y1() const { return m_y1; } - SVGLength x2() const { return m_x2; } - SVGLength y2() const { return m_y2; } + SVGLengthValue x1() const { return m_x1; } + SVGLengthValue y1() const { return m_y1; } + SVGLengthValue x2() const { return m_x2; } + SVGLengthValue y2() const { return m_y2; } - void setX1(const SVGLength& value) { m_x1 = value; m_x1Set = true; } - void setY1(const SVGLength& value) { m_y1 = value; m_y1Set = true; } - void setX2(const SVGLength& value) { m_x2 = value; m_x2Set = true; } - void setY2(const SVGLength& value) { m_y2 = value; m_y2Set = true; } + void setX1(SVGLengthValue value) { m_x1 = value; m_x1Set = true; } + void setY1(SVGLengthValue value) { m_y1 = value; m_y1Set = true; } + void setX2(SVGLengthValue value) { m_x2 = value; m_x2Set = true; } + void setY2(SVGLengthValue value) { m_y2 = value; m_y2Set = true; } bool hasX1() const { return m_x1Set; } bool hasY1() const { return m_y1Set; } @@ -54,10 +52,10 @@ struct LinearGradientAttributes : GradientAttributes { private: // Properties - SVGLength m_x1; - SVGLength m_y1; - SVGLength m_x2; - SVGLength m_y2; + SVGLengthValue m_x1; + SVGLengthValue m_y1; + SVGLengthValue m_x2; + SVGLengthValue m_y2; // Property states bool m_x1Set : 1; @@ -67,8 +65,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/PatternAttributes.h b/Source/WebCore/svg/PatternAttributes.h index 3677b74fa..5bed0bef5 100644 --- a/Source/WebCore/svg/PatternAttributes.h +++ b/Source/WebCore/svg/PatternAttributes.h @@ -17,12 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef PatternAttributes_h -#define PatternAttributes_h +#pragma once -#if ENABLE(SVG) -#include "SVGLength.h" -#include "SVGPreserveAspectRatio.h" +#include "SVGLengthValue.h" +#include "SVGPreserveAspectRatioValue.h" namespace WebCore { @@ -38,7 +36,7 @@ struct PatternAttributes { , m_preserveAspectRatio() , m_patternUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) , m_patternContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_patternContentElement(0) + , m_patternContentElement(nullptr) , m_xSet(false) , m_ySet(false) , m_widthSet(false) @@ -52,36 +50,36 @@ struct PatternAttributes { { } - SVGLength x() const { return m_x; } - SVGLength y() const { return m_y; } - SVGLength width() const { return m_width; } - SVGLength height() const { return m_height; } + SVGLengthValue x() const { return m_x; } + SVGLengthValue y() const { return m_y; } + SVGLengthValue width() const { return m_width; } + SVGLengthValue height() const { return m_height; } FloatRect viewBox() const { return m_viewBox; } - SVGPreserveAspectRatio preserveAspectRatio() const { return m_preserveAspectRatio; } + SVGPreserveAspectRatioValue preserveAspectRatio() const { return m_preserveAspectRatio; } SVGUnitTypes::SVGUnitType patternUnits() const { return m_patternUnits; } SVGUnitTypes::SVGUnitType patternContentUnits() const { return m_patternContentUnits; } AffineTransform patternTransform() const { return m_patternTransform; } const SVGPatternElement* patternContentElement() const { return m_patternContentElement; } - void setX(const SVGLength& value) + void setX(SVGLengthValue value) { m_x = value; m_xSet = true; } - void setY(const SVGLength& value) + void setY(SVGLengthValue value) { m_y = value; m_ySet = true; } - void setWidth(const SVGLength& value) + void setWidth(SVGLengthValue value) { m_width = value; m_widthSet = true; } - void setHeight(const SVGLength& value) + void setHeight(SVGLengthValue value) { m_height = value; m_heightSet = true; @@ -93,7 +91,7 @@ struct PatternAttributes { m_viewBoxSet = true; } - void setPreserveAspectRatio(const SVGPreserveAspectRatio& value) + void setPreserveAspectRatio(SVGPreserveAspectRatioValue value) { m_preserveAspectRatio = value; m_preserveAspectRatioSet = true; @@ -136,12 +134,12 @@ struct PatternAttributes { private: // Properties - SVGLength m_x; - SVGLength m_y; - SVGLength m_width; - SVGLength m_height; + SVGLengthValue m_x; + SVGLengthValue m_y; + SVGLengthValue m_width; + SVGLengthValue m_height; FloatRect m_viewBox; - SVGPreserveAspectRatio m_preserveAspectRatio; + SVGPreserveAspectRatioValue m_preserveAspectRatio; SVGUnitTypes::SVGUnitType m_patternUnits; SVGUnitTypes::SVGUnitType m_patternContentUnits; AffineTransform m_patternTransform; @@ -161,6 +159,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/RadialGradientAttributes.h b/Source/WebCore/svg/RadialGradientAttributes.h index 9613956c9..87be72288 100644 --- a/Source/WebCore/svg/RadialGradientAttributes.h +++ b/Source/WebCore/svg/RadialGradientAttributes.h @@ -17,13 +17,12 @@ * Boston, MA 02110-1301, USA. */ -#ifndef RadialGradientAttributes_h -#define RadialGradientAttributes_h +#pragma once -#if ENABLE(SVG) #include "GradientAttributes.h" namespace WebCore { + struct RadialGradientAttributes : GradientAttributes { RadialGradientAttributes() : m_cx(LengthModeWidth, "50%") @@ -38,19 +37,19 @@ struct RadialGradientAttributes : GradientAttributes { { } - SVGLength cx() const { return m_cx; } - SVGLength cy() const { return m_cy; } - SVGLength r() const { return m_r; } - SVGLength fx() const { return m_fx; } - SVGLength fy() const { return m_fy; } - SVGLength fr() const { return m_fr; } + SVGLengthValue cx() const { return m_cx; } + SVGLengthValue cy() const { return m_cy; } + SVGLengthValue r() const { return m_r; } + SVGLengthValue fx() const { return m_fx; } + SVGLengthValue fy() const { return m_fy; } + SVGLengthValue fr() const { return m_fr; } - void setCx(const SVGLength& value) { m_cx = value; m_cxSet = true; } - void setCy(const SVGLength& value) { m_cy = value; m_cySet = true; } - void setR(const SVGLength& value) { m_r = value; m_rSet = true; } - void setFx(const SVGLength& value) { m_fx = value; m_fxSet = true; } - void setFy(const SVGLength& value) { m_fy = value; m_fySet = true; } - void setFr(const SVGLength& value) { m_fr = value; m_frSet = true; } + void setCx(SVGLengthValue value) { m_cx = value; m_cxSet = true; } + void setCy(SVGLengthValue value) { m_cy = value; m_cySet = true; } + void setR(SVGLengthValue value) { m_r = value; m_rSet = true; } + void setFx(SVGLengthValue value) { m_fx = value; m_fxSet = true; } + void setFy(SVGLengthValue value) { m_fy = value; m_fySet = true; } + void setFr(SVGLengthValue value) { m_fr = value; m_frSet = true; } bool hasCx() const { return m_cxSet; } bool hasCy() const { return m_cySet; } @@ -61,12 +60,12 @@ struct RadialGradientAttributes : GradientAttributes { private: // Properties - SVGLength m_cx; - SVGLength m_cy; - SVGLength m_r; - SVGLength m_fx; - SVGLength m_fy; - SVGLength m_fr; + SVGLengthValue m_cx; + SVGLengthValue m_cy; + SVGLengthValue m_r; + SVGLengthValue m_fx; + SVGLengthValue m_fy; + SVGLengthValue m_fr; // Property states bool m_cxSet : 1; @@ -78,8 +77,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGAElement.cpp b/Source/WebCore/svg/SVGAElement.cpp index f6fbbc669..710dece81 100644 --- a/Source/WebCore/svg/SVGAElement.cpp +++ b/Source/WebCore/svg/SVGAElement.cpp @@ -21,15 +21,10 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAElement.h" -#include "Attr.h" -#include "Attribute.h" #include "Document.h" #include "EventHandler.h" -#include "EventNames.h" #include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderTypes.h" @@ -42,15 +37,12 @@ #include "RenderSVGText.h" #include "RenderSVGTransformableContainer.h" #include "ResourceRequest.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGSMILElement.h" #include "XLinkNames.h" namespace WebCore { -using namespace HTMLNames; - // Animated property definitions DEFINE_ANIMATED_STRING(SVGAElement, SVGNames::targetAttr, SVGTarget, svgTarget) DEFINE_ANIMATED_STRING(SVGAElement, XLinkNames::hrefAttr, Href, href) @@ -70,15 +62,15 @@ inline SVGAElement::SVGAElement(const QualifiedName& tagName, Document& document registerAnimatedPropertiesForSVGAElement(); } -PassRefPtr<SVGAElement> SVGAElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGAElement> SVGAElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGAElement(tagName, document)); + return adoptRef(*new SVGAElement(tagName, document)); } String SVGAElement::title() const { // If the xlink:title is set (non-empty string), use it. - const AtomicString& title = fastGetAttribute(XLinkNames::titleAttr); + const AtomicString& title = attributeWithoutSynchronization(XLinkNames::titleAttr); if (!title.isEmpty()) return title; @@ -86,84 +78,57 @@ String SVGAElement::title() const return SVGElement::title(); } -bool SVGAElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGURIReference::addSupportedAttributes(supportedAttributes); - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::targetAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGAElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGGraphicsElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::targetAttr) { setSVGTargetBaseValue(value); return; } - if (SVGURIReference::parseAttribute(name, value)) - return; - if (SVGLangSpace::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGGraphicsElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGAElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGGraphicsElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - // Unlike other SVG*Element classes, SVGAElement only listens to SVGURIReference changes - // as none of the other properties changes the linking behaviour for our <a> element. if (SVGURIReference::isKnownAttribute(attrName)) { bool wasLink = isLink(); setIsLink(!href().isNull() && !shouldProhibitLinks(this)); - if (wasLink != isLink()) - setNeedsStyleRecalc(); + if (wasLink != isLink()) { + InstanceInvalidationGuard guard(*this); + invalidateStyleForSubtree(); + } } + + SVGGraphicsElement::svgAttributeChanged(attrName); } -RenderPtr<RenderElement> SVGAElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGAElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - if (parentNode() && parentNode()->isSVGElement() && toSVGElement(parentNode())->isTextContent()) - return createRenderer<RenderSVGInline>(*this, std::move(style)); + if (parentNode() && parentNode()->isSVGElement() && downcast<SVGElement>(*parentNode()).isTextContent()) + return createRenderer<RenderSVGInline>(*this, WTFMove(style)); - return createRenderer<RenderSVGTransformableContainer>(*this, std::move(style)); + return createRenderer<RenderSVGTransformableContainer>(*this, WTFMove(style)); } -void SVGAElement::defaultEventHandler(Event* event) +void SVGAElement::defaultEventHandler(Event& event) { if (isLink()) { if (focused() && isEnterKeyKeydownEvent(event)) { - event->setDefaultHandled(); - dispatchSimulatedClick(event); + event.setDefaultHandled(); + dispatchSimulatedClick(&event); return; } - if (isLinkClick(event)) { + if (MouseEvent::canTriggerActivationBehavior(event)) { String url = stripLeadingAndTrailingHTMLSpaces(href()); if (url[0] == '#') { - Element* targetElement = treeScope().getElementById(url.substring(1)); - if (targetElement && isSVGSMILElement(*targetElement)) { - toSVGSMILElement(*targetElement).beginByLinkActivation(); - event->setDefaultHandled(); + Element* targetElement = treeScope().getElementById(url.substringSharingImpl(1)); + if (is<SVGSMILElement>(targetElement)) { + downcast<SVGSMILElement>(*targetElement).beginByLinkActivation(); + event.setDefaultHandled(); return; } // Only allow navigation to internal <view> anchors. @@ -172,14 +137,14 @@ void SVGAElement::defaultEventHandler(Event* event) } String target = this->target(); - if (target.isEmpty() && fastGetAttribute(XLinkNames::showAttr) == "new") + if (target.isEmpty() && attributeWithoutSynchronization(XLinkNames::showAttr) == "new") target = "_blank"; - event->setDefaultHandled(); + event.setDefaultHandled(); Frame* frame = document().frame(); if (!frame) return; - frame->loader().urlSelected(document().completeURL(url), target, event, false, false, MaybeSendReferrer); + frame->loader().urlSelected(document().completeURL(url), target, &event, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate()); return; } } @@ -187,11 +152,18 @@ void SVGAElement::defaultEventHandler(Event* event) SVGGraphicsElement::defaultEventHandler(event); } +int SVGAElement::tabIndex() const +{ + // Skip the supportsFocus check in SVGElement. + return Element::tabIndex(); +} + bool SVGAElement::supportsFocus() const { if (hasEditableStyle()) return SVGGraphicsElement::supportsFocus(); - return true; + // If not a link we should still be able to focus the element if it has a tabIndex. + return isLink() || Element::supportsFocus(); } bool SVGAElement::isFocusable() const @@ -204,23 +176,36 @@ bool SVGAElement::isFocusable() const bool SVGAElement::isURLAttribute(const Attribute& attribute) const { - return attribute.name().localName() == hrefAttr || SVGGraphicsElement::isURLAttribute(attribute); + return attribute.name().localName() == XLinkNames::hrefAttr || SVGGraphicsElement::isURLAttribute(attribute); } bool SVGAElement::isMouseFocusable() const { - return false; + // Links are focusable by default, but only allow links with tabindex or contenteditable to be mouse focusable. + // https://bugs.webkit.org/show_bug.cgi?id=26856 + if (isLink()) + return Element::supportsFocus(); + + return SVGElement::isMouseFocusable(); } -bool SVGAElement::isKeyboardFocusable(KeyboardEvent* event) const +bool SVGAElement::isKeyboardFocusable(KeyboardEvent& event) const { - if (!isFocusable()) - return false; - - if (!document().frame()) - return false; - - return document().frame()->eventHandler().tabsToLinks(event); + if (isFocusable() && Element::supportsFocus()) + return SVGElement::isKeyboardFocusable(event); + + if (isLink()) + return document().frame()->eventHandler().tabsToLinks(event); + + return SVGElement::isKeyboardFocusable(event); +} + +bool SVGAElement::canStartSelection() const +{ + if (!isLink()) + return SVGElement::canStartSelection(); + + return hasEditableStyle(); } bool SVGAElement::childShouldCreateRenderer(const Node& child) const @@ -229,8 +214,9 @@ bool SVGAElement::childShouldCreateRenderer(const Node& child) const // The 'a' element may contain any element that its parent may contain, except itself. if (child.hasTagName(SVGNames::aTag)) return false; - if (parentNode() && parentNode()->isSVGElement()) - return parentNode()->childShouldCreateRenderer(child); + + if (parentElement() && parentElement()->isSVGElement()) + return parentElement()->childShouldCreateRenderer(child); return SVGElement::childShouldCreateRenderer(child); } @@ -241,5 +227,3 @@ bool SVGAElement::willRespondToMouseClickEvents() } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAElement.h b/Source/WebCore/svg/SVGAElement.h index 00f0a7f35..f6202f95b 100644 --- a/Source/WebCore/svg/SVGAElement.h +++ b/Source/WebCore/svg/SVGAElement.h @@ -19,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAElement_h -#define SVGAElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGExternalResourcesRequired.h" #include "SVGGraphicsElement.h" @@ -34,43 +32,41 @@ class SVGAElement final : public SVGGraphicsElement, public SVGURIReference, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGAElement> create(const QualifiedName&, Document&); + static Ref<SVGAElement> create(const QualifiedName&, Document&); private: SVGAElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } + bool isValid() const final { return SVGTests::isValid(); } - virtual String title() const override; - virtual String target() const override { return svgTarget(); } + String title() const final; + String target() const final { return svgTarget(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool childShouldCreateRenderer(const Node&) const override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; + bool childShouldCreateRenderer(const Node&) const final; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) final; - virtual bool supportsFocus() const override; - virtual bool isMouseFocusable() const override; - virtual bool isKeyboardFocusable(KeyboardEvent*) const override; - virtual bool isFocusable() const override; - virtual bool isURLAttribute(const Attribute&) const override; + bool supportsFocus() const final; + bool isMouseFocusable() const final; + bool isKeyboardFocusable(KeyboardEvent&) const final; + bool isFocusable() const final; + bool isURLAttribute(const Attribute&) const final; + bool canStartSelection() const final; + int tabIndex() const final; - virtual bool willRespondToMouseClickEvents() override; + bool willRespondToMouseClickEvents() final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAElement) // This declaration used to define a non-virtual "String& target() const" method, that clashes with "virtual String Element::target() const". // That's why it has been renamed to "svgTarget", the CodeGenerators take care of calling svgTargetAnimated() instead of targetAnimated(), see CodeGenerator.pm. DECLARE_ANIMATED_STRING(SVGTarget, svgTarget) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAElement_h diff --git a/Source/WebCore/svg/SVGAElement.idl b/Source/WebCore/svg/SVGAElement.idl index bbaa6892d..3ede6dc9c 100644 --- a/Source/WebCore/svg/SVGAElement.idl +++ b/Source/WebCore/svg/SVGAElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGAElement : SVGGraphicsElement { +interface SVGAElement : SVGGraphicsElement { [ImplementedAs=svgTarget] readonly attribute SVGAnimatedString target; }; diff --git a/Source/WebCore/svg/SVGAllInOne.cpp b/Source/WebCore/svg/SVGAllInOne.cpp new file mode 100644 index 000000000..d4aca4275 --- /dev/null +++ b/Source/WebCore/svg/SVGAllInOne.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build. + +#include "SVGAElement.cpp" +#include "SVGAltGlyphDefElement.cpp" +#include "SVGAltGlyphElement.cpp" +#include "SVGAltGlyphItemElement.cpp" +#include "SVGAnimateColorElement.cpp" +#include "SVGAnimateElement.cpp" +#include "SVGAnimateElementBase.cpp" +#include "SVGAnimateMotionElement.cpp" +#include "SVGAnimateTransformElement.cpp" +#include "SVGAnimatedAngle.cpp" +#include "SVGAnimatedBoolean.cpp" +#include "SVGAnimatedColor.cpp" +#include "SVGAnimatedEnumeration.cpp" +#include "SVGAnimatedInteger.cpp" +#include "SVGAnimatedIntegerOptionalInteger.cpp" +#include "SVGAnimatedLength.cpp" +#include "SVGAnimatedLengthList.cpp" +#include "SVGAnimatedNumber.cpp" +#include "SVGAnimatedNumberList.cpp" +#include "SVGAnimatedNumberOptionalNumber.cpp" +#include "SVGAnimatedPath.cpp" +#include "SVGAnimatedPointList.cpp" +#include "SVGAnimatedPreserveAspectRatio.cpp" +#include "SVGAnimatedRect.cpp" +#include "SVGAnimatedString.cpp" +#include "SVGAnimatedTransformList.cpp" +#include "SVGAnimatedType.cpp" +#include "SVGAnimatedTypeAnimator.cpp" +#include "SVGAnimationElement.cpp" +#include "SVGCircleElement.cpp" +#include "SVGClipPathElement.cpp" +#include "SVGComponentTransferFunctionElement.cpp" +#include "SVGCursorElement.cpp" +#include "SVGDefsElement.cpp" +#include "SVGDescElement.cpp" +#include "SVGDocument.cpp" +#include "SVGDocumentExtensions.cpp" +#include "SVGElement.cpp" +#include "SVGEllipseElement.cpp" +#include "SVGException.cpp" +#include "SVGExternalResourcesRequired.cpp" +#include "SVGFEBlendElement.cpp" +#include "SVGFEColorMatrixElement.cpp" +#include "SVGFEComponentTransferElement.cpp" +#include "SVGFECompositeElement.cpp" +#include "SVGFEConvolveMatrixElement.cpp" +#include "SVGFEDiffuseLightingElement.cpp" +#include "SVGFEDisplacementMapElement.cpp" +#include "SVGFEDistantLightElement.cpp" +#include "SVGFEDropShadowElement.cpp" +#include "SVGFEFloodElement.cpp" +#include "SVGFEFuncAElement.cpp" +#include "SVGFEFuncBElement.cpp" +#include "SVGFEFuncGElement.cpp" +#include "SVGFEFuncRElement.cpp" +#include "SVGFEGaussianBlurElement.cpp" +#include "SVGFEImageElement.cpp" +#include "SVGFELightElement.cpp" +#include "SVGFEMergeElement.cpp" +#include "SVGFEMergeNodeElement.cpp" +#include "SVGFEMorphologyElement.cpp" +#include "SVGFEOffsetElement.cpp" +#include "SVGFEPointLightElement.cpp" +#include "SVGFESpecularLightingElement.cpp" +#include "SVGFESpotLightElement.cpp" +#include "SVGFETileElement.cpp" +#include "SVGFETurbulenceElement.cpp" +#include "SVGFilterElement.cpp" +#include "SVGFilterPrimitiveStandardAttributes.cpp" +#include "SVGFitToViewBox.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 "SVGGlyphRefElement.cpp" +#include "SVGGradientElement.cpp" +#include "SVGGraphicsElement.cpp" +#include "SVGHKernElement.cpp" +#include "SVGImageElement.cpp" +#include "SVGImageLoader.cpp" +#include "SVGLangSpace.cpp" +#include "SVGLengthContext.cpp" +#include "SVGLengthListValues.cpp" +#include "SVGLineElement.cpp" +#include "SVGLinearGradientElement.cpp" +#include "SVGLocatable.cpp" +#include "SVGMPathElement.cpp" +#include "SVGMarkerElement.cpp" +#include "SVGMaskElement.cpp" +#include "SVGMetadataElement.cpp" +#include "SVGMissingGlyphElement.cpp" +#include "SVGNumberListValues.cpp" +#include "SVGParserUtilities.cpp" +#include "SVGPathBlender.cpp" +#include "SVGPathBuilder.cpp" +#include "SVGPathByteStreamBuilder.cpp" +#include "SVGPathByteStreamSource.cpp" +#include "SVGPathElement.cpp" +#include "SVGPathParser.cpp" +#include "SVGPathSegList.cpp" +#include "SVGPathSegListBuilder.cpp" +#include "SVGPathSegListSource.cpp" +#include "SVGPathSegListValues.cpp" +#include "SVGPathStringBuilder.cpp" +#include "SVGPathStringSource.cpp" +#include "SVGPathTraversalStateBuilder.cpp" +#include "SVGPathUtilities.cpp" +#include "SVGPatternElement.cpp" +#include "SVGPointListValues.cpp" +#include "SVGPolyElement.cpp" +#include "SVGPolygonElement.cpp" +#include "SVGPolylineElement.cpp" +#include "SVGPreserveAspectRatioValue.cpp" +#include "SVGRadialGradientElement.cpp" +#include "SVGRectElement.cpp" +#include "SVGSVGElement.cpp" +#include "SVGScriptElement.cpp" +#include "SVGSetElement.cpp" +#include "SVGStopElement.cpp" +#include "SVGStringListValues.cpp" +#include "SVGStyleElement.cpp" +#include "SVGSwitchElement.cpp" +#include "SVGSymbolElement.cpp" +#include "SVGTRefElement.cpp" +#include "SVGTSpanElement.cpp" +#include "SVGTests.cpp" +#include "SVGTextContentElement.cpp" +#include "SVGTextElement.cpp" +#include "SVGTextPathElement.cpp" +#include "SVGTextPositioningElement.cpp" +#include "SVGTitleElement.cpp" +#include "SVGTransform.cpp" +#include "SVGTransformDistance.cpp" +#include "SVGTransformListValues.cpp" +#include "SVGTransformable.cpp" +#include "SVGURIReference.cpp" +#include "SVGUseElement.cpp" +#include "SVGVKernElement.cpp" +#include "SVGViewElement.cpp" +#include "SVGViewSpec.cpp" +#include "SVGZoomAndPan.cpp" +#include "SVGZoomEvent.cpp" diff --git a/Source/WebCore/svg/SVGAltGlyphDefElement.cpp b/Source/WebCore/svg/SVGAltGlyphDefElement.cpp index 099c40f67..91f8879f3 100644 --- a/Source/WebCore/svg/SVGAltGlyphDefElement.cpp +++ b/Source/WebCore/svg/SVGAltGlyphDefElement.cpp @@ -19,7 +19,7 @@ #include "config.h" -#if ENABLE(SVG) && ENABLE(SVG_FONTS) +#if ENABLE(SVG_FONTS) #include "SVGAltGlyphDefElement.h" #include "ElementIterator.h" @@ -35,9 +35,9 @@ inline SVGAltGlyphDefElement::SVGAltGlyphDefElement(const QualifiedName& tagName ASSERT(hasTagName(SVGNames::altGlyphDefTag)); } -PassRefPtr<SVGAltGlyphDefElement> SVGAltGlyphDefElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGAltGlyphDefElement> SVGAltGlyphDefElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGAltGlyphDefElement(tagName, document)); + return adoptRef(*new SVGAltGlyphDefElement(tagName, document)); } bool SVGAltGlyphDefElement::hasValidGlyphElements(Vector<String>& glyphNames) const @@ -90,11 +90,11 @@ bool SVGAltGlyphDefElement::hasValidGlyphElements(Vector<String>& glyphNames) co bool foundFirstAltGlyphItem = false; for (auto& child : childrenOfType<SVGElement>(*this)) { - if (!foundFirstAltGlyphItem && isSVGGlyphRefElement(child)) { + if (!foundFirstAltGlyphItem && is<SVGGlyphRefElement>(child)) { fountFirstGlyphRef = true; String referredGlyphName; - if (toSVGGlyphRefElement(child).hasValidGlyphElement(referredGlyphName)) + if (downcast<SVGGlyphRefElement>(child).hasValidGlyphElement(referredGlyphName)) glyphNames.append(referredGlyphName); else { // As the spec says "If any of the referenced glyphs are unavailable, @@ -104,12 +104,12 @@ bool SVGAltGlyphDefElement::hasValidGlyphElements(Vector<String>& glyphNames) co glyphNames.clear(); return false; } - } else if (!fountFirstGlyphRef && isSVGAltGlyphItemElement(child)) { + } else if (!fountFirstGlyphRef && is<SVGAltGlyphItemElement>(child)) { foundFirstAltGlyphItem = true; // As the spec says "The first 'altGlyphItem' in which all referenced glyphs // are available is chosen." - if (toSVGAltGlyphItemElement(child).hasValidGlyphElements(glyphNames) && !glyphNames.isEmpty()) + if (downcast<SVGAltGlyphItemElement>(child).hasValidGlyphElements(glyphNames) && !glyphNames.isEmpty()) return true; } } diff --git a/Source/WebCore/svg/SVGAltGlyphDefElement.h b/Source/WebCore/svg/SVGAltGlyphDefElement.h index 5a818db37..40996a5f3 100644 --- a/Source/WebCore/svg/SVGAltGlyphDefElement.h +++ b/Source/WebCore/svg/SVGAltGlyphDefElement.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAltGlyphDefElement_h -#define SVGAltGlyphDefElement_h +#pragma once + +#if ENABLE(SVG_FONTS) -#if ENABLE(SVG) && ENABLE(SVG_FONTS) #include "SVGElement.h" #include <wtf/Vector.h> @@ -28,20 +28,16 @@ namespace WebCore { class SVGAltGlyphDefElement final : public SVGElement { public: - static PassRefPtr<SVGAltGlyphDefElement> create(const QualifiedName&, Document&); + static Ref<SVGAltGlyphDefElement> create(const QualifiedName&, Document&); bool hasValidGlyphElements(Vector<String>& glyphNames) const; private: SVGAltGlyphDefElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGAltGlyphDefElement) - -} - -#endif -#endif +} // namespace WebCore +#endif // ENABLE(SVG_FONTS) diff --git a/Source/WebCore/svg/SVGAltGlyphDefElement.idl b/Source/WebCore/svg/SVGAltGlyphDefElement.idl index abe10b672..72721faab 100644 --- a/Source/WebCore/svg/SVGAltGlyphDefElement.idl +++ b/Source/WebCore/svg/SVGAltGlyphDefElement.idl @@ -17,6 +17,6 @@ * Boston, MA 02110-1301, USA. */ -[Conditional=SVG&SVG_FONTS] interface SVGAltGlyphDefElement : SVGElement { +[Conditional=SVG_FONTS] interface SVGAltGlyphDefElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGAltGlyphElement.cpp b/Source/WebCore/svg/SVGAltGlyphElement.cpp index 6df3bebb1..ddcea7401 100644 --- a/Source/WebCore/svg/SVGAltGlyphElement.cpp +++ b/Source/WebCore/svg/SVGAltGlyphElement.cpp @@ -21,9 +21,9 @@ */ #include "config.h" +#include "SVGAltGlyphElement.h" #if ENABLE(SVG_FONTS) -#include "SVGAltGlyphElement.h" #include "ExceptionCode.h" #include "RenderInline.h" @@ -50,57 +50,52 @@ inline SVGAltGlyphElement::SVGAltGlyphElement(const QualifiedName& tagName, Docu registerAnimatedPropertiesForSVGAltGlyphElement(); } -PassRefPtr<SVGAltGlyphElement> SVGAltGlyphElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGAltGlyphElement> SVGAltGlyphElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGAltGlyphElement(tagName, document)); + return adoptRef(*new SVGAltGlyphElement(tagName, document)); } -void SVGAltGlyphElement::setGlyphRef(const AtomicString&, ExceptionCode& ec) +ExceptionOr<void> SVGAltGlyphElement::setGlyphRef(const AtomicString&) { - ec = NO_MODIFICATION_ALLOWED_ERR; + return Exception { NO_MODIFICATION_ALLOWED_ERR }; } const AtomicString& SVGAltGlyphElement::glyphRef() const { - return fastGetAttribute(SVGNames::glyphRefAttr); + return attributeWithoutSynchronization(SVGNames::glyphRefAttr); } -void SVGAltGlyphElement::setFormat(const AtomicString&, ExceptionCode& ec) +ExceptionOr<void> SVGAltGlyphElement::setFormat(const AtomicString&) { - ec = NO_MODIFICATION_ALLOWED_ERR; + return Exception { NO_MODIFICATION_ALLOWED_ERR }; } const AtomicString& SVGAltGlyphElement::format() const { - return fastGetAttribute(SVGNames::formatAttr); + return attributeWithoutSynchronization(SVGNames::formatAttr); } bool SVGAltGlyphElement::childShouldCreateRenderer(const Node& child) const { - if (child.isTextNode()) - return true; - return false; + return child.isTextNode(); } -RenderPtr<RenderElement> SVGAltGlyphElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGAltGlyphElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGTSpan>(*this, std::move(style)); + return createRenderer<RenderSVGTSpan>(*this, WTFMove(style)); } bool SVGAltGlyphElement::hasValidGlyphElements(Vector<String>& glyphNames) const { String target; - Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &target); - if (!element) - return false; + auto* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &target); - if (isSVGGlyphElement(element)) { + if (is<SVGGlyphElement>(element)) { glyphNames.append(target); return true; } - if (isSVGAltGlyphDefElement(element) - && toSVGAltGlyphDefElement(element)->hasValidGlyphElements(glyphNames)) + if (is<SVGAltGlyphDefElement>(element) && downcast<SVGAltGlyphDefElement>(*element).hasValidGlyphElements(glyphNames)) return true; return false; @@ -108,4 +103,4 @@ bool SVGAltGlyphElement::hasValidGlyphElements(Vector<String>& glyphNames) const } -#endif // ENABLE(SVG) +#endif diff --git a/Source/WebCore/svg/SVGAltGlyphElement.h b/Source/WebCore/svg/SVGAltGlyphElement.h index b99afda5c..93f490885 100644 --- a/Source/WebCore/svg/SVGAltGlyphElement.h +++ b/Source/WebCore/svg/SVGAltGlyphElement.h @@ -19,44 +19,39 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAltGlyphElement_h -#define SVGAltGlyphElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGTextPositioningElement.h" #include "SVGURIReference.h" -#include <wtf/Vector.h> namespace WebCore { class SVGGlyphElement; -class SVGAltGlyphElement final : public SVGTextPositioningElement, - public SVGURIReference { +class SVGAltGlyphElement final : public SVGTextPositioningElement, public SVGURIReference { public: - static PassRefPtr<SVGAltGlyphElement> create(const QualifiedName&, Document&); + static Ref<SVGAltGlyphElement> create(const QualifiedName&, Document&); const AtomicString& glyphRef() const; - void setGlyphRef(const AtomicString&, ExceptionCode&); + ExceptionOr<void> setGlyphRef(const AtomicString&); const AtomicString& format() const; - void setFormat(const AtomicString&, ExceptionCode&); + ExceptionOr<void> setFormat(const AtomicString&); bool hasValidGlyphElements(Vector<String>& glyphNames) const; private: SVGAltGlyphElement(const QualifiedName&, Document&); - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool childShouldCreateRenderer(const Node&) const override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool childShouldCreateRenderer(const Node&) const override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAltGlyphElement) - DECLARE_ANIMATED_STRING(Href, href) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGAltGlyphElement) - } // namespace WebCore -#endif // ENABLE(SVG) #endif diff --git a/Source/WebCore/svg/SVGAltGlyphElement.idl b/Source/WebCore/svg/SVGAltGlyphElement.idl index 9bb3f1671..a76e6af72 100644 --- a/Source/WebCore/svg/SVGAltGlyphElement.idl +++ b/Source/WebCore/svg/SVGAltGlyphElement.idl @@ -24,10 +24,10 @@ */ [ - Conditional=SVG&SVG_FONTS, + Conditional=SVG_FONTS, ] interface SVGAltGlyphElement : SVGTextPositioningElement { - [SetterRaisesException] attribute DOMString glyphRef; - [SetterRaisesException] attribute DOMString format; + [SetterMayThrowException] attribute DOMString glyphRef; + [SetterMayThrowException] attribute DOMString format; }; SVGAltGlyphElement implements SVGURIReference; diff --git a/Source/WebCore/svg/SVGAltGlyphItemElement.cpp b/Source/WebCore/svg/SVGAltGlyphItemElement.cpp index 42c8ddbb7..21aeb8ff1 100644 --- a/Source/WebCore/svg/SVGAltGlyphItemElement.cpp +++ b/Source/WebCore/svg/SVGAltGlyphItemElement.cpp @@ -19,7 +19,7 @@ #include "config.h" -#if ENABLE(SVG) && ENABLE(SVG_FONTS) +#if ENABLE(SVG_FONTS) #include "SVGAltGlyphItemElement.h" #include "ElementIterator.h" @@ -34,9 +34,9 @@ inline SVGAltGlyphItemElement::SVGAltGlyphItemElement(const QualifiedName& tagNa ASSERT(hasTagName(SVGNames::altGlyphItemTag)); } -PassRefPtr<SVGAltGlyphItemElement> SVGAltGlyphItemElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGAltGlyphItemElement> SVGAltGlyphItemElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGAltGlyphItemElement(tagName, document)); + return adoptRef(*new SVGAltGlyphItemElement(tagName, document)); } bool SVGAltGlyphItemElement::hasValidGlyphElements(Vector<String>& glyphNames) const diff --git a/Source/WebCore/svg/SVGAltGlyphItemElement.h b/Source/WebCore/svg/SVGAltGlyphItemElement.h index d86b1945c..840a92815 100644 --- a/Source/WebCore/svg/SVGAltGlyphItemElement.h +++ b/Source/WebCore/svg/SVGAltGlyphItemElement.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAltGlyphItemElement_h -#define SVGAltGlyphItemElement_h +#pragma once + +#if ENABLE(SVG_FONTS) -#if ENABLE(SVG) && ENABLE(SVG_FONTS) #include "SVGElement.h" #include <wtf/Vector.h> @@ -28,20 +28,16 @@ namespace WebCore { class SVGAltGlyphItemElement final : public SVGElement { public: - static PassRefPtr<SVGAltGlyphItemElement> create(const QualifiedName&, Document&); + static Ref<SVGAltGlyphItemElement> create(const QualifiedName&, Document&); bool hasValidGlyphElements(Vector<String>& glyphNames) const; private: SVGAltGlyphItemElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGAltGlyphItemElement) - -} - -#endif -#endif +} // namespace WebCore +#endif // ENABLE(SVG_FONTS) diff --git a/Source/WebCore/svg/SVGAltGlyphItemElement.idl b/Source/WebCore/svg/SVGAltGlyphItemElement.idl index e4bb7975e..2b627084a 100644 --- a/Source/WebCore/svg/SVGAltGlyphItemElement.idl +++ b/Source/WebCore/svg/SVGAltGlyphItemElement.idl @@ -17,6 +17,6 @@ * Boston, MA 02110-1301, USA. */ -[Conditional=SVG&SVG_FONTS] interface SVGAltGlyphItemElement : SVGElement { +[Conditional=SVG_FONTS] interface SVGAltGlyphItemElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGAngle.h b/Source/WebCore/svg/SVGAngle.h index f127fd458..c7d5a5f54 100644 --- a/Source/WebCore/svg/SVGAngle.h +++ b/Source/WebCore/svg/SVGAngle.h @@ -1,73 +1,156 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> - * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGAngle_h -#define SVGAngle_h +#pragma once -#if ENABLE(SVG) -#include "SVGPropertyTraits.h" +#include "ExceptionCode.h" +#include "SVGAngleValue.h" +#include "SVGPropertyTearOff.h" namespace WebCore { -typedef int ExceptionCode; - -class SVGAngle { - WTF_MAKE_FAST_ALLOCATED; +class SVGAngle : public SVGPropertyTearOff<SVGAngleValue> { public: - SVGAngle(); + static Ref<SVGAngle> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGAngleValue& value) + { + return adoptRef(*new SVGAngle(animatedProperty, role, value)); + } + + static Ref<SVGAngle> create(const SVGAngleValue& initialValue = { }) + { + return adoptRef(*new SVGAngle(initialValue)); + } + + static Ref<SVGAngle> create(const SVGAngleValue* initialValue) + { + return adoptRef(*new SVGAngle(initialValue)); + } + + template<typename T> static ExceptionOr<Ref<SVGAngle>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } + + SVGAngleValue::Type unitType() + { + return propertyReference().unitType(); + } + + ExceptionOr<void> setValueForBindings(float value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; - enum SVGAngleType { - SVG_ANGLETYPE_UNKNOWN = 0, - SVG_ANGLETYPE_UNSPECIFIED = 1, - SVG_ANGLETYPE_DEG = 2, - SVG_ANGLETYPE_RAD = 3, - SVG_ANGLETYPE_GRAD = 4 - }; + propertyReference().setValue(value); + commitChange(); - SVGAngleType unitType() const { return m_unitType; } + return { }; + } + + float valueForBindings() + { + return propertyReference().value(); + } - void setValue(float); - float value() const; + ExceptionOr<void> setValueInSpecifiedUnits(float valueInSpecifiedUnits) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; - void setValueInSpecifiedUnits(float valueInSpecifiedUnits) { m_valueInSpecifiedUnits = valueInSpecifiedUnits; } - float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; } + propertyReference().setValueInSpecifiedUnits(valueInSpecifiedUnits); + commitChange(); + + return { }; + } + + float valueInSpecifiedUnits() + { + return propertyReference().valueInSpecifiedUnits(); + } - void setValueAsString(const String&, ExceptionCode&); - String valueAsString() const; + ExceptionOr<void> setValueAsString(const String& value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; - void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionCode&); - void convertToSpecifiedUnits(unsigned short unitType, ExceptionCode&); + auto result = propertyReference().setValueAsString(value); + if (result.hasException()) + return result; + + commitChange(); + return result; + } + + String valueAsString() + { + return propertyReference().valueAsString(); + } + + ExceptionOr<void> newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().newValueSpecifiedUnits(unitType, valueInSpecifiedUnits); + if (result.hasException()) + return result; + + commitChange(); + return result; + } + + ExceptionOr<void> convertToSpecifiedUnits(unsigned short unitType) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().convertToSpecifiedUnits(unitType); + if (result.hasException()) + return result; + + commitChange(); + return result; + } private: - SVGAngleType m_unitType; - float m_valueInSpecifiedUnits; -}; + SVGAngle(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGAngleValue& value) + : SVGPropertyTearOff<SVGAngleValue>(&animatedProperty, role, value) + { + } + + explicit SVGAngle(const SVGAngleValue& initialValue) + : SVGPropertyTearOff<SVGAngleValue>(initialValue) + { + } -template<> -struct SVGPropertyTraits<SVGAngle> { - static SVGAngle initialValue() { return SVGAngle(); } - static String toString(const SVGAngle& type) { return type.valueAsString(); } + explicit SVGAngle(const SVGAngleValue* initialValue) + : SVGPropertyTearOff<SVGAngleValue>(initialValue) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAngle_h diff --git a/Source/WebCore/svg/SVGAngle.idl b/Source/WebCore/svg/SVGAngle.idl index a03f0a754..25b634585 100644 --- a/Source/WebCore/svg/SVGAngle.idl +++ b/Source/WebCore/svg/SVGAngle.idl @@ -21,7 +21,7 @@ */ [ - Conditional=SVG, + ConstantsScope=SVGAngleValue ] interface SVGAngle { // Angle Unit Types const unsigned short SVG_ANGLETYPE_UNKNOWN = 0; @@ -31,13 +31,11 @@ const unsigned short SVG_ANGLETYPE_GRAD = 4; readonly attribute unsigned short unitType; - [StrictTypeChecking] attribute float value; - [StrictTypeChecking] attribute float valueInSpecifiedUnits; + [SetterMayThrowException, ImplementedAs=valueForBindings] attribute unrestricted float value; + [SetterMayThrowException] attribute unrestricted float valueInSpecifiedUnits; - [TreatNullAs=NullString, SetterRaisesException] attribute DOMString valueAsString; + [SetterMayThrowException] attribute DOMString valueAsString; - [StrictTypeChecking, RaisesException] void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits); - - [StrictTypeChecking, RaisesException] void convertToSpecifiedUnits(unsigned short unitType); + [MayThrowException] void newValueSpecifiedUnits(unsigned short unitType, unrestricted float valueInSpecifiedUnits); + [MayThrowException] void convertToSpecifiedUnits(unsigned short unitType); }; - diff --git a/Source/WebCore/svg/SVGAngle.cpp b/Source/WebCore/svg/SVGAngleValue.cpp index cb4aa6f01..9511d147c 100644 --- a/Source/WebCore/svg/SVGAngle.cpp +++ b/Source/WebCore/svg/SVGAngleValue.cpp @@ -20,24 +20,16 @@ */ #include "config.h" - -#if ENABLE(SVG) -#include "SVGAngle.h" +#include "SVGAngleValue.h" #include "ExceptionCode.h" #include "SVGParserUtilities.h" #include <wtf/MathExtras.h> -#include <wtf/text/WTFString.h> +#include <wtf/text/StringView.h> namespace WebCore { -SVGAngle::SVGAngle() - : m_unitType(SVG_ANGLETYPE_UNSPECIFIED) - , m_valueInSpecifiedUnits(0) -{ -} - -float SVGAngle::value() const +float SVGAngleValue::value() const { switch (m_unitType) { case SVG_ANGLETYPE_GRAD: @@ -49,82 +41,37 @@ float SVGAngle::value() const case SVG_ANGLETYPE_DEG: return m_valueInSpecifiedUnits; } - ASSERT_NOT_REACHED(); return 0; } -void SVGAngle::setValue(float value) +void SVGAngleValue::setValue(float value) { switch (m_unitType) { case SVG_ANGLETYPE_GRAD: m_valueInSpecifiedUnits = deg2grad(value); - break; + return; case SVG_ANGLETYPE_RAD: m_valueInSpecifiedUnits = deg2rad(value); - break; + return; case SVG_ANGLETYPE_UNSPECIFIED: case SVG_ANGLETYPE_UNKNOWN: case SVG_ANGLETYPE_DEG: m_valueInSpecifiedUnits = value; - break; + return; } + ASSERT_NOT_REACHED(); } -inline SVGAngle::SVGAngleType stringToAngleType(const UChar*& ptr, const UChar* end) -{ - // If there's no unit given, the angle type is unspecified. - if (ptr == end) - return SVGAngle::SVG_ANGLETYPE_UNSPECIFIED; - - const UChar firstChar = *ptr; - - // If the unit contains only one character, the angle type is unknown. - ++ptr; - if (ptr == end) - return SVGAngle::SVG_ANGLETYPE_UNKNOWN; - - const UChar secondChar = *ptr; - - // If the unit contains only two characters, the angle type is unknown. - ++ptr; - if (ptr == end) - return SVGAngle::SVG_ANGLETYPE_UNKNOWN; - - const UChar thirdChar = *ptr; - if (firstChar == 'd' && secondChar == 'e' && thirdChar == 'g') - return SVGAngle::SVG_ANGLETYPE_DEG; - if (firstChar == 'r' && secondChar == 'a' && thirdChar == 'd') - return SVGAngle::SVG_ANGLETYPE_RAD; - - // If the unit contains three characters, but is not deg or rad, then it's unknown. - ++ptr; - if (ptr == end) - return SVGAngle::SVG_ANGLETYPE_UNKNOWN; - - const UChar fourthChar = *ptr; - - if (firstChar == 'g' && secondChar == 'r' && thirdChar == 'a' && fourthChar == 'd') - return SVGAngle::SVG_ANGLETYPE_GRAD; - - return SVGAngle::SVG_ANGLETYPE_UNKNOWN; -} - -String SVGAngle::valueAsString() const +String SVGAngleValue::valueAsString() const { switch (m_unitType) { - case SVG_ANGLETYPE_DEG: { - DEFINE_STATIC_LOCAL(String, degString, (ASCIILiteral("deg"))); - return String::number(m_valueInSpecifiedUnits) + degString; - } - case SVG_ANGLETYPE_RAD: { - DEFINE_STATIC_LOCAL(String, radString, (ASCIILiteral("rad"))); - return String::number(m_valueInSpecifiedUnits) + radString; - } - case SVG_ANGLETYPE_GRAD: { - DEFINE_STATIC_LOCAL(String, gradString, (ASCIILiteral("grad"))); - return String::number(m_valueInSpecifiedUnits) + gradString; - } + case SVG_ANGLETYPE_DEG: + return String::number(m_valueInSpecifiedUnits) + "deg"; + case SVG_ANGLETYPE_RAD: + return String::number(m_valueInSpecifiedUnits) + "rad"; + case SVG_ANGLETYPE_GRAD: + return String::number(m_valueInSpecifiedUnits) + "grad"; case SVG_ANGLETYPE_UNSPECIFIED: case SVG_ANGLETYPE_UNKNOWN: return String::number(m_valueInSpecifiedUnits); @@ -134,54 +81,66 @@ String SVGAngle::valueAsString() const return String(); } -void SVGAngle::setValueAsString(const String& value, ExceptionCode& ec) +static inline SVGAngleValue::Type parseAngleType(const UChar* ptr, const UChar* end) +{ + switch (end - ptr) { + case 0: + return SVGAngleValue::SVG_ANGLETYPE_UNSPECIFIED; + case 3: + if (ptr[0] == 'd' && ptr[1] == 'e' && ptr[2] == 'g') + return SVGAngleValue::SVG_ANGLETYPE_DEG; + if (ptr[0] == 'r' && ptr[1] == 'a' && ptr[2] == 'd') + return SVGAngleValue::SVG_ANGLETYPE_RAD; + break; + case 4: + if (ptr[0] == 'g' && ptr[1] == 'r' && ptr[2] == 'a' && ptr[3] == 'd') + return SVGAngleValue::SVG_ANGLETYPE_GRAD; + break; + } + return SVGAngleValue::SVG_ANGLETYPE_UNKNOWN; +} + +ExceptionOr<void> SVGAngleValue::setValueAsString(const String& value) { if (value.isEmpty()) { m_unitType = SVG_ANGLETYPE_UNSPECIFIED; - return; + return { }; } - float valueInSpecifiedUnits = 0; - const UChar* ptr = value.deprecatedCharacters(); + auto upconvertedCharacters = StringView(value).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + value.length(); - if (!parseNumber(ptr, end, valueInSpecifiedUnits, false)) { - ec = SYNTAX_ERR; - return; - } + float valueInSpecifiedUnits = 0; + if (!parseNumber(ptr, end, valueInSpecifiedUnits, false)) + return Exception { SYNTAX_ERR }; - SVGAngleType unitType = stringToAngleType(ptr, end); - if (unitType == SVG_ANGLETYPE_UNKNOWN) { - ec = SYNTAX_ERR; - return; - } + auto unitType = parseAngleType(ptr, end); + if (unitType == SVG_ANGLETYPE_UNKNOWN) + return Exception { SYNTAX_ERR }; m_unitType = unitType; m_valueInSpecifiedUnits = valueInSpecifiedUnits; + return { }; } -void SVGAngle::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionCode& ec) +ExceptionOr<void> SVGAngleValue::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits) { - if (unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) { - ec = NOT_SUPPORTED_ERR; - return; - } - - if (unitType != m_unitType) - m_unitType = static_cast<SVGAngleType>(unitType); + if (unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) + return Exception { NOT_SUPPORTED_ERR }; + m_unitType = static_cast<Type>(unitType); m_valueInSpecifiedUnits = valueInSpecifiedUnits; + return { }; } -void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionCode& ec) +ExceptionOr<void> SVGAngleValue::convertToSpecifiedUnits(unsigned short unitType) { - if (unitType == SVG_ANGLETYPE_UNKNOWN || m_unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) { - ec = NOT_SUPPORTED_ERR; - return; - } + if (unitType == SVG_ANGLETYPE_UNKNOWN || m_unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) + return Exception { NOT_SUPPORTED_ERR }; if (unitType == m_unitType) - return; + return { }; switch (m_unitType) { case SVG_ANGLETYPE_RAD: @@ -225,8 +184,8 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionCode& e m_valueInSpecifiedUnits = deg2grad(m_valueInSpecifiedUnits); break; case SVG_ANGLETYPE_UNSPECIFIED: - break; case SVG_ANGLETYPE_DEG: + break; case SVG_ANGLETYPE_UNKNOWN: ASSERT_NOT_REACHED(); break; @@ -237,9 +196,9 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionCode& e break; } - m_unitType = static_cast<SVGAngleType>(unitType); -} + m_unitType = static_cast<Type>(unitType); + return { }; } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGAngleValue.h b/Source/WebCore/svg/SVGAngleValue.h new file mode 100644 index 000000000..370750794 --- /dev/null +++ b/Source/WebCore/svg/SVGAngleValue.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@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 + * 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. + */ + +#pragma once + +#include "ExceptionOr.h" +#include "SVGPropertyTraits.h" + +namespace WebCore { + +class SVGAngleValue { + WTF_MAKE_FAST_ALLOCATED; +public: + enum Type { + SVG_ANGLETYPE_UNKNOWN = 0, + SVG_ANGLETYPE_UNSPECIFIED = 1, + SVG_ANGLETYPE_DEG = 2, + SVG_ANGLETYPE_RAD = 3, + SVG_ANGLETYPE_GRAD = 4 + }; + + Type unitType() const { return m_unitType; } + + void setValue(float); + float value() const; + + void setValueInSpecifiedUnits(float valueInSpecifiedUnits) { m_valueInSpecifiedUnits = valueInSpecifiedUnits; } + float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; } + + ExceptionOr<void> setValueAsString(const String&); + String valueAsString() const; + + ExceptionOr<void> newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits); + ExceptionOr<void> convertToSpecifiedUnits(unsigned short unitType); + +private: + Type m_unitType { SVG_ANGLETYPE_UNSPECIFIED }; + float m_valueInSpecifiedUnits { 0 }; +}; + +template<> struct SVGPropertyTraits<SVGAngleValue> { + static SVGAngleValue initialValue() { return SVGAngleValue(); } + static String toString(const SVGAngleValue& type) { return type.valueAsString(); } +}; + +} diff --git a/Source/WebCore/svg/SVGAnimateColorElement.cpp b/Source/WebCore/svg/SVGAnimateColorElement.cpp index 9bf06ff2a..0fb6d2ba7 100644 --- a/Source/WebCore/svg/SVGAnimateColorElement.cpp +++ b/Source/WebCore/svg/SVGAnimateColorElement.cpp @@ -20,33 +20,32 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimateColorElement.h" + #include "SVGNames.h" namespace WebCore { inline SVGAnimateColorElement::SVGAnimateColorElement(const QualifiedName& tagName, Document& document) - : SVGAnimateElement(tagName, document) + : SVGAnimateElementBase(tagName, document) { ASSERT(hasTagName(SVGNames::animateColorTag)); } -PassRefPtr<SVGAnimateColorElement> SVGAnimateColorElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGAnimateColorElement> SVGAnimateColorElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGAnimateColorElement(tagName, document)); + return adoptRef(*new SVGAnimateColorElement(tagName, document)); } static bool attributeValueIsCurrentColor(const String& value) { - DEFINE_STATIC_LOCAL(const AtomicString, currentColor, ("currentColor", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> currentColor("currentColor", AtomicString::ConstructFromLiteral); return value == currentColor; } void SVGAnimateColorElement::determinePropertyValueTypes(const String& from, const String& to) { - SVGAnimateElement::determinePropertyValueTypes(from, to); + SVGAnimateElementBase::determinePropertyValueTypes(from, to); if (attributeValueIsCurrentColor(from)) m_fromPropertyValueType = CurrentColorValue; if (attributeValueIsCurrentColor(to)) @@ -54,5 +53,3 @@ void SVGAnimateColorElement::determinePropertyValueTypes(const String& from, con } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimateColorElement.h b/Source/WebCore/svg/SVGAnimateColorElement.h index 8888a57d9..359109e07 100644 --- a/Source/WebCore/svg/SVGAnimateColorElement.h +++ b/Source/WebCore/svg/SVGAnimateColorElement.h @@ -19,24 +19,19 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimateColorElement_h -#define SVGAnimateColorElement_h +#pragma once -#if ENABLE(SVG) -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" namespace WebCore { -class SVGAnimateColorElement final : public SVGAnimateElement { +class SVGAnimateColorElement final : public SVGAnimateElementBase { public: - static PassRefPtr<SVGAnimateColorElement> create(const QualifiedName&, Document&); + static Ref<SVGAnimateColorElement> create(const QualifiedName&, Document&); private: SVGAnimateColorElement(const QualifiedName&, Document&); - virtual void determinePropertyValueTypes(const String& from, const String& to) override; + void determinePropertyValueTypes(const String& from, const String& to) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimateColorElement_h diff --git a/Source/WebCore/svg/SVGAnimateColorElement.idl b/Source/WebCore/svg/SVGAnimateColorElement.idl index 930e40698..48fb42c66 100644 --- a/Source/WebCore/svg/SVGAnimateColorElement.idl +++ b/Source/WebCore/svg/SVGAnimateColorElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGAnimateColorElement : SVGAnimationElement { +interface SVGAnimateColorElement : SVGAnimationElement { }; diff --git a/Source/WebCore/svg/SVGAnimateElement.cpp b/Source/WebCore/svg/SVGAnimateElement.cpp index 1789ff3e9..110284e9a 100644 --- a/Source/WebCore/svg/SVGAnimateElement.cpp +++ b/Source/WebCore/svg/SVGAnimateElement.cpp @@ -1,462 +1,42 @@ /* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> - * Copyright (C) 2008 Apple Inc. All rights reserved. - * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2014 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimateElement.h" -#include "CSSParser.h" -#include "CSSPropertyNames.h" -#include "QualifiedName.h" -#include "RenderObject.h" -#include "SVGAnimatorFactory.h" -#include "SVGElement.h" -#include "SVGNames.h" -#include "StyleProperties.h" - namespace WebCore { SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document& document) - : SVGAnimationElement(tagName, document) - , m_animatedPropertyType(AnimatedString) -{ - ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateColorTag) || hasTagName(SVGNames::animateTransformTag)); -} - -PassRefPtr<SVGAnimateElement> SVGAnimateElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGAnimateElement(tagName, document)); -} - -SVGAnimateElement::~SVGAnimateElement() -{ -} - -bool SVGAnimateElement::hasValidAttributeType() -{ - SVGElement* targetElement = this->targetElement(); - if (!targetElement) - return false; - - return m_animatedPropertyType != AnimatedUnknown && !hasInvalidCSSAttributeType(); -} - -AnimatedPropertyType SVGAnimateElement::determineAnimatedPropertyType(SVGElement* targetElement) const -{ - ASSERT(targetElement); - - Vector<AnimatedPropertyType> propertyTypes; - targetElement->animatedPropertyTypeForAttribute(attributeName(), propertyTypes); - if (propertyTypes.isEmpty()) - return AnimatedUnknown; - - ASSERT(propertyTypes.size() <= 2); - AnimatedPropertyType type = propertyTypes[0]; - if (hasTagName(SVGNames::animateColorTag) && type != AnimatedColor) - return AnimatedUnknown; - - // Animations of transform lists are not allowed for <animate> or <set> - // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties - if (type == AnimatedTransformList && !hasTagName(SVGNames::animateTransformTag)) - return AnimatedUnknown; - - // Fortunately there's just one special case needed here: SVGMarkerElements orientAttr, which - // corresponds to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType. We have to - // figure out whose value to change here. - if (targetElement->hasTagName(SVGNames::markerTag) && type == AnimatedAngle) { - ASSERT(propertyTypes.size() == 2); - ASSERT(propertyTypes[0] == AnimatedAngle); - ASSERT(propertyTypes[1] == AnimatedEnumeration); - } else if (propertyTypes.size() == 2) - ASSERT(propertyTypes[0] == propertyTypes[1]); - - return type; -} - -void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) -{ - ASSERT(resultElement); - SVGElement* targetElement = this->targetElement(); - if (!targetElement) - return; - - ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(targetElement)); - - ASSERT(percentage >= 0 && percentage <= 1); - ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag)); - ASSERT(m_animatedPropertyType != AnimatedUnknown); - ASSERT(m_animator); - ASSERT(m_animator->type() == m_animatedPropertyType); - ASSERT(m_fromType); - ASSERT(m_fromType->type() == m_animatedPropertyType); - ASSERT(m_toType); - - SVGAnimateElement* resultAnimationElement = toSVGAnimateElement(resultElement); - ASSERT(resultAnimationElement->m_animatedType); - ASSERT(resultAnimationElement->m_animatedPropertyType == m_animatedPropertyType); - - if (hasTagName(SVGNames::setTag)) - percentage = 1; - - if (calcMode() == CalcModeDiscrete) - percentage = percentage < 0.5 ? 0 : 1; - - // Target element might have changed. - m_animator->setContextElement(targetElement); - - // Be sure to detach list wrappers before we modfiy their underlying value. If we'd do - // if after calculateAnimatedValue() ran the cached pointers in the list propery tear - // offs would point nowhere, and we couldn't create copies of those values anymore, - // while detaching. This is covered by assertions, moving this down would fire them. - if (!m_animatedProperties.isEmpty()) - m_animator->animValWillChange(m_animatedProperties); - - // Values-animation accumulates using the last values entry corresponding to the end of duration time. - SVGAnimatedType* toAtEndOfDurationType = m_toAtEndOfDurationType ? m_toAtEndOfDurationType.get() : m_toType.get(); - m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromType.get(), m_toType.get(), toAtEndOfDurationType, resultAnimationElement->m_animatedType.get()); -} - -bool SVGAnimateElement::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) -{ - if (toAtEndOfDurationString.isEmpty()) - return false; - m_toAtEndOfDurationType = ensureAnimator()->constructFromString(toAtEndOfDurationString); - return true; -} - -bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const String& toString) -{ - SVGElement* targetElement = this->targetElement(); - if (!targetElement) - return false; - - determinePropertyValueTypes(fromString, toString); - ensureAnimator()->calculateFromAndToValues(m_fromType, m_toType, fromString, toString); - ASSERT(m_animatedPropertyType == m_animator->type()); - return true; -} - -bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const String& byString) -{ - SVGElement* targetElement = this->targetElement(); - if (!targetElement) - return false; - - if (animationMode() == ByAnimation && !isAdditive()) - return false; - - // from-by animation may only be used with attributes that support addition (e.g. most numeric attributes). - if (animationMode() == FromByAnimation && !animatedPropertyTypeSupportsAddition()) - return false; - - ASSERT(!hasTagName(SVGNames::setTag)); - - determinePropertyValueTypes(fromString, byString); - ensureAnimator()->calculateFromAndByValues(m_fromType, m_toType, fromString, byString); - ASSERT(m_animatedPropertyType == m_animator->type()); - return true; -} - -#ifndef NDEBUG -static inline bool propertyTypesAreConsistent(AnimatedPropertyType expectedPropertyType, const SVGElementAnimatedPropertyList& animatedTypes) -{ - SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end(); - for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) { - for (size_t i = 0; i < it->properties.size(); ++i) { - if (expectedPropertyType != it->properties[i]->animatedPropertyType()) { - // This is the only allowed inconsistency. SVGAnimatedAngleAnimator handles both SVGAnimatedAngle & SVGAnimatedEnumeration for markers orient attribute. - if (expectedPropertyType == AnimatedAngle && it->properties[i]->animatedPropertyType() == AnimatedEnumeration) - return true; - return false; - } - } - } - - return true; -} -#endif - -void SVGAnimateElement::resetAnimatedType() -{ - SVGAnimatedTypeAnimator* animator = ensureAnimator(); - ASSERT(m_animatedPropertyType == animator->type()); - - SVGElement* targetElement = this->targetElement(); - const QualifiedName& attributeName = this->attributeName(); - ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName); - - if (shouldApply == DontApplyAnimation) - return; - - if (shouldApply == ApplyXMLAnimation) { - // SVG DOM animVal animation code-path. - m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(targetElement, attributeName); - ASSERT(!m_animatedProperties.isEmpty()); - - ASSERT(propertyTypesAreConsistent(m_animatedPropertyType, m_animatedProperties)); - if (!m_animatedType) - m_animatedType = animator->startAnimValAnimation(m_animatedProperties); - else { - animator->resetAnimValToBaseVal(m_animatedProperties, m_animatedType.get()); - animator->animValDidChange(m_animatedProperties); - } - return; - } - - // CSS properties animation code-path. - ASSERT(m_animatedProperties.isEmpty()); - String baseValue; - - if (shouldApply == ApplyCSSAnimation) { - ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName)); - computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue); - } - - if (!m_animatedType) - m_animatedType = animator->constructFromString(baseValue); - else - m_animatedType->setValueAsString(attributeName, baseValue); -} - -static inline void applyCSSPropertyToTarget(SVGElement* targetElement, CSSPropertyID id, const String& value) + : SVGAnimateElementBase(tagName, document) { - ASSERT(!targetElement->m_deletionHasBegun); - - if (!targetElement->ensureAnimatedSMILStyleProperties().setProperty(id, value, false, 0)) - return; - - targetElement->setNeedsStyleRecalc(SyntheticStyleChange); -} - -static inline void removeCSSPropertyFromTarget(SVGElement* targetElement, CSSPropertyID id) -{ - ASSERT(!targetElement->m_deletionHasBegun); - targetElement->ensureAnimatedSMILStyleProperties().removeProperty(id); - targetElement->setNeedsStyleRecalc(SyntheticStyleChange); -} - -static inline void applyCSSPropertyToTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName, const String& valueAsString) -{ - ASSERT(targetElement); - if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode()) - return; - - CSSPropertyID id = cssPropertyID(attributeName.localName()); - - SVGElementInstance::InstanceUpdateBlocker blocker(targetElement); - applyCSSPropertyToTarget(targetElement, id, valueAsString); - - // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. - 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) { - if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement()) - applyCSSPropertyToTarget(shadowTreeElement, id, valueAsString); - } -} - -static inline void removeCSSPropertyFromTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName) -{ - ASSERT(targetElement); - if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode()) - return; - - CSSPropertyID id = cssPropertyID(attributeName.localName()); - - SVGElementInstance::InstanceUpdateBlocker blocker(targetElement); - removeCSSPropertyFromTarget(targetElement, id); - - // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. - 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) { - if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement()) - removeCSSPropertyFromTarget(shadowTreeElement, id); - } -} - -static inline void notifyTargetAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName) -{ - ASSERT(!targetElement->m_deletionHasBegun); - targetElement->svgAttributeChanged(attributeName); -} - -static inline void notifyTargetAndInstancesAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName) -{ - ASSERT(targetElement); - if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode()) - return; - - SVGElementInstance::InstanceUpdateBlocker blocker(targetElement); - notifyTargetAboutAnimValChange(targetElement, attributeName); - - // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. - 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) { - if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement()) - notifyTargetAboutAnimValChange(shadowTreeElement, attributeName); - } -} - -void SVGAnimateElement::clearAnimatedType(SVGElement* targetElement) -{ - if (!m_animatedType) - return; - - if (!targetElement) { - m_animatedType = nullptr; - return; - } - - if (m_animatedProperties.isEmpty()) { - // CSS properties animation code-path. - removeCSSPropertyFromTargetAndInstances(targetElement, attributeName()); - m_animatedType = nullptr; - return; - } - - // SVG DOM animVal animation code-path. - if (m_animator) { - m_animator->stopAnimValAnimation(m_animatedProperties); - notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName()); - } - - m_animatedProperties.clear(); - m_animatedType = nullptr; + ASSERT(hasTagName(SVGNames::animateTag)); } -void SVGAnimateElement::applyResultsToTarget() +Ref<SVGAnimateElement> SVGAnimateElement::create(const QualifiedName& tagName, Document& document) { - ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag)); - ASSERT(m_animatedPropertyType != AnimatedUnknown); - ASSERT(m_animator); - - // Early exit if our animated type got destructed by a previous endedActiveInterval(). - if (!m_animatedType) - return; - - if (m_animatedProperties.isEmpty()) { - // CSS properties animation code-path. - // Convert the result of the animation to a String and apply it as CSS property on the target & all instances. - applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedType->valueAsString()); - return; - } - - // SVG DOM animVal animation code-path. - // At this point the SVG DOM values are already changed, unlike for CSS. - // We only have to trigger update notifications here. - m_animator->animValDidChange(m_animatedProperties); - notifyTargetAndInstancesAboutAnimValChange(targetElement(), attributeName()); -} - -bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() const -{ - // Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties. - switch (m_animatedPropertyType) { - case AnimatedBoolean: - case AnimatedEnumeration: - case AnimatedPreserveAspectRatio: - case AnimatedString: - case AnimatedUnknown: - return false; - case AnimatedAngle: - case AnimatedColor: - case AnimatedInteger: - case AnimatedIntegerOptionalInteger: - case AnimatedLength: - case AnimatedLengthList: - case AnimatedNumber: - case AnimatedNumberList: - case AnimatedNumberOptionalNumber: - case AnimatedPath: - case AnimatedPoints: - case AnimatedRect: - case AnimatedTransformList: - return true; - default: - RELEASE_ASSERT_NOT_REACHED(); - return true; - } -} - -bool SVGAnimateElement::isAdditive() const -{ - if (animationMode() == ByAnimation || animationMode() == FromByAnimation) - if (!animatedPropertyTypeSupportsAddition()) - return false; - - return SVGAnimationElement::isAdditive(); -} - -float SVGAnimateElement::calculateDistance(const String& fromString, const String& toString) -{ - // FIXME: A return value of float is not enough to support paced animations on lists. - SVGElement* targetElement = this->targetElement(); - if (!targetElement) - return -1; - - return ensureAnimator()->calculateDistance(fromString, toString); -} - -void SVGAnimateElement::setTargetElement(SVGElement* target) -{ - SVGAnimationElement::setTargetElement(target); - resetAnimatedPropertyType(); -} - -void SVGAnimateElement::setAttributeName(const QualifiedName& attributeName) -{ - SVGAnimationElement::setAttributeName(attributeName); - resetAnimatedPropertyType(); -} - -void SVGAnimateElement::resetAnimatedPropertyType() -{ - ASSERT(!m_animatedType); - m_fromType = nullptr; - m_toType = nullptr; - m_toAtEndOfDurationType = nullptr; - m_animator = nullptr; - m_animatedPropertyType = targetElement() ? determineAnimatedPropertyType(targetElement()) : AnimatedString; -} - -SVGAnimatedTypeAnimator* SVGAnimateElement::ensureAnimator() -{ - if (!m_animator) - m_animator = SVGAnimatorFactory::create(this, targetElement(), m_animatedPropertyType); - ASSERT(m_animatedPropertyType == m_animator->type()); - return m_animator.get(); -} - -bool isSVGAnimateElement(const Node& node) -{ - return node.hasTagName(SVGNames::animateTag) - || node.hasTagName(SVGNames::animateColorTag) - || node.hasTagName(SVGNames::animateTransformTag) - || node.hasTagName(SVGNames::setTag); -} - + return adoptRef(*new SVGAnimateElement(tagName, document)); } -#endif // ENABLE(SVG) +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGAnimateElement.h b/Source/WebCore/svg/SVGAnimateElement.h index 0b43fb87a..3bf9d6698 100644 --- a/Source/WebCore/svg/SVGAnimateElement.h +++ b/Source/WebCore/svg/SVGAnimateElement.h @@ -1,85 +1,42 @@ /* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> - * Copyright (C) 2008 Apple Inc. All rights reserved. - * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2014 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGAnimateElement_h -#define SVGAnimateElement_h +#pragma once -#if ENABLE(SVG) -#include "SVGAnimatedType.h" -#include "SVGAnimatedTypeAnimator.h" -#include "SVGAnimationElement.h" -#include "SVGNames.h" +#include "SVGAnimateElementBase.h" namespace WebCore { class SVGAnimatedProperty; -class SVGAnimateElement : public SVGAnimationElement { +class SVGAnimateElement final : public SVGAnimateElementBase { public: - static PassRefPtr<SVGAnimateElement> create(const QualifiedName&, Document&); - virtual ~SVGAnimateElement(); - - AnimatedPropertyType determineAnimatedPropertyType(SVGElement*) const; - -protected: - SVGAnimateElement(const QualifiedName&, Document&); - - virtual void resetAnimatedType() override; - virtual void clearAnimatedType(SVGElement* targetElement) override; - - virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) override; - virtual bool calculateFromAndToValues(const String& fromString, const String& toString) override; - virtual bool calculateFromAndByValues(const String& fromString, const String& byString) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) override; - virtual void applyResultsToTarget() override; - virtual float calculateDistance(const String& fromString, const String& toString) override; - virtual bool isAdditive() const override; - - virtual void setTargetElement(SVGElement*) override; - virtual void setAttributeName(const QualifiedName&) override; - - AnimatedPropertyType m_animatedPropertyType; + static Ref<SVGAnimateElement> create(const QualifiedName&, Document&); private: - void resetAnimatedPropertyType(); - SVGAnimatedTypeAnimator* ensureAnimator(); - bool animatedPropertyTypeSupportsAddition() const; - - virtual bool hasValidAttributeType() override; - - std::unique_ptr<SVGAnimatedType> m_fromType; - std::unique_ptr<SVGAnimatedType> m_toType; - std::unique_ptr<SVGAnimatedType> m_toAtEndOfDurationType; - std::unique_ptr<SVGAnimatedType> m_animatedType; - - SVGElementAnimatedPropertyList m_animatedProperties; - std::unique_ptr<SVGAnimatedTypeAnimator> m_animator; + SVGAnimateElement(const QualifiedName&, Document&); }; -void isSVGAnimateElement(const SVGAnimateElement&); // Catch unnecessary runtime check of type known at compile time. -bool isSVGAnimateElement(const Node&); -NODE_TYPE_CASTS(SVGAnimateElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimateElement_h diff --git a/Source/WebCore/svg/SVGAnimateElement.idl b/Source/WebCore/svg/SVGAnimateElement.idl index 95a10fbfe..eb848c458 100644 --- a/Source/WebCore/svg/SVGAnimateElement.idl +++ b/Source/WebCore/svg/SVGAnimateElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGAnimateElement : SVGAnimationElement { +interface SVGAnimateElement : SVGAnimationElement { }; diff --git a/Source/WebCore/svg/SVGAnimateElementBase.cpp b/Source/WebCore/svg/SVGAnimateElementBase.cpp new file mode 100644 index 000000000..11ae7a981 --- /dev/null +++ b/Source/WebCore/svg/SVGAnimateElementBase.cpp @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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" +#include "SVGAnimateElementBase.h" + +#include "CSSPropertyNames.h" +#include "CSSPropertyParser.h" +#include "QualifiedName.h" +#include "RenderObject.h" +#include "SVGAnimatorFactory.h" +#include "SVGElement.h" +#include "SVGNames.h" +#include "StyleProperties.h" + +namespace WebCore { + +SVGAnimateElementBase::SVGAnimateElementBase(const QualifiedName& tagName, Document& document) + : SVGAnimationElement(tagName, document) + , m_animatedPropertyType(AnimatedString) +{ + ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateColorTag) || hasTagName(SVGNames::animateTransformTag)); +} + +SVGAnimateElementBase::~SVGAnimateElementBase() +{ +} + +bool SVGAnimateElementBase::hasValidAttributeType() +{ + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return false; + + return m_animatedPropertyType != AnimatedUnknown && !hasInvalidCSSAttributeType(); +} + +AnimatedPropertyType SVGAnimateElementBase::determineAnimatedPropertyType(SVGElement& targetElement) const +{ + auto propertyTypes = targetElement.animatedPropertyTypesForAttribute(attributeName()); + if (propertyTypes.isEmpty()) + return AnimatedUnknown; + + ASSERT(propertyTypes.size() <= 2); + AnimatedPropertyType type = propertyTypes[0]; + if (hasTagName(SVGNames::animateColorTag) && type != AnimatedColor) + return AnimatedUnknown; + + // Animations of transform lists are not allowed for <animate> or <set> + // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties + if (type == AnimatedTransformList && !hasTagName(SVGNames::animateTransformTag)) + return AnimatedUnknown; + + // Fortunately there's just one special case needed here: SVGMarkerElements orientAttr, which + // corresponds to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType. We have to + // figure out whose value to change here. + if (targetElement.hasTagName(SVGNames::markerTag) && type == AnimatedAngle) { + ASSERT(propertyTypes.size() == 2); + ASSERT(propertyTypes[0] == AnimatedAngle); + ASSERT(propertyTypes[1] == AnimatedEnumeration); + } else if (propertyTypes.size() == 2) + ASSERT(propertyTypes[0] == propertyTypes[1]); + + return type; +} + +void SVGAnimateElementBase::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) +{ + ASSERT(resultElement); + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return; + + ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(*targetElement)); + + ASSERT(percentage >= 0 && percentage <= 1); + ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag)); + ASSERT(m_animatedPropertyType != AnimatedUnknown); + ASSERT(m_animator); + ASSERT(m_animator->type() == m_animatedPropertyType); + ASSERT(m_fromType); + ASSERT(m_fromType->type() == m_animatedPropertyType); + ASSERT(m_toType); + + SVGAnimateElementBase& resultAnimationElement = downcast<SVGAnimateElementBase>(*resultElement); + ASSERT(resultAnimationElement.m_animatedType); + ASSERT(resultAnimationElement.m_animatedPropertyType == m_animatedPropertyType); + + if (hasTagName(SVGNames::setTag)) + percentage = 1; + + if (calcMode() == CalcMode::Discrete) + percentage = percentage < 0.5 ? 0 : 1; + + // Target element might have changed. + m_animator->setContextElement(targetElement); + + // Be sure to detach list wrappers before we modfiy their underlying value. If we'd do + // if after calculateAnimatedValue() ran the cached pointers in the list propery tear + // offs would point nowhere, and we couldn't create copies of those values anymore, + // while detaching. This is covered by assertions, moving this down would fire them. + if (!m_animatedProperties.isEmpty()) + m_animator->animValWillChange(m_animatedProperties); + + // Values-animation accumulates using the last values entry corresponding to the end of duration time. + SVGAnimatedType* toAtEndOfDurationType = m_toAtEndOfDurationType ? m_toAtEndOfDurationType.get() : m_toType.get(); + m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromType.get(), m_toType.get(), toAtEndOfDurationType, resultAnimationElement.m_animatedType.get()); +} + +bool SVGAnimateElementBase::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) +{ + if (toAtEndOfDurationString.isEmpty()) + return false; + m_toAtEndOfDurationType = ensureAnimator()->constructFromString(toAtEndOfDurationString); + return true; +} + +bool SVGAnimateElementBase::calculateFromAndToValues(const String& fromString, const String& toString) +{ + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return false; + + determinePropertyValueTypes(fromString, toString); + ensureAnimator()->calculateFromAndToValues(m_fromType, m_toType, fromString, toString); + ASSERT(m_animatedPropertyType == m_animator->type()); + return true; +} + +bool SVGAnimateElementBase::calculateFromAndByValues(const String& fromString, const String& byString) +{ + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return false; + + if (animationMode() == ByAnimation && !isAdditive()) + return false; + + // from-by animation may only be used with attributes that support addition (e.g. most numeric attributes). + if (animationMode() == FromByAnimation && !animatedPropertyTypeSupportsAddition()) + return false; + + ASSERT(!hasTagName(SVGNames::setTag)); + + determinePropertyValueTypes(fromString, byString); + ensureAnimator()->calculateFromAndByValues(m_fromType, m_toType, fromString, byString); + ASSERT(m_animatedPropertyType == m_animator->type()); + return true; +} + +#ifndef NDEBUG +static inline bool propertyTypesAreConsistent(AnimatedPropertyType expectedPropertyType, const SVGElementAnimatedPropertyList& animatedTypes) +{ + for (auto& type : animatedTypes) { + for (auto& property : type.properties) { + if (expectedPropertyType != property->animatedPropertyType()) { + // This is the only allowed inconsistency. SVGAnimatedAngleAnimator handles both SVGAnimatedAngle & SVGAnimatedEnumeration for markers orient attribute. + if (expectedPropertyType == AnimatedAngle && property->animatedPropertyType() == AnimatedEnumeration) + return true; + return false; + } + } + } + + return true; +} +#endif + +void SVGAnimateElementBase::resetAnimatedType() +{ + SVGAnimatedTypeAnimator* animator = ensureAnimator(); + ASSERT(m_animatedPropertyType == animator->type()); + + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return; + + const QualifiedName& attributeName = this->attributeName(); + ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName); + + if (shouldApply == DontApplyAnimation) + return; + + if (shouldApply == ApplyXMLAnimation || shouldApply == ApplyXMLandCSSAnimation) { + // SVG DOM animVal animation code-path. + m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(*targetElement, attributeName); + if (m_animatedProperties.isEmpty()) + return; + + ASSERT(propertyTypesAreConsistent(m_animatedPropertyType, m_animatedProperties)); + if (!m_animatedType) + m_animatedType = animator->startAnimValAnimation(m_animatedProperties); + else { + animator->resetAnimValToBaseVal(m_animatedProperties, *m_animatedType); + animator->animValDidChange(m_animatedProperties); + } + return; + } + + // CSS properties animation code-path. + ASSERT(m_animatedProperties.isEmpty()); + String baseValue; + + if (shouldApply == ApplyCSSAnimation) { + ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName)); + computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue); + } + + if (!m_animatedType) + m_animatedType = animator->constructFromString(baseValue); + else + m_animatedType->setValueAsString(attributeName, baseValue); +} + +static inline void applyCSSPropertyToTarget(SVGElement& targetElement, CSSPropertyID id, const String& value) +{ + ASSERT(!targetElement.m_deletionHasBegun); + + if (!targetElement.ensureAnimatedSMILStyleProperties().setProperty(id, value, false)) + return; + + targetElement.invalidateStyleAndLayerComposition(); +} + +static inline void removeCSSPropertyFromTarget(SVGElement& targetElement, CSSPropertyID id) +{ + ASSERT(!targetElement.m_deletionHasBegun); + targetElement.ensureAnimatedSMILStyleProperties().removeProperty(id); + targetElement.invalidateStyleAndLayerComposition(); +} + +static inline void applyCSSPropertyToTargetAndInstances(SVGElement& targetElement, const QualifiedName& attributeName, const String& valueAsString) +{ + // FIXME: Do we really need to check both isConnected and !parentNode? + if (attributeName == anyQName() || !targetElement.isConnected() || !targetElement.parentNode()) + return; + + CSSPropertyID id = cssPropertyID(attributeName.localName()); + + SVGElement::InstanceUpdateBlocker blocker(targetElement); + applyCSSPropertyToTarget(targetElement, id, valueAsString); + + // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. + for (auto* instance : targetElement.instances()) + applyCSSPropertyToTarget(*instance, id, valueAsString); +} + +static inline void removeCSSPropertyFromTargetAndInstances(SVGElement& targetElement, const QualifiedName& attributeName) +{ + // FIXME: Do we really need to check both isConnected and !parentNode? + if (attributeName == anyQName() || !targetElement.isConnected() || !targetElement.parentNode()) + return; + + CSSPropertyID id = cssPropertyID(attributeName.localName()); + + SVGElement::InstanceUpdateBlocker blocker(targetElement); + removeCSSPropertyFromTarget(targetElement, id); + + // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. + for (auto* instance : targetElement.instances()) + removeCSSPropertyFromTarget(*instance, id); +} + +static inline void notifyTargetAboutAnimValChange(SVGElement& targetElement, const QualifiedName& attributeName) +{ + ASSERT(!targetElement.m_deletionHasBegun); + targetElement.svgAttributeChanged(attributeName); +} + +static inline void notifyTargetAndInstancesAboutAnimValChange(SVGElement& targetElement, const QualifiedName& attributeName) +{ + if (attributeName == anyQName() || !targetElement.isConnected() || !targetElement.parentNode()) + return; + + SVGElement::InstanceUpdateBlocker blocker(targetElement); + notifyTargetAboutAnimValChange(targetElement, attributeName); + + // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. + for (auto* instance : targetElement.instances()) + notifyTargetAboutAnimValChange(*instance, attributeName); +} + +void SVGAnimateElementBase::clearAnimatedType(SVGElement* targetElement) +{ + if (!m_animatedType) + return; + + if (!targetElement) { + m_animatedType = nullptr; + return; + } + + if (m_animatedProperties.isEmpty()) { + // CSS properties animation code-path. + removeCSSPropertyFromTargetAndInstances(*targetElement, attributeName()); + m_animatedType = nullptr; + return; + } + + ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName()); + if (shouldApply == ApplyXMLandCSSAnimation) + removeCSSPropertyFromTargetAndInstances(*targetElement, attributeName()); + + // SVG DOM animVal animation code-path. + if (m_animator) { + m_animator->stopAnimValAnimation(m_animatedProperties); + notifyTargetAndInstancesAboutAnimValChange(*targetElement, attributeName()); + } + + m_animatedProperties.clear(); + m_animatedType = nullptr; +} + +void SVGAnimateElementBase::applyResultsToTarget() +{ + ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag)); + ASSERT(m_animatedPropertyType != AnimatedUnknown); + ASSERT(m_animator); + + // Early exit if our animated type got destroyed by a previous endedActiveInterval(). + if (!m_animatedType) + return; + + SVGElement* targetElement = this->targetElement(); + const QualifiedName& attributeName = this->attributeName(); + + ASSERT(targetElement); + + if (m_animatedProperties.isEmpty()) { + // CSS properties animation code-path. + // Convert the result of the animation to a String and apply it as CSS property on the target & all instances. + applyCSSPropertyToTargetAndInstances(*targetElement, attributeName, m_animatedType->valueAsString()); + return; + } + + // We do update the style and the animation property independent of each other. + ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName); + if (shouldApply == ApplyXMLandCSSAnimation) + applyCSSPropertyToTargetAndInstances(*targetElement, attributeName, m_animatedType->valueAsString()); + + // SVG DOM animVal animation code-path. + // At this point the SVG DOM values are already changed, unlike for CSS. + // We only have to trigger update notifications here. + m_animator->animValDidChange(m_animatedProperties); + notifyTargetAndInstancesAboutAnimValChange(*targetElement, attributeName); +} + +bool SVGAnimateElementBase::animatedPropertyTypeSupportsAddition() const +{ + // Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties. + switch (m_animatedPropertyType) { + case AnimatedBoolean: + case AnimatedEnumeration: + case AnimatedPreserveAspectRatio: + case AnimatedString: + case AnimatedUnknown: + return false; + case AnimatedAngle: + case AnimatedColor: + case AnimatedInteger: + case AnimatedIntegerOptionalInteger: + case AnimatedLength: + case AnimatedLengthList: + case AnimatedNumber: + case AnimatedNumberList: + case AnimatedNumberOptionalNumber: + case AnimatedPath: + case AnimatedPoints: + case AnimatedRect: + case AnimatedTransformList: + return true; + default: + RELEASE_ASSERT_NOT_REACHED(); + return true; + } +} + +bool SVGAnimateElementBase::isAdditive() const +{ + if (animationMode() == ByAnimation || animationMode() == FromByAnimation) { + if (!animatedPropertyTypeSupportsAddition()) + return false; + } + + return SVGAnimationElement::isAdditive(); +} + +float SVGAnimateElementBase::calculateDistance(const String& fromString, const String& toString) +{ + // FIXME: A return value of float is not enough to support paced animations on lists. + SVGElement* targetElement = this->targetElement(); + if (!targetElement) + return -1; + + return ensureAnimator()->calculateDistance(fromString, toString); +} + +void SVGAnimateElementBase::setTargetElement(SVGElement* target) +{ + SVGAnimationElement::setTargetElement(target); + resetAnimatedPropertyType(); +} + +void SVGAnimateElementBase::setAttributeName(const QualifiedName& attributeName) +{ + SVGSMILElement::setAttributeName(attributeName); + checkInvalidCSSAttributeType(targetElement()); + resetAnimatedPropertyType(); +} + +void SVGAnimateElementBase::resetAnimatedPropertyType() +{ + SVGAnimationElement::resetAnimatedPropertyType(); + ASSERT(!m_animatedType); + m_fromType = nullptr; + m_toType = nullptr; + m_toAtEndOfDurationType = nullptr; + m_animator = nullptr; + m_animatedPropertyType = targetElement() ? determineAnimatedPropertyType(*targetElement()) : AnimatedString; +} + +SVGAnimatedTypeAnimator* SVGAnimateElementBase::ensureAnimator() +{ + if (!m_animator) + m_animator = SVGAnimatorFactory::create(this, targetElement(), m_animatedPropertyType); + ASSERT(m_animatedPropertyType == m_animator->type()); + return m_animator.get(); +} + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGAnimateElementBase.h b/Source/WebCore/svg/SVGAnimateElementBase.h new file mode 100644 index 000000000..a33de9e4f --- /dev/null +++ b/Source/WebCore/svg/SVGAnimateElementBase.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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. + */ + +#pragma once + +#include "SVGAnimatedType.h" +#include "SVGAnimatedTypeAnimator.h" +#include "SVGAnimationElement.h" +#include "SVGNames.h" + +namespace WebCore { + +class SVGAnimateElementBase : public SVGAnimationElement { +public: + virtual ~SVGAnimateElementBase(); + + AnimatedPropertyType determineAnimatedPropertyType(SVGElement&) const; + +protected: + SVGAnimateElementBase(const QualifiedName&, Document&); + + void resetAnimatedType() override; + void clearAnimatedType(SVGElement* targetElement) override; + + bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) override; + bool calculateFromAndToValues(const String& fromString, const String& toString) override; + bool calculateFromAndByValues(const String& fromString, const String& byString) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) override; + void applyResultsToTarget() override; + float calculateDistance(const String& fromString, const String& toString) override; + bool isAdditive() const override; + + void setTargetElement(SVGElement*) override; + void setAttributeName(const QualifiedName&) override; + void resetAnimatedPropertyType() override; + + AnimatedPropertyType m_animatedPropertyType; + +private: + SVGAnimatedTypeAnimator* ensureAnimator(); + bool animatedPropertyTypeSupportsAddition() const; + + bool hasValidAttributeType() override; + + std::unique_ptr<SVGAnimatedType> m_fromType; + std::unique_ptr<SVGAnimatedType> m_toType; + std::unique_ptr<SVGAnimatedType> m_toAtEndOfDurationType; + std::unique_ptr<SVGAnimatedType> m_animatedType; + + SVGElementAnimatedPropertyList m_animatedProperties; + std::unique_ptr<SVGAnimatedTypeAnimator> m_animator; +}; + +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGAnimateElementBase) + static bool isType(const WebCore::SVGElement& element) + { + return element.hasTagName(WebCore::SVGNames::animateTag) || element.hasTagName(WebCore::SVGNames::animateColorTag) + || element.hasTagName(WebCore::SVGNames::animateTransformTag) || element.hasTagName(WebCore::SVGNames::setTag); + } + static bool isType(const WebCore::Node& node) { return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.cpp b/Source/WebCore/svg/SVGAnimateMotionElement.cpp index 8bb615048..e808d7969 100644 --- a/Source/WebCore/svg/SVGAnimateMotionElement.cpp +++ b/Source/WebCore/svg/SVGAnimateMotionElement.cpp @@ -20,16 +20,12 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimateMotionElement.h" #include "AffineTransform.h" -#include "Attribute.h" #include "ElementIterator.h" -#include "RenderObject.h" +#include "PathTraversalState.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGImageElement.h" #include "SVGMPathElement.h" #include "SVGNames.h" @@ -37,9 +33,9 @@ #include "SVGPathData.h" #include "SVGPathElement.h" #include "SVGPathUtilities.h" -#include "SVGTransformList.h" #include <wtf/MathExtras.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringView.h> namespace WebCore { @@ -49,13 +45,13 @@ inline SVGAnimateMotionElement::SVGAnimateMotionElement(const QualifiedName& tag : SVGAnimationElement(tagName, document) , m_hasToPointAtEndOfDuration(false) { - setCalcMode(CalcModePaced); + setCalcMode(CalcMode::Paced); ASSERT(hasTagName(animateMotionTag)); } -PassRefPtr<SVGAnimateMotionElement> SVGAnimateMotionElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGAnimateMotionElement> SVGAnimateMotionElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGAnimateMotionElement(tagName, document)); + return adoptRef(*new SVGAnimateMotionElement(tagName, document)); } bool SVGAnimateMotionElement::hasValidAttributeType() @@ -72,7 +68,7 @@ bool SVGAnimateMotionElement::hasValidAttributeType() if (targetElement->hasTagName(gTag) || targetElement->hasTagName(defsTag) || targetElement->hasTagName(useTag) - || isSVGImageElement(targetElement) + || is<SVGImageElement>(*targetElement) || targetElement->hasTagName(switchTag) || targetElement->hasTagName(pathTag) || targetElement->hasTagName(rectTag) @@ -97,21 +93,8 @@ bool SVGAnimateMotionElement::hasValidAttributeName() return true; } -bool SVGAnimateMotionElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - supportedAttributes.add(SVGNames::pathAttr); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGAnimateMotionElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGAnimationElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::pathAttr) { m_path = Path(); buildPathFromString(value, m_path); @@ -119,13 +102,13 @@ void SVGAnimateMotionElement::parseAttribute(const QualifiedName& name, const At return; } - ASSERT_NOT_REACHED(); + SVGAnimationElement::parseAttribute(name, value); } SVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode() const { - DEFINE_STATIC_LOCAL(const AtomicString, autoVal, ("auto", AtomicString::ConstructFromLiteral)); - DEFINE_STATIC_LOCAL(const AtomicString, autoReverse, ("auto-reverse", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> autoVal("auto", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> autoReverse("auto-reverse", AtomicString::ConstructFromLiteral); const AtomicString& rotate = getAttribute(SVGNames::rotateAttr); if (rotate == autoVal) return RotateAuto; @@ -148,7 +131,7 @@ void SVGAnimateMotionElement::updateAnimationPath() } } - if (!foundMPath && fastHasAttribute(SVGNames::pathAttr)) + if (!foundMPath && hasAttributeWithoutSynchronization(SVGNames::pathAttr)) m_animationPath = m_path; updateAnimationMode(); @@ -158,7 +141,8 @@ static bool parsePoint(const String& s, FloatPoint& point) { if (s.isEmpty()) return false; - const UChar* cur = s.deprecatedCharacters(); + auto upconvertedCharacters = StringView(s).upconvertedCharacters(); + const UChar* cur = upconvertedCharacters; const UChar* end = cur + s.length(); if (!skipOptionalSVGSpaces(cur, end)) @@ -228,16 +212,19 @@ void SVGAnimateMotionElement::buildTransformForProgress(AffineTransform* transfo { ASSERT(!m_animationPath.isEmpty()); - bool ok = false; + bool success = false; float positionOnPath = m_animationPath.length() * percentage; - FloatPoint position = m_animationPath.pointAtLength(positionOnPath, ok); - if (!ok) + auto traversalState(m_animationPath.traversalStateAtLength(positionOnPath, success)); + if (!success) return; + + FloatPoint position = traversalState.current(); + float angle = traversalState.normalAngle(); + transform->translate(position.x(), position.y()); RotateMode rotateMode = this->rotateMode(); if (rotateMode != RotateAuto && rotateMode != RotateAutoReverse) return; - float angle = m_animationPath.normalAngleAtLength(positionOnPath, ok); if (rotateMode == RotateAutoReverse) angle += 180; transform->rotate(angle); @@ -292,19 +279,17 @@ void SVGAnimateMotionElement::applyResultsToTarget() if (RenderElement* renderer = targetElement->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); - AffineTransform* t = targetElement->supplementalTransform(); - if (!t) + AffineTransform* targetSupplementalTransform = targetElement->supplementalTransform(); + if (!targetSupplementalTransform) return; // ...except in case where we have additional instances in <use> trees. - for (auto instance : targetElement->instancesForElement()) { - SVGElement* shadowTreeElement = instance->shadowTreeElement(); - ASSERT(shadowTreeElement); - AffineTransform* transform = shadowTreeElement->supplementalTransform(); - if (!transform) + for (auto* instance : targetElement->instances()) { + AffineTransform* transform = instance->supplementalTransform(); + if (!transform || *transform == *targetSupplementalTransform) continue; - transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f()); - if (RenderElement* renderer = shadowTreeElement->renderer()) { + *transform = *targetSupplementalTransform; + if (RenderElement* renderer = instance->renderer()) { renderer->setNeedsTransformUpdate(); RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); } @@ -332,4 +317,3 @@ void SVGAnimateMotionElement::updateAnimationMode() } } -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.h b/Source/WebCore/svg/SVGAnimateMotionElement.h index a7057a82b..df3dc385d 100644 --- a/Source/WebCore/svg/SVGAnimateMotionElement.h +++ b/Source/WebCore/svg/SVGAnimateMotionElement.h @@ -18,9 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimateMotionElement_h -#define SVGAnimateMotionElement_h -#if ENABLE(SVG) +#pragma once + #include "Path.h" #include "SVGAnimationElement.h" @@ -30,26 +29,25 @@ class AffineTransform; class SVGAnimateMotionElement final : public SVGAnimationElement { public: - static PassRefPtr<SVGAnimateMotionElement> create(const QualifiedName&, Document&); + static Ref<SVGAnimateMotionElement> create(const QualifiedName&, Document&); void updateAnimationPath(); private: SVGAnimateMotionElement(const QualifiedName&, Document&); - virtual bool hasValidAttributeType() override; - virtual bool hasValidAttributeName() override; + bool hasValidAttributeType() override; + bool hasValidAttributeName() override; - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void resetAnimatedType() override; - virtual void clearAnimatedType(SVGElement* targetElement) override; - virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) override; - virtual bool calculateFromAndToValues(const String& fromString, const String& toString) override; - virtual bool calculateFromAndByValues(const String& fromString, const String& byString) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) override; - virtual void applyResultsToTarget() override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void resetAnimatedType() override; + void clearAnimatedType(SVGElement* targetElement) override; + bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) override; + bool calculateFromAndToValues(const String& fromString, const String& toString) override; + bool calculateFromAndByValues(const String& fromString, const String& byString) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) override; + void applyResultsToTarget() override; + float calculateDistance(const String& fromString, const String& toString) override; enum RotateMode { RotateAngle, @@ -61,7 +59,7 @@ private: bool m_hasToPointAtEndOfDuration; - virtual void updateAnimationMode() override; + void updateAnimationMode() override; // Note: we do not support percentage values for to/from coords as the spec implies we should (opera doesn't either) FloatPoint m_fromPoint; @@ -71,10 +69,5 @@ private: Path m_path; Path m_animationPath; }; - -NODE_TYPE_CASTS(SVGAnimateMotionElement) } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimateMotionElement_h diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.idl b/Source/WebCore/svg/SVGAnimateMotionElement.idl index 997febf5c..51003c6e0 100644 --- a/Source/WebCore/svg/SVGAnimateMotionElement.idl +++ b/Source/WebCore/svg/SVGAnimateMotionElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGAnimateMotionElement : SVGAnimationElement { +interface SVGAnimateMotionElement : SVGAnimationElement { }; diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.cpp b/Source/WebCore/svg/SVGAnimateTransformElement.cpp index b20a89eca..72eb7720c 100644 --- a/Source/WebCore/svg/SVGAnimateTransformElement.cpp +++ b/Source/WebCore/svg/SVGAnimateTransformElement.cpp @@ -21,26 +21,23 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimateTransformElement.h" -#include "Attribute.h" #include "SVGNames.h" #include "SVGTransformable.h" namespace WebCore { inline SVGAnimateTransformElement::SVGAnimateTransformElement(const QualifiedName& tagName, Document& document) - : SVGAnimateElement(tagName, document) - , m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN) + : SVGAnimateElementBase(tagName, document) + , m_type(SVGTransformValue::SVG_TRANSFORM_UNKNOWN) { ASSERT(hasTagName(SVGNames::animateTransformTag)); } -PassRefPtr<SVGAnimateTransformElement> SVGAnimateTransformElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGAnimateTransformElement> SVGAnimateTransformElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGAnimateTransformElement(tagName, document)); + return adoptRef(*new SVGAnimateTransformElement(tagName, document)); } bool SVGAnimateTransformElement::hasValidAttributeType() @@ -49,37 +46,22 @@ bool SVGAnimateTransformElement::hasValidAttributeType() if (!targetElement) return false; - if (attributeType() == AttributeTypeCSS) + if (attributeType() == AttributeType::CSS) return false; return m_animatedPropertyType == AnimatedTransformList; } -bool SVGAnimateTransformElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - supportedAttributes.add(SVGNames::typeAttr); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGAnimateTransformElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGAnimateElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::typeAttr) { m_type = SVGTransformable::parseTransformType(value); - if (m_type == SVGTransform::SVG_TRANSFORM_MATRIX) - m_type = SVGTransform::SVG_TRANSFORM_UNKNOWN; + if (m_type == SVGTransformValue::SVG_TRANSFORM_MATRIX) + m_type = SVGTransformValue::SVG_TRANSFORM_UNKNOWN; return; } - ASSERT_NOT_REACHED(); + SVGAnimateElementBase::parseAttribute(name, value); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.h b/Source/WebCore/svg/SVGAnimateTransformElement.h index d2e4e0927..e223489ec 100644 --- a/Source/WebCore/svg/SVGAnimateTransformElement.h +++ b/Source/WebCore/svg/SVGAnimateTransformElement.h @@ -20,37 +20,28 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimateTransformElement_h -#define SVGAnimateTransformElement_h +#pragma once -#if ENABLE(SVG) -#include "SVGAnimateElement.h" -#include "SVGTransform.h" +#include "SVGAnimateElementBase.h" +#include "SVGTransformValue.h" namespace WebCore { class AffineTransform; -class SVGAnimateTransformElement final : public SVGAnimateElement { +class SVGAnimateTransformElement final : public SVGAnimateElementBase { public: - static PassRefPtr<SVGAnimateTransformElement> create(const QualifiedName&, Document&); + static Ref<SVGAnimateTransformElement> create(const QualifiedName&, Document&); - SVGTransform::SVGTransformType transformType() const { return m_type; } + SVGTransformValue::SVGTransformType transformType() const { return m_type; } private: SVGAnimateTransformElement(const QualifiedName&, Document&); - virtual bool hasValidAttributeType() override; + bool hasValidAttributeType() final; + void parseAttribute(const QualifiedName&, const AtomicString&) final; - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - - SVGTransform::SVGTransformType m_type; + SVGTransformValue::SVGTransformType m_type; }; -NODE_TYPE_CASTS(SVGAnimateTransformElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimateTransformElement_h diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.idl b/Source/WebCore/svg/SVGAnimateTransformElement.idl index d676f325e..eddecc32c 100644 --- a/Source/WebCore/svg/SVGAnimateTransformElement.idl +++ b/Source/WebCore/svg/SVGAnimateTransformElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGAnimateTransformElement : SVGAnimationElement { +interface SVGAnimateTransformElement : SVGAnimationElement { }; diff --git a/Source/WebCore/svg/SVGAnimatedAngle.cpp b/Source/WebCore/svg/SVGAnimatedAngle.cpp index f3e3b2ec9..c573255ec 100644 --- a/Source/WebCore/svg/SVGAnimatedAngle.cpp +++ b/Source/WebCore/svg/SVGAnimatedAngle.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedAngle.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGMarkerElement.h" namespace WebCore { @@ -34,11 +32,11 @@ SVGAnimatedAngleAnimator::SVGAnimatedAngleAnimator(SVGAnimationElement* animatio std::unique_ptr<SVGAnimatedType> SVGAnimatedAngleAnimator::constructFromString(const String& string) { - auto animatedType = SVGAnimatedType::createAngleAndEnumeration(std::make_unique<std::pair<SVGAngle, unsigned>>()); - std::pair<SVGAngle, unsigned>& animatedPair = animatedType->angleAndEnumeration(); + auto animatedType = SVGAnimatedType::createAngleAndEnumeration(std::make_unique<std::pair<SVGAngleValue, unsigned>>()); + auto& animatedPair = animatedType->angleAndEnumeration(); - SVGAngle angle; - SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string, angle); + SVGAngleValue angle; + SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string, angle); if (orientType > 0) animatedPair.second = orientType; if (orientType == SVGMarkerOrientAngle) @@ -57,7 +55,7 @@ void SVGAnimatedAngleAnimator::stopAnimValAnimation(const SVGElementAnimatedProp stopAnimValAnimationForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes); } -void SVGAnimatedAngleAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedAngleAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::angleAndEnumeration); } @@ -77,13 +75,13 @@ void SVGAnimatedAngleAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimat ASSERT(from->type() == AnimatedAngle); ASSERT(from->type() == to->type()); - const std::pair<SVGAngle, unsigned>& fromAngleAndEnumeration = from->angleAndEnumeration(); - std::pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration(); + const auto& fromAngleAndEnumeration = from->angleAndEnumeration(); + auto& toAngleAndEnumeration = to->angleAndEnumeration(); // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto'). if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second || fromAngleAndEnumeration.second != SVGMarkerOrientAngle) return; - const SVGAngle& fromAngle = fromAngleAndEnumeration.first; - SVGAngle& toAngle = toAngleAndEnumeration.first; + const auto& fromAngle = fromAngleAndEnumeration.first; + auto& toAngle = toAngleAndEnumeration.first; toAngle.setValue(toAngle.value() + fromAngle.value()); } @@ -92,64 +90,57 @@ void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned ASSERT(m_animationElement); ASSERT(m_contextElement); - const std::pair<SVGAngle, unsigned>& fromAngleAndEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->angleAndEnumeration() : from->angleAndEnumeration(); - const std::pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration(); - const std::pair<SVGAngle, unsigned>& toAtEndOfDurationAngleAndEnumeration = toAtEndOfDuration->angleAndEnumeration(); - std::pair<SVGAngle, unsigned>& animatedAngleAndEnumeration = animated->angleAndEnumeration(); + const auto& fromAngleAndEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->angleAndEnumeration() : from->angleAndEnumeration(); + auto& toAngleAndEnumeration = to->angleAndEnumeration(); + auto& toAtEndOfDurationAngleAndEnumeration = toAtEndOfDuration->angleAndEnumeration(); + auto& animatedAngleAndEnumeration = animated->angleAndEnumeration(); if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second) { - // Animating from eg. auto to 90deg, or auto to 90deg. - if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) { - // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword.. - if (toAngleAndEnumeration.second == SVGMarkerOrientAuto) { - if (percentage < 0.5f) { - animatedAngleAndEnumeration.first = fromAngleAndEnumeration.first; - animatedAngleAndEnumeration.second = SVGMarkerOrientAngle; - return; - } + // Discrete animation - no linear interpolation possible between values (e.g. auto to angle). + if (percentage < 0.5f) { + animatedAngleAndEnumeration.second = fromAngleAndEnumeration.second; + if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) + animatedAngleAndEnumeration.first = fromAngleAndEnumeration.first; + else animatedAngleAndEnumeration.first.setValue(0); - animatedAngleAndEnumeration.second = SVGMarkerOrientAuto; - return; - } - animatedAngleAndEnumeration.first.setValue(0); - animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown; return; } - } - - // From 'auto' to 'auto'. - if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto) { - animatedAngleAndEnumeration.first.setValue(0); - animatedAngleAndEnumeration.second = SVGMarkerOrientAuto; + animatedAngleAndEnumeration.second = toAngleAndEnumeration.second; + if (toAngleAndEnumeration.second == SVGMarkerOrientAngle) + animatedAngleAndEnumeration.first = toAngleAndEnumeration.first; + else + animatedAngleAndEnumeration.first.setValue(0); return; } - // If the enumeration value is not angle or auto, its unknown. - if (fromAngleAndEnumeration.second != SVGMarkerOrientAngle) { - animatedAngleAndEnumeration.first.setValue(0); - animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown; + if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) { + // Regular from angle to angle animation, with support for smooth interpolation, and additive and accumulated animation. + animatedAngleAndEnumeration.second = SVGMarkerOrientAngle; + + auto& animatedSVGAngle = animatedAngleAndEnumeration.first; + const auto& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first; + float animatedAngle = animatedSVGAngle.value(); + m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle); + animatedSVGAngle.setValue(animatedAngle); return; } - // Regular from angle to angle animation, with all features like additive etc. - animatedAngleAndEnumeration.second = SVGMarkerOrientAngle; + // auto, auto-start-reverse, or unknown. + animatedAngleAndEnumeration.first.setValue(0); - SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first; - const SVGAngle& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first; - float animatedAngle = animatedSVGAngle.value(); - m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle); - animatedSVGAngle.setValue(animatedAngle); + if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto || fromAngleAndEnumeration.second == SVGMarkerOrientAutoStartReverse) + animatedAngleAndEnumeration.second = fromAngleAndEnumeration.second; + else + animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown; } float SVGAnimatedAngleAnimator::calculateDistance(const String& fromString, const String& toString) { - SVGAngle from = SVGAngle(); - from.setValueAsString(fromString, ASSERT_NO_EXCEPTION); - SVGAngle to = SVGAngle(); - to.setValueAsString(toString, ASSERT_NO_EXCEPTION); + auto from = SVGAngleValue(); + from.setValueAsString(fromString); + auto to = SVGAngleValue(); + to.setValueAsString(toString); return fabsf(to.value() - from.value()); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedAngle.h b/Source/WebCore/svg/SVGAnimatedAngle.h index a28e18b77..521178ba9 100644 --- a/Source/WebCore/svg/SVGAnimatedAngle.h +++ b/Source/WebCore/svg/SVGAnimatedAngle.h @@ -17,21 +17,19 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedAngle_h -#define SVGAnimatedAngle_h +#pragma once -#if ENABLE(SVG) #include "SVGAngle.h" #include "SVGAnimatedPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" namespace WebCore { -typedef SVGAnimatedPropertyTearOff<SVGAngle> SVGAnimatedAngle; +using SVGAnimatedAngle = SVGAnimatedPropertyTearOff<SVGAngle>; // Helper macros to declare/define a SVGAnimatedAngle object. SVGAnimatedAngle is only used in the SVG DOM for SVGMarkerElement. #define DECLARE_ANIMATED_ANGLE(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedAngle, SVGAngle, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedAngle, SVGAngleValue, UpperProperty, LowerProperty, ) // Only used for SVGMarkerElements orientAttr, which maps to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType. #define DEFINE_ANIMATED_ANGLE_AND_ENUMERATION(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty) \ @@ -43,20 +41,17 @@ class SVGAnimatedAngleAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedAngleAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedAngle.idl b/Source/WebCore/svg/SVGAnimatedAngle.idl index 6469a4cd4..9ac224e7c 100644 --- a/Source/WebCore/svg/SVGAnimatedAngle.idl +++ b/Source/WebCore/svg/SVGAnimatedAngle.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedAngle { readonly attribute SVGAngle baseVal; diff --git a/Source/WebCore/svg/SVGAnimatedBoolean.cpp b/Source/WebCore/svg/SVGAnimatedBoolean.cpp index 41177beab..ec0842a73 100644 --- a/Source/WebCore/svg/SVGAnimatedBoolean.cpp +++ b/Source/WebCore/svg/SVGAnimatedBoolean.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" namespace WebCore { @@ -48,7 +46,7 @@ void SVGAnimatedBooleanAnimator::stopAnimValAnimation(const SVGElementAnimatedPr stopAnimValAnimationForType<SVGAnimatedBoolean>(animatedTypes); } -void SVGAnimatedBooleanAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedBooleanAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedBoolean>(animatedTypes, type, &SVGAnimatedType::boolean); } @@ -87,5 +85,3 @@ float SVGAnimatedBooleanAnimator::calculateDistance(const String&, const String& } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedBoolean.h b/Source/WebCore/svg/SVGAnimatedBoolean.h index 996865d0e..6515a0531 100644 --- a/Source/WebCore/svg/SVGAnimatedBoolean.h +++ b/Source/WebCore/svg/SVGAnimatedBoolean.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedBoolean_h -#define SVGAnimatedBoolean_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedStaticPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" @@ -30,7 +28,10 @@ typedef SVGAnimatedStaticPropertyTearOff<bool> SVGAnimatedBoolean; // Helper macros to declare/define a SVGAnimatedBoolean object #define DECLARE_ANIMATED_BOOLEAN(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedBoolean, bool, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedBoolean, bool, UpperProperty, LowerProperty, ) + +#define DECLARE_ANIMATED_BOOLEAN_OVERRIDE(UpperProperty, LowerProperty) \ +DECLARE_ANIMATED_PROPERTY(SVGAnimatedBoolean, bool, UpperProperty, LowerProperty, override) #define DEFINE_ANIMATED_BOOLEAN(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedBoolean, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -41,19 +42,16 @@ class SVGAnimatedBooleanAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedBooleanAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedBoolean.idl b/Source/WebCore/svg/SVGAnimatedBoolean.idl index 0f703f69d..3ef70a656 100644 --- a/Source/WebCore/svg/SVGAnimatedBoolean.idl +++ b/Source/WebCore/svg/SVGAnimatedBoolean.idl @@ -24,10 +24,9 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedBoolean { - [StrictTypeChecking, SetterRaisesException] attribute boolean baseVal; + [SetterMayThrowException] attribute boolean baseVal; readonly attribute boolean animVal; }; diff --git a/Source/WebCore/svg/SVGAnimatedColor.cpp b/Source/WebCore/svg/SVGAnimatedColor.cpp index bbb36a92d..1670ffbab 100644 --- a/Source/WebCore/svg/SVGAnimatedColor.cpp +++ b/Source/WebCore/svg/SVGAnimatedColor.cpp @@ -18,49 +18,50 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedColor.h" -#include "ColorDistance.h" +#include "CSSParser.h" #include "RenderElement.h" -#include "SVGAnimateElement.h" -#include "SVGColor.h" +#include "SVGAnimateElementBase.h" namespace WebCore { -SVGAnimatedColorAnimator::SVGAnimatedColorAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement) - : SVGAnimatedTypeAnimator(AnimatedColor, animationElement, contextElement) +SVGAnimatedColorAnimator::SVGAnimatedColorAnimator(SVGAnimationElement& animationElement, SVGElement& contextElement) + : SVGAnimatedTypeAnimator(AnimatedColor, &animationElement, &contextElement) { } std::unique_ptr<SVGAnimatedType> SVGAnimatedColorAnimator::constructFromString(const String& string) { - auto animatedType = SVGAnimatedType::createColor(std::make_unique<Color>()); - animatedType->color() = string.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(string); - return animatedType; + return SVGAnimatedType::createColor(std::make_unique<Color>(CSSParser::parseColor(string.stripWhiteSpace()))); } void SVGAnimatedColorAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to) { + ASSERT(from); + ASSERT(to); ASSERT(from->type() == AnimatedColor); - ASSERT(from->type() == to->type()); - to->color() = ColorDistance::addColors(from->color(), to->color()); + ASSERT(to->type() == AnimatedColor); + + // Ignores any alpha and sets alpha on result to 100% opaque. + auto& fromColor = from->color(); + auto& toColor = to->color(); + toColor = { roundAndClampColorChannel(toColor.red() + fromColor.red()), + roundAndClampColorChannel(toColor.green() + fromColor.green()), + roundAndClampColorChannel(toColor.blue() + fromColor.blue()) }; } -static inline void adjustForCurrentColor(SVGElement* targetElement, Color& color) +static inline Color currentColor(SVGElement& targetElement) { - ASSERT(targetElement); - - if (RenderElement* targetRenderer = targetElement->renderer()) - color = targetRenderer->style().visitedDependentColor(CSSPropertyColor); - else - color = Color(); + RenderElement* targetRenderer = targetElement.renderer(); + if (!targetRenderer) + return { }; + return targetRenderer->style().visitedDependentColor(CSSPropertyColor); } static Color parseColorFromString(SVGAnimationElement*, const String& string) { - return SVGColor::colorFromRGBColorString(string); + return CSSParser::parseColor(string.stripWhiteSpace()); } void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated) @@ -70,8 +71,6 @@ void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned Color fromColor = m_animationElement->animationMode() == ToAnimation ? animated->color() : from->color(); Color toColor = to->color(); - const Color& toAtEndOfDurationColor = toAtEndOfDuration->color(); - Color& animatedColor = animated->color(); // Apply CSS inheritance rules. m_animationElement->adjustForInheritance<Color>(parseColorFromString, m_animationElement->fromPropertyValueType(), fromColor, m_contextElement); @@ -79,37 +78,42 @@ void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned // Apply <animateColor> rules. if (m_animationElement->fromPropertyValueType() == CurrentColorValue) - adjustForCurrentColor(m_contextElement, fromColor); + fromColor = currentColor(*m_contextElement); if (m_animationElement->toPropertyValueType() == CurrentColorValue) - adjustForCurrentColor(m_contextElement, toColor); + toColor = currentColor(*m_contextElement); + + auto& toAtEndOfDurationColor = toAtEndOfDuration->color(); + auto& animatedColor = animated->color(); - float animatedRed = animatedColor.red(); - m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), animatedRed); + // FIXME: ExtendedColor - this will need to handle blending between colors in different color spaces, + // as well as work with non [0-255] Colors. + float red = animatedColor.red(); + m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), red); - float animatedGreen = animatedColor.green(); - m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), animatedGreen); + float green = animatedColor.green(); + m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), green); - float animatedBlue = animatedColor.blue(); - m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), animatedBlue); + float blue = animatedColor.blue(); + m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), blue); - float animatedAlpha = animatedColor.alpha(); - m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), animatedAlpha); + float alpha = animatedColor.alpha(); + m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), alpha); - animatedColor = ColorDistance::clampColor(static_cast<int>(roundf(animatedRed)), static_cast<int>(roundf(animatedGreen)), static_cast<int>(roundf(animatedBlue)), static_cast<int>(roundf(animatedAlpha))); + animatedColor = { roundAndClampColorChannel(red), roundAndClampColorChannel(green), roundAndClampColorChannel(blue), roundAndClampColorChannel(alpha) }; } float SVGAnimatedColorAnimator::calculateDistance(const String& fromString, const String& toString) { - ASSERT(m_contextElement); - Color from = SVGColor::colorFromRGBColorString(fromString); + Color from = CSSParser::parseColor(fromString.stripWhiteSpace()); if (!from.isValid()) return -1; - Color to = SVGColor::colorFromRGBColorString(toString); + Color to = CSSParser::parseColor(toString.stripWhiteSpace()); if (!to.isValid()) return -1; - return ColorDistance(from, to).distance(); + float red = from.red() - to.red(); + float green = from.green() - to.green(); + float blue = from.blue() - to.blue(); + return sqrtf(red * red + green * green + blue * blue); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedColor.h b/Source/WebCore/svg/SVGAnimatedColor.h index 0f74915e7..1e4041bae 100644 --- a/Source/WebCore/svg/SVGAnimatedColor.h +++ b/Source/WebCore/svg/SVGAnimatedColor.h @@ -17,33 +17,26 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedColor_h -#define SVGAnimatedColor_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedTypeAnimator.h" namespace WebCore { -class SVGAnimationElement; - class SVGAnimatedColorAnimator final : public SVGAnimatedTypeAnimator { public: - SVGAnimatedColorAnimator(SVGAnimationElement*, SVGElement*); - - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override { return nullptr; } - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override { } - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override { } - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override { } - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override { } - - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + SVGAnimatedColorAnimator(SVGAnimationElement&, SVGElement&); + +private: + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) final; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) final { return nullptr; } + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) final { } + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) final { } + void animValWillChange(const SVGElementAnimatedPropertyList&) final { } + void animValDidChange(const SVGElementAnimatedPropertyList&) final { } + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) final; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) final; + float calculateDistance(const String& fromString, const String& toString) final; }; -} // namespace WebCore - -#endif // ENABLE(SVG) -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGAnimatedEnumeration.cpp b/Source/WebCore/svg/SVGAnimatedEnumeration.cpp index b861b6033..819d257e6 100644 --- a/Source/WebCore/svg/SVGAnimatedEnumeration.cpp +++ b/Source/WebCore/svg/SVGAnimatedEnumeration.cpp @@ -18,8 +18,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedEnumeration.h" #include "SVGAnimationElement.h" @@ -64,7 +62,6 @@ static inline unsigned enumerationValueForTargetAttribute(SVGElement* targetElem if (attrName == SVGNames::spreadMethodAttr) return SVGPropertyTraits<SVGSpreadMethodType>::fromString(value); -#if ENABLE(FILTERS) if (attrName == SVGNames::edgeModeAttr) return SVGPropertyTraits<EdgeModeType>::fromString(value); @@ -88,15 +85,17 @@ static inline unsigned enumerationValueForTargetAttribute(SVGElement* targetElem return SVGPropertyTraits<ComponentTransferType>::fromString(value); } - if (attrName == SVGNames::modeAttr) - return SVGPropertyTraits<BlendModeType>::fromString(value); + if (attrName == SVGNames::modeAttr) { + BlendMode mode = BlendModeNormal; + parseBlendMode(value, mode); + return mode; + } if (attrName == SVGNames::stitchTilesAttr) return SVGPropertyTraits<SVGStitchOptions>::fromString(value); if (attrName == SVGNames::xChannelSelectorAttr) return SVGPropertyTraits<ChannelSelectorType>::fromString(value); if (attrName == SVGNames::yChannelSelectorAttr) return SVGPropertyTraits<ChannelSelectorType>::fromString(value); -#endif ASSERT_NOT_REACHED(); return 0; @@ -125,7 +124,7 @@ void SVGAnimatedEnumerationAnimator::stopAnimValAnimation(const SVGElementAnimat stopAnimValAnimationForType<SVGAnimatedEnumeration>(animatedTypes); } -void SVGAnimatedEnumerationAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedEnumerationAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::enumeration); } @@ -164,5 +163,3 @@ float SVGAnimatedEnumerationAnimator::calculateDistance(const String&, const Str } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedEnumeration.h b/Source/WebCore/svg/SVGAnimatedEnumeration.h index 5622cc4b5..d6d11497d 100644 --- a/Source/WebCore/svg/SVGAnimatedEnumeration.h +++ b/Source/WebCore/svg/SVGAnimatedEnumeration.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedEnumeration_h -#define SVGAnimatedEnumeration_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedEnumerationPropertyTearOff.h" #include "SVGAnimatedPropertyMacros.h" #include "SVGAnimatedTypeAnimator.h" @@ -31,7 +29,7 @@ typedef SVGAnimatedStaticPropertyTearOff<unsigned> SVGAnimatedEnumeration; // Helper macros to declare/define a SVGAnimatedEnumeration object #define DECLARE_ANIMATED_ENUMERATION(UpperProperty, LowerProperty, EnumType) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedEnumerationPropertyTearOff<EnumType>, EnumType, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedEnumerationPropertyTearOff<EnumType>, EnumType, UpperProperty, LowerProperty, ) #define DEFINE_ANIMATED_ENUMERATION(OwnerType, DOMAttribute, UpperProperty, LowerProperty, EnumType) \ DEFINE_ANIMATED_PROPERTY(AnimatedEnumeration, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -40,19 +38,16 @@ class SVGAnimatedEnumerationAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedEnumerationAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedEnumeration.idl b/Source/WebCore/svg/SVGAnimatedEnumeration.idl index b2210eae1..080a7e9ed 100644 --- a/Source/WebCore/svg/SVGAnimatedEnumeration.idl +++ b/Source/WebCore/svg/SVGAnimatedEnumeration.idl @@ -24,10 +24,9 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedEnumeration { - [StrictTypeChecking, SetterRaisesException] attribute unsigned short baseVal; + [SetterMayThrowException] attribute unsigned short baseVal; readonly attribute unsigned short animVal; }; diff --git a/Source/WebCore/svg/SVGAnimatedInteger.cpp b/Source/WebCore/svg/SVGAnimatedInteger.cpp index 2c7f59869..c3f8c8e78 100644 --- a/Source/WebCore/svg/SVGAnimatedInteger.cpp +++ b/Source/WebCore/svg/SVGAnimatedInteger.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedInteger.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGAnimatedNumber.h" #include <wtf/MathExtras.h> @@ -50,7 +48,7 @@ void SVGAnimatedIntegerAnimator::stopAnimValAnimation(const SVGElementAnimatedPr stopAnimValAnimationForType<SVGAnimatedInteger>(animatedTypes); } -void SVGAnimatedIntegerAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedIntegerAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedInteger>(animatedTypes, type, &SVGAnimatedType::integer); } @@ -102,5 +100,3 @@ float SVGAnimatedIntegerAnimator::calculateDistance(const String& fromString, co } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedInteger.h b/Source/WebCore/svg/SVGAnimatedInteger.h index 9245d40a1..a62a472e9 100644 --- a/Source/WebCore/svg/SVGAnimatedInteger.h +++ b/Source/WebCore/svg/SVGAnimatedInteger.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedInteger_h -#define SVGAnimatedInteger_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyMacros.h" #include "SVGAnimatedStaticPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" @@ -31,7 +29,7 @@ typedef SVGAnimatedStaticPropertyTearOff<int> SVGAnimatedInteger; // Helper macros to declare/define a SVGAnimatedInteger object #define DECLARE_ANIMATED_INTEGER(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedInteger, int, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedInteger, int, UpperProperty, LowerProperty, ) #define DEFINE_ANIMATED_INTEGER(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedInteger, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -47,19 +45,16 @@ public: static void calculateAnimatedInteger(SVGAnimationElement*, float percentage, unsigned repeatCount, int fromInteger, int toInteger, int toAtEndOfDurationInteger, int& animatedInteger); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedInteger.idl b/Source/WebCore/svg/SVGAnimatedInteger.idl index 862bce631..bcf8af07e 100644 --- a/Source/WebCore/svg/SVGAnimatedInteger.idl +++ b/Source/WebCore/svg/SVGAnimatedInteger.idl @@ -24,10 +24,9 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedInteger { - [StrictTypeChecking, SetterRaisesException] attribute long baseVal; + [SetterMayThrowException] attribute long baseVal; readonly attribute long animVal; }; diff --git a/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.cpp b/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.cpp index 9f0be8cdc..5b567ed2a 100644 --- a/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.cpp +++ b/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedIntegerOptionalInteger.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGAnimatedInteger.h" #include "SVGParserUtilities.h" @@ -59,7 +57,7 @@ void SVGAnimatedIntegerOptionalIntegerAnimator::stopAnimValAnimation(const SVGEl stopAnimValAnimationForTypes<SVGAnimatedInteger, SVGAnimatedInteger>(animatedTypes); } -void SVGAnimatedIntegerOptionalIntegerAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedIntegerOptionalIntegerAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValues<SVGAnimatedInteger, SVGAnimatedInteger>(animatedTypes, type, &SVGAnimatedType::integerOptionalInteger); } @@ -107,5 +105,3 @@ float SVGAnimatedIntegerOptionalIntegerAnimator::calculateDistance(const String& } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.h b/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.h index d30895f59..10f1ea98a 100644 --- a/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.h +++ b/Source/WebCore/svg/SVGAnimatedIntegerOptionalInteger.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedIntegerOptionalInteger_h -#define SVGAnimatedIntegerOptionalInteger_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedTypeAnimator.h" namespace WebCore { @@ -31,19 +29,16 @@ class SVGAnimatedIntegerOptionalIntegerAnimator final : public SVGAnimatedTypeAn public: SVGAnimatedIntegerOptionalIntegerAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedLength.cpp b/Source/WebCore/svg/SVGAnimatedLength.cpp index 922fbfeb7..ab58f1831 100644 --- a/Source/WebCore/svg/SVGAnimatedLength.cpp +++ b/Source/WebCore/svg/SVGAnimatedLength.cpp @@ -18,31 +18,23 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedLength.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGAnimatedNumber.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { SVGAnimatedLengthAnimator::SVGAnimatedLengthAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement) : SVGAnimatedTypeAnimator(AnimatedLength, animationElement, contextElement) - , m_lengthMode(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())) + , m_lengthMode(SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())) { } -static inline SVGLength& sharedSVGLength(SVGLengthMode mode, const String& valueAsString) -{ - DEFINE_STATIC_LOCAL(SVGLength, sharedLength, ()); - sharedLength.setValueAsString(valueAsString, mode, ASSERT_NO_EXCEPTION); - return sharedLength; -} - std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthAnimator::constructFromString(const String& string) { - return SVGAnimatedType::createLength(std::make_unique<SVGLength>(m_lengthMode, string)); + return SVGAnimatedType::createLength(std::make_unique<SVGLengthValue>(m_lengthMode, string)); } std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) @@ -55,7 +47,7 @@ void SVGAnimatedLengthAnimator::stopAnimValAnimation(const SVGElementAnimatedPro stopAnimValAnimationForType<SVGAnimatedLength>(animatedTypes); } -void SVGAnimatedLengthAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedLengthAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedLength>(animatedTypes, type, &SVGAnimatedType::length); } @@ -76,15 +68,17 @@ void SVGAnimatedLengthAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnima ASSERT(from->type() == to->type()); SVGLengthContext lengthContext(m_contextElement); - const SVGLength& fromLength = from->length(); - SVGLength& toLength = to->length(); + const auto& fromLength = from->length(); + auto& toLength = to->length(); - toLength.setValue(toLength.value(lengthContext) + fromLength.value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION); + toLength.setValue(toLength.value(lengthContext) + fromLength.value(lengthContext), lengthContext); } -static SVGLength parseLengthFromString(SVGAnimationElement* animationElement, const String& string) +static SVGLengthValue parseLengthFromString(SVGAnimationElement* animationElement, const String& string) { - return sharedSVGLength(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()), string); + SVGLengthValue length; + length.setValueAsString(string, SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())); + return length; } void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated) @@ -92,34 +86,32 @@ void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigne ASSERT(m_animationElement); ASSERT(m_contextElement); - SVGLength fromSVGLength = m_animationElement->animationMode() == ToAnimation ? animated->length() : from->length(); - SVGLength toSVGLength = to->length(); - const SVGLength& toAtEndOfDurationSVGLength = toAtEndOfDuration->length(); - SVGLength& animatedSVGLength = animated->length(); + auto fromSVGLength = m_animationElement->animationMode() == ToAnimation ? animated->length() : from->length(); + auto toSVGLength = to->length(); + const auto& toAtEndOfDurationSVGLength = toAtEndOfDuration->length(); + auto& animatedSVGLength = animated->length(); // Apply CSS inheritance rules. - m_animationElement->adjustForInheritance<SVGLength>(parseLengthFromString, m_animationElement->fromPropertyValueType(), fromSVGLength, m_contextElement); - m_animationElement->adjustForInheritance<SVGLength>(parseLengthFromString, m_animationElement->toPropertyValueType(), toSVGLength, m_contextElement); + m_animationElement->adjustForInheritance<SVGLengthValue>(parseLengthFromString, m_animationElement->fromPropertyValueType(), fromSVGLength, m_contextElement); + m_animationElement->adjustForInheritance<SVGLengthValue>(parseLengthFromString, m_animationElement->toPropertyValueType(), toSVGLength, m_contextElement); SVGLengthContext lengthContext(m_contextElement); float animatedNumber = animatedSVGLength.value(lengthContext); SVGLengthType unitType = percentage < 0.5 ? fromSVGLength.unitType() : toSVGLength.unitType(); m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromSVGLength.value(lengthContext), toSVGLength.value(lengthContext), toAtEndOfDurationSVGLength.value(lengthContext), animatedNumber); - animatedSVGLength.setValue(lengthContext, animatedNumber, m_lengthMode, unitType, ASSERT_NO_EXCEPTION); + animatedSVGLength.setValue(lengthContext, animatedNumber, m_lengthMode, unitType); } float SVGAnimatedLengthAnimator::calculateDistance(const String& fromString, const String& toString) { ASSERT(m_animationElement); ASSERT(m_contextElement); - SVGLengthMode lengthMode = SVGLength::lengthModeForAnimatedLengthAttribute(m_animationElement->attributeName()); - SVGLength from = SVGLength(lengthMode, fromString); - SVGLength to = SVGLength(lengthMode, toString); + auto lengthMode = SVGLengthValue::lengthModeForAnimatedLengthAttribute(m_animationElement->attributeName()); + auto from = SVGLengthValue(lengthMode, fromString); + auto to = SVGLengthValue(lengthMode, toString); SVGLengthContext lengthContext(m_contextElement); return fabsf(to.value(lengthContext) - from.value(lengthContext)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedLength.h b/Source/WebCore/svg/SVGAnimatedLength.h index e17a66d15..14a3460c7 100644 --- a/Source/WebCore/svg/SVGAnimatedLength.h +++ b/Source/WebCore/svg/SVGAnimatedLength.h @@ -17,21 +17,19 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedLength_h -#define SVGAnimatedLength_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" #include "SVGLength.h" namespace WebCore { -typedef SVGAnimatedPropertyTearOff<SVGLength> SVGAnimatedLength; +using SVGAnimatedLength = SVGAnimatedPropertyTearOff<SVGLength>; // Helper macros to declare/define a SVGAnimatedLength object #define DECLARE_ANIMATED_LENGTH(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedLength, SVGLength, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedLength, SVGLengthValue, UpperProperty, LowerProperty, ) #define DEFINE_ANIMATED_LENGTH(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedLength, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -42,22 +40,19 @@ class SVGAnimatedLengthAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedLengthAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; private: SVGLengthMode m_lengthMode; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedLength.idl b/Source/WebCore/svg/SVGAnimatedLength.idl index 7265999b8..21097d1eb 100644 --- a/Source/WebCore/svg/SVGAnimatedLength.idl +++ b/Source/WebCore/svg/SVGAnimatedLength.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedLength { readonly attribute SVGLength baseVal; diff --git a/Source/WebCore/svg/SVGAnimatedLengthList.cpp b/Source/WebCore/svg/SVGAnimatedLengthList.cpp index 44fb8b3ff..95ffb6a81 100644 --- a/Source/WebCore/svg/SVGAnimatedLengthList.cpp +++ b/Source/WebCore/svg/SVGAnimatedLengthList.cpp @@ -18,24 +18,22 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedLengthList.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGAnimatedNumber.h" namespace WebCore { SVGAnimatedLengthListAnimator::SVGAnimatedLengthListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement) : SVGAnimatedTypeAnimator(AnimatedLengthList, animationElement, contextElement) - , m_lengthMode(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())) + , m_lengthMode(SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())) { } std::unique_ptr<SVGAnimatedType> SVGAnimatedLengthListAnimator::constructFromString(const String& string) { - auto animatedType = SVGAnimatedType::createLengthList(std::make_unique<SVGLengthList>()); + auto animatedType = SVGAnimatedType::createLengthList(std::make_unique<SVGLengthListValues>()); animatedType->lengthList().parse(string, m_lengthMode); return animatedType; } @@ -50,7 +48,7 @@ void SVGAnimatedLengthListAnimator::stopAnimValAnimation(const SVGElementAnimate stopAnimValAnimationForType<SVGAnimatedLengthList>(animatedTypes); } -void SVGAnimatedLengthListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedLengthListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedLengthList>(animatedTypes, type, &SVGAnimatedType::lengthList); } @@ -70,8 +68,8 @@ void SVGAnimatedLengthListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGA ASSERT(from->type() == AnimatedLengthList); ASSERT(from->type() == to->type()); - const SVGLengthList& fromLengthList = from->lengthList(); - SVGLengthList& toLengthList = to->lengthList(); + const auto& fromLengthList = from->lengthList(); + auto& toLengthList = to->lengthList(); unsigned fromLengthListSize = fromLengthList.size(); if (!fromLengthListSize || fromLengthListSize != toLengthList.size()) @@ -79,13 +77,13 @@ void SVGAnimatedLengthListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGA SVGLengthContext lengthContext(m_contextElement); for (unsigned i = 0; i < fromLengthListSize; ++i) - toLengthList[i].setValue(toLengthList[i].value(lengthContext) + fromLengthList[i].value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION); + toLengthList[i].setValue(toLengthList[i].value(lengthContext) + fromLengthList[i].value(lengthContext), lengthContext); } -static SVGLengthList parseLengthListFromString(SVGAnimationElement* animationElement, const String& string) +static SVGLengthListValues parseLengthListFromString(SVGAnimationElement* animationElement, const String& string) { - SVGLengthList lengthList; - lengthList.parse(string, SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())); + SVGLengthListValues lengthList; + lengthList.parse(string, SVGLengthValue::lengthModeForAnimatedLengthAttribute(animationElement->attributeName())); return lengthList; } @@ -94,16 +92,16 @@ void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, uns ASSERT(m_animationElement); ASSERT(m_contextElement); - SVGLengthList fromLengthList = m_animationElement->animationMode() == ToAnimation ? animated->lengthList() : from->lengthList(); - SVGLengthList toLengthList = to->lengthList(); - const SVGLengthList& toAtEndOfDurationLengthList = toAtEndOfDuration->lengthList(); - SVGLengthList& animatedLengthList = animated->lengthList(); + auto fromLengthList = m_animationElement->animationMode() == ToAnimation ? animated->lengthList() : from->lengthList(); + auto toLengthList = to->lengthList(); + const auto& toAtEndOfDurationLengthList = toAtEndOfDuration->lengthList(); + auto& animatedLengthList = animated->lengthList(); // Apply CSS inheritance rules. - m_animationElement->adjustForInheritance<SVGLengthList>(parseLengthListFromString, m_animationElement->fromPropertyValueType(), fromLengthList, m_contextElement); - m_animationElement->adjustForInheritance<SVGLengthList>(parseLengthListFromString, m_animationElement->toPropertyValueType(), toLengthList, m_contextElement); + m_animationElement->adjustForInheritance<SVGLengthListValues>(parseLengthListFromString, m_animationElement->fromPropertyValueType(), fromLengthList, m_contextElement); + m_animationElement->adjustForInheritance<SVGLengthListValues>(parseLengthListFromString, m_animationElement->toPropertyValueType(), toLengthList, m_contextElement); - if (!m_animationElement->adjustFromToListValues<SVGLengthList>(fromLengthList, toLengthList, animatedLengthList, percentage)) + if (!m_animationElement->adjustFromToListValues<SVGLengthListValues>(fromLengthList, toLengthList, animatedLengthList, percentage)) return; unsigned fromLengthListSize = fromLengthList.size(); @@ -123,16 +121,14 @@ void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, uns float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationLengthList[i].value(lengthContext) : 0; m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toLengthList[i].value(lengthContext), effectiveToAtEnd, animatedNumber); - animatedLengthList[i].setValue(lengthContext, animatedNumber, m_lengthMode, unitType, ASSERT_NO_EXCEPTION); + animatedLengthList[i].setValue(lengthContext, animatedNumber, m_lengthMode, unitType); } } float SVGAnimatedLengthListAnimator::calculateDistance(const String&, const String&) { - // FIXME: Distance calculation is not possible for SVGLengthList right now. We need the distance for every single value. + // FIXME: Distance calculation is not possible for SVGLengthListValues right now. We need the distance for every single value. return -1; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedLengthList.h b/Source/WebCore/svg/SVGAnimatedLengthList.h index d79e99407..f3619a00e 100644 --- a/Source/WebCore/svg/SVGAnimatedLengthList.h +++ b/Source/WebCore/svg/SVGAnimatedLengthList.h @@ -17,21 +17,20 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedLengthList_h -#define SVGAnimatedLengthList_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedListPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" +#include "SVGLength.h" #include "SVGLengthList.h" namespace WebCore { -typedef SVGAnimatedListPropertyTearOff<SVGLengthList> SVGAnimatedLengthList; +using SVGAnimatedLengthList = SVGAnimatedListPropertyTearOff<SVGLengthListValues>; // Helper macros to declare/define a SVGAnimatedLengthList object #define DECLARE_ANIMATED_LENGTH_LIST(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedLengthList, SVGLengthList, UpperProperty, LowerProperty) +DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedLengthList, SVGLengthListValues, UpperProperty, LowerProperty) #define DEFINE_ANIMATED_LENGTH_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedLengthList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -42,22 +41,19 @@ class SVGAnimatedLengthListAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedLengthListAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; private: SVGLengthMode m_lengthMode; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedLengthList.idl b/Source/WebCore/svg/SVGAnimatedLengthList.idl index bf300e629..4fd75528d 100644 --- a/Source/WebCore/svg/SVGAnimatedLengthList.idl +++ b/Source/WebCore/svg/SVGAnimatedLengthList.idl @@ -24,10 +24,8 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedLengthList { readonly attribute SVGLengthList baseVal; readonly attribute SVGLengthList animVal; }; - diff --git a/Source/WebCore/svg/SVGAnimatedNumber.cpp b/Source/WebCore/svg/SVGAnimatedNumber.cpp index dc0b3152f..4f1ea9a8d 100644 --- a/Source/WebCore/svg/SVGAnimatedNumber.cpp +++ b/Source/WebCore/svg/SVGAnimatedNumber.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedNumber.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGParserUtilities.h" namespace WebCore { @@ -51,7 +49,7 @@ void SVGAnimatedNumberAnimator::stopAnimValAnimation(const SVGElementAnimatedPro stopAnimValAnimationForType<SVGAnimatedNumber>(animatedTypes); } -void SVGAnimatedNumberAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedNumberAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedNumber>(animatedTypes, type, &SVGAnimatedType::number); } @@ -109,5 +107,3 @@ float SVGAnimatedNumberAnimator::calculateDistance(const String& fromString, con } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedNumber.h b/Source/WebCore/svg/SVGAnimatedNumber.h index cadf442f5..55eb121f3 100644 --- a/Source/WebCore/svg/SVGAnimatedNumber.h +++ b/Source/WebCore/svg/SVGAnimatedNumber.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedNumber_h -#define SVGAnimatedNumber_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyMacros.h" #include "SVGAnimatedStaticPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" @@ -31,7 +29,7 @@ typedef SVGAnimatedStaticPropertyTearOff<float> SVGAnimatedNumber; // Helper macros to declare/define a SVGAnimatedNumber object #define DECLARE_ANIMATED_NUMBER(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedNumber, float, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedNumber, float, UpperProperty, LowerProperty, ) #define DEFINE_ANIMATED_NUMBER(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedNumber, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -45,19 +43,16 @@ class SVGAnimatedNumberAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedNumberAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedNumber.idl b/Source/WebCore/svg/SVGAnimatedNumber.idl index c5e386346..e4cd9f407 100644 --- a/Source/WebCore/svg/SVGAnimatedNumber.idl +++ b/Source/WebCore/svg/SVGAnimatedNumber.idl @@ -25,10 +25,9 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedNumber { - [StrictTypeChecking, SetterRaisesException] attribute float baseVal; - readonly attribute float animVal; + [SetterMayThrowException] attribute unrestricted float baseVal; + readonly attribute unrestricted float animVal; }; diff --git a/Source/WebCore/svg/SVGAnimatedNumberList.cpp b/Source/WebCore/svg/SVGAnimatedNumberList.cpp index a4581dce9..87f973a1b 100644 --- a/Source/WebCore/svg/SVGAnimatedNumberList.cpp +++ b/Source/WebCore/svg/SVGAnimatedNumberList.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedNumberList.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGAnimatedNumber.h" namespace WebCore { @@ -34,7 +32,7 @@ SVGAnimatedNumberListAnimator::SVGAnimatedNumberListAnimator(SVGAnimationElement std::unique_ptr<SVGAnimatedType> SVGAnimatedNumberListAnimator::constructFromString(const String& string) { - auto animatedType = SVGAnimatedType::createNumberList(std::make_unique<SVGNumberList>()); + auto animatedType = SVGAnimatedType::createNumberList(std::make_unique<SVGNumberListValues>()); animatedType->numberList().parse(string); return animatedType; } @@ -49,7 +47,7 @@ void SVGAnimatedNumberListAnimator::stopAnimValAnimation(const SVGElementAnimate stopAnimValAnimationForType<SVGAnimatedNumberList>(animatedTypes); } -void SVGAnimatedNumberListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedNumberListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedNumberList>(animatedTypes, type, &SVGAnimatedType::numberList); } @@ -69,8 +67,8 @@ void SVGAnimatedNumberListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGA ASSERT(from->type() == AnimatedNumberList); ASSERT(from->type() == to->type()); - const SVGNumberList& fromNumberList = from->numberList(); - SVGNumberList& toNumberList = to->numberList(); + const auto& fromNumberList = from->numberList(); + auto& toNumberList = to->numberList(); unsigned fromNumberListSize = fromNumberList.size(); if (!fromNumberListSize || fromNumberListSize != toNumberList.size()) @@ -84,11 +82,11 @@ void SVGAnimatedNumberListAnimator::calculateAnimatedValue(float percentage, uns { ASSERT(m_animationElement); - const SVGNumberList& fromNumberList = m_animationElement->animationMode() == ToAnimation ? animated->numberList() : from->numberList(); - const SVGNumberList& toNumberList = to->numberList(); - const SVGNumberList& toAtEndOfDurationNumberList = toAtEndOfDuration->numberList(); - SVGNumberList& animatedNumberList = animated->numberList(); - if (!m_animationElement->adjustFromToListValues<SVGNumberList>(fromNumberList, toNumberList, animatedNumberList, percentage)) + const auto& fromNumberList = m_animationElement->animationMode() == ToAnimation ? animated->numberList() : from->numberList(); + const auto& toNumberList = to->numberList(); + const auto& toAtEndOfDurationNumberList = toAtEndOfDuration->numberList(); + auto& animatedNumberList = animated->numberList(); + if (!m_animationElement->adjustFromToListValues<SVGNumberListValues>(fromNumberList, toNumberList, animatedNumberList, percentage)) return; unsigned fromNumberListSize = fromNumberList.size(); @@ -104,10 +102,8 @@ void SVGAnimatedNumberListAnimator::calculateAnimatedValue(float percentage, uns float SVGAnimatedNumberListAnimator::calculateDistance(const String&, const String&) { - // FIXME: Distance calculation is not possible for SVGNumberList right now. We need the distance for every single value. + // FIXME: Distance calculation is not possible for SVGNumberListValues right now. We need the distance for every single value. return -1; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedNumberList.h b/Source/WebCore/svg/SVGAnimatedNumberList.h index 031856354..aad51a04f 100644 --- a/Source/WebCore/svg/SVGAnimatedNumberList.h +++ b/Source/WebCore/svg/SVGAnimatedNumberList.h @@ -17,21 +17,20 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedNumberList_h -#define SVGAnimatedNumberList_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedListPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" +#include "SVGNumber.h" #include "SVGNumberList.h" namespace WebCore { -typedef SVGAnimatedListPropertyTearOff<SVGNumberList> SVGAnimatedNumberList; +using SVGAnimatedNumberList = SVGAnimatedListPropertyTearOff<SVGNumberListValues>; // Helper macros to declare/define a SVGAnimatedNumberList object #define DECLARE_ANIMATED_NUMBER_LIST(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedNumberList, SVGNumberList, UpperProperty, LowerProperty) +DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedNumberList, SVGNumberListValues, UpperProperty, LowerProperty) #define DEFINE_ANIMATED_NUMBER_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedNumberList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -42,19 +41,16 @@ class SVGAnimatedNumberListAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedNumberListAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedNumberList.idl b/Source/WebCore/svg/SVGAnimatedNumberList.idl index 9a836dbf7..9ece646d9 100644 --- a/Source/WebCore/svg/SVGAnimatedNumberList.idl +++ b/Source/WebCore/svg/SVGAnimatedNumberList.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedNumberList { readonly attribute SVGNumberList baseVal; diff --git a/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.cpp b/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.cpp index 729a5d80d..3c4ca864d 100644 --- a/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.cpp +++ b/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedNumberOptionalNumber.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGAnimatedNumber.h" #include "SVGParserUtilities.h" @@ -54,7 +52,7 @@ void SVGAnimatedNumberOptionalNumberAnimator::stopAnimValAnimation(const SVGElem stopAnimValAnimationForTypes<SVGAnimatedNumber, SVGAnimatedNumber>(animatedTypes); } -void SVGAnimatedNumberOptionalNumberAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedNumberOptionalNumberAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValues<SVGAnimatedNumber, SVGAnimatedNumber>(animatedTypes, type, &SVGAnimatedType::numberOptionalNumber); } @@ -102,5 +100,3 @@ float SVGAnimatedNumberOptionalNumberAnimator::calculateDistance(const String&, } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.h b/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.h index 07a6a74fb..66c4fc0e8 100644 --- a/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.h +++ b/Source/WebCore/svg/SVGAnimatedNumberOptionalNumber.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedNumberOptionalNumber_h -#define SVGAnimatedNumberOptionalNumber_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedTypeAnimator.h" namespace WebCore { @@ -31,19 +29,16 @@ class SVGAnimatedNumberOptionalNumberAnimator final : public SVGAnimatedTypeAnim public: SVGAnimatedNumberOptionalNumberAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedPath.cpp b/Source/WebCore/svg/SVGAnimatedPath.cpp index b210ad95f..29e249bc8 100644 --- a/Source/WebCore/svg/SVGAnimatedPath.cpp +++ b/Source/WebCore/svg/SVGAnimatedPath.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedPath.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGAnimatedPathSegListPropertyTearOff.h" #include "SVGPathUtilities.h" @@ -36,47 +34,53 @@ SVGAnimatedPathAnimator::SVGAnimatedPathAnimator(SVGAnimationElement* animationE std::unique_ptr<SVGAnimatedType> SVGAnimatedPathAnimator::constructFromString(const String& string) { auto byteStream = std::make_unique<SVGPathByteStream>(); - buildSVGPathByteStreamFromString(string, byteStream.get(), UnalteredParsing); - return SVGAnimatedType::createPath(std::move(byteStream)); + buildSVGPathByteStreamFromString(string, *byteStream, UnalteredParsing); + return SVGAnimatedType::createPath(WTFMove(byteStream)); } std::unique_ptr<SVGAnimatedType> SVGAnimatedPathAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) { ASSERT(animatedTypes.size() >= 1); - SVGAnimatedPathSegListPropertyTearOff* property = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get()); - const SVGPathSegList& baseValue = property->currentBaseValue(); // Build initial path byte stream. auto byteStream = std::make_unique<SVGPathByteStream>(); - buildSVGPathByteStreamFromSVGPathSegList(baseValue, byteStream.get(), UnalteredParsing); + resetAnimValToBaseVal(animatedTypes, byteStream.get()); + return SVGAnimatedType::createPath(WTFMove(byteStream)); +} - Vector<RefPtr<SVGAnimatedPathSegListPropertyTearOff>> result; +void SVGAnimatedPathAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) +{ + stopAnimValAnimationForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes); +} - SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end(); - for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) - result.append(castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(it->properties[0].get())); +void SVGAnimatedPathAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGPathByteStream* byteStream) +{ + SVGAnimatedPathSegListPropertyTearOff* property = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get()); + const auto& baseValue = property->currentBaseValue(); - SVGElementInstance::InstanceUpdateBlocker blocker(property->contextElement()); + buildSVGPathByteStreamFromSVGPathSegListValues(baseValue, *byteStream, UnalteredParsing); - size_t resultSize = result.size(); - for (size_t i = 0; i < resultSize; ++i) - result[i]->animationStarted(byteStream.get(), &baseValue); + Vector<RefPtr<SVGAnimatedPathSegListPropertyTearOff>> result; - return SVGAnimatedType::createPath(std::move(byteStream)); -} + for (auto& type : animatedTypes) { + auto* segment = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(type.properties[0].get()); + if (segment->isAnimating()) + continue; + result.append(segment); + } -void SVGAnimatedPathAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) -{ - stopAnimValAnimationForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes); + if (!result.isEmpty()) { + SVGElement::InstanceUpdateBlocker blocker(*property->contextElement()); + for (auto& segment : result) + segment->animationStarted(byteStream, &baseValue); + } } -void SVGAnimatedPathAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedPathAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { ASSERT(animatedTypes.size() >= 1); - ASSERT(type); - ASSERT(type->type() == m_type); - const SVGPathSegList& baseValue = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get())->currentBaseValue(); - buildSVGPathByteStreamFromSVGPathSegList(baseValue, type->path(), UnalteredParsing); + ASSERT(type.type() == m_type); + resetAnimValToBaseVal(animatedTypes, type.path()); } void SVGAnimatedPathAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes) @@ -99,7 +103,7 @@ void SVGAnimatedPathAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimate unsigned fromPathSize = fromPath->size(); if (!fromPathSize || fromPathSize != toPath->size()) return; - addToSVGPathByteStream(toPath, fromPath); + addToSVGPathByteStream(*toPath, *fromPath); } void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated) @@ -128,15 +132,15 @@ void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned if (!m_animationElement->adjustFromToListValues<SVGPathByteStream>(*fromPath, *toPath, *animatedPath, percentage, false)) return; - buildAnimatedSVGPathByteStream(fromPath, toPath, animatedPath, percentage); + buildAnimatedSVGPathByteStream(*fromPath, *toPath, *animatedPath, percentage); // Handle additive='sum'. if (lastAnimatedPath) - addToSVGPathByteStream(animatedPath, lastAnimatedPath.get()); + addToSVGPathByteStream(*animatedPath, *lastAnimatedPath); // Handle accumulate='sum'. if (m_animationElement->isAccumulated() && repeatCount) - addToSVGPathByteStream(animatedPath, toAtEndOfDurationPath, repeatCount); + addToSVGPathByteStream(*animatedPath, *toAtEndOfDurationPath, repeatCount); } float SVGAnimatedPathAnimator::calculateDistance(const String&, const String&) @@ -146,5 +150,3 @@ float SVGAnimatedPathAnimator::calculateDistance(const String&, const String&) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedPath.h b/Source/WebCore/svg/SVGAnimatedPath.h index e0c4cbee3..7feb70f02 100644 --- a/Source/WebCore/svg/SVGAnimatedPath.h +++ b/Source/WebCore/svg/SVGAnimatedPath.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPath_h -#define SVGAnimatedPath_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedTypeAnimator.h" namespace WebCore { @@ -31,19 +29,19 @@ class SVGAnimatedPathAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedPathAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; + +private: + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGPathByteStream*); }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedPointList.cpp b/Source/WebCore/svg/SVGAnimatedPointList.cpp index e02c5dc46..5f0780d52 100644 --- a/Source/WebCore/svg/SVGAnimatedPointList.cpp +++ b/Source/WebCore/svg/SVGAnimatedPointList.cpp @@ -18,13 +18,12 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedPointList.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGParserUtilities.h" -#include "SVGPointList.h" +#include "SVGPoint.h" +#include "SVGPointListValues.h" namespace WebCore { @@ -35,7 +34,7 @@ SVGAnimatedPointListAnimator::SVGAnimatedPointListAnimator(SVGAnimationElement* std::unique_ptr<SVGAnimatedType> SVGAnimatedPointListAnimator::constructFromString(const String& string) { - auto animatedType = SVGAnimatedType::createPointList(std::make_unique<SVGPointList>()); + auto animatedType = SVGAnimatedType::createPointList(std::make_unique<SVGPointListValues>()); pointsListFromSVGData(animatedType->pointList(), string); return animatedType; } @@ -50,7 +49,7 @@ void SVGAnimatedPointListAnimator::stopAnimValAnimation(const SVGElementAnimated stopAnimValAnimationForType<SVGAnimatedPointList>(animatedTypes); } -void SVGAnimatedPointListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedPointListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedPointList>(animatedTypes, type, &SVGAnimatedType::pointList); } @@ -70,8 +69,8 @@ void SVGAnimatedPointListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAn ASSERT(from->type() == AnimatedPoints); ASSERT(from->type() == to->type()); - const SVGPointList& fromPointList = from->pointList(); - SVGPointList& toPointList = to->pointList(); + const auto& fromPointList = from->pointList(); + auto& toPointList = to->pointList(); unsigned fromPointListSize = fromPointList.size(); if (!fromPointListSize || fromPointListSize != toPointList.size()) @@ -85,11 +84,11 @@ void SVGAnimatedPointListAnimator::calculateAnimatedValue(float percentage, unsi { ASSERT(m_animationElement); - const SVGPointList& fromPointList = m_animationElement->animationMode() == ToAnimation ? animated->pointList() : from->pointList(); - const SVGPointList& toPointList = to->pointList(); - const SVGPointList& toAtEndOfDurationPointList = toAtEndOfDuration->pointList(); - SVGPointList& animatedPointList = animated->pointList(); - if (!m_animationElement->adjustFromToListValues<SVGPointList>(fromPointList, toPointList, animatedPointList, percentage)) + const auto& fromPointList = m_animationElement->animationMode() == ToAnimation ? animated->pointList() : from->pointList(); + const auto& toPointList = to->pointList(); + const auto& toAtEndOfDurationPointList = toAtEndOfDuration->pointList(); + auto& animatedPointList = animated->pointList(); + if (!m_animationElement->adjustFromToListValues<SVGPointListValues>(fromPointList, toPointList, animatedPointList, percentage)) return; unsigned fromPointListSize = fromPointList.size(); @@ -112,10 +111,8 @@ void SVGAnimatedPointListAnimator::calculateAnimatedValue(float percentage, unsi float SVGAnimatedPointListAnimator::calculateDistance(const String&, const String&) { - // FIXME: Distance calculation is not possible for SVGPointList right now. We need the distance of for every single value. + // FIXME: Distance calculation is not possible for SVGPointListValues right now. We need the distance of for every single value. return -1; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedPointList.h b/Source/WebCore/svg/SVGAnimatedPointList.h index 3476d03be..2090e827d 100644 --- a/Source/WebCore/svg/SVGAnimatedPointList.h +++ b/Source/WebCore/svg/SVGAnimatedPointList.h @@ -17,17 +17,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPointList_h -#define SVGAnimatedPointList_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedListPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" #include "SVGPointList.h" namespace WebCore { -typedef SVGAnimatedListPropertyTearOff<SVGPointList> SVGAnimatedPointList; +using SVGAnimatedPointList = SVGAnimatedListPropertyTearOff<SVGPointListValues>; class SVGAnimationElement; @@ -35,19 +33,16 @@ class SVGAnimatedPointListAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedPointListAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.cpp b/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.cpp index 7fe5d386a..801025b45 100644 --- a/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.cpp +++ b/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedPreserveAspectRatio.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" namespace WebCore { @@ -33,7 +31,7 @@ SVGAnimatedPreserveAspectRatioAnimator::SVGAnimatedPreserveAspectRatioAnimator(S std::unique_ptr<SVGAnimatedType> SVGAnimatedPreserveAspectRatioAnimator::constructFromString(const String& string) { - auto animatedType = SVGAnimatedType::createPreserveAspectRatio(std::make_unique<SVGPreserveAspectRatio>()); + auto animatedType = SVGAnimatedType::createPreserveAspectRatio(std::make_unique<SVGPreserveAspectRatioValue>()); animatedType->preserveAspectRatio().parse(string); return animatedType; } @@ -48,7 +46,7 @@ void SVGAnimatedPreserveAspectRatioAnimator::stopAnimValAnimation(const SVGEleme stopAnimValAnimationForType<SVGAnimatedPreserveAspectRatio>(animatedTypes); } -void SVGAnimatedPreserveAspectRatioAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedPreserveAspectRatioAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedPreserveAspectRatio>(animatedTypes, type, &SVGAnimatedType::preserveAspectRatio); } @@ -73,11 +71,11 @@ void SVGAnimatedPreserveAspectRatioAnimator::calculateAnimatedValue(float percen ASSERT(m_animationElement); ASSERT(m_contextElement); - const SVGPreserveAspectRatio& fromPreserveAspectRatio = m_animationElement->animationMode() == ToAnimation ? animated->preserveAspectRatio() : from->preserveAspectRatio(); - const SVGPreserveAspectRatio& toPreserveAspectRatio = to->preserveAspectRatio(); - SVGPreserveAspectRatio& animatedPreserveAspectRatio = animated->preserveAspectRatio(); + const auto& fromPreserveAspectRatio = m_animationElement->animationMode() == ToAnimation ? animated->preserveAspectRatio() : from->preserveAspectRatio(); + const auto& toPreserveAspectRatio = to->preserveAspectRatio(); + auto& animatedPreserveAspectRatio = animated->preserveAspectRatio(); - m_animationElement->animateDiscreteType<SVGPreserveAspectRatio>(percentage, fromPreserveAspectRatio, toPreserveAspectRatio, animatedPreserveAspectRatio); + m_animationElement->animateDiscreteType<SVGPreserveAspectRatioValue>(percentage, fromPreserveAspectRatio, toPreserveAspectRatio, animatedPreserveAspectRatio); } float SVGAnimatedPreserveAspectRatioAnimator::calculateDistance(const String&, const String&) @@ -87,5 +85,3 @@ float SVGAnimatedPreserveAspectRatioAnimator::calculateDistance(const String&, c } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.h b/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.h index 2039e418e..8f9e76b08 100644 --- a/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.h +++ b/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.h @@ -17,21 +17,22 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPreserveAspectRatio_h -#define SVGAnimatedPreserveAspectRatio_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" #include "SVGPreserveAspectRatio.h" namespace WebCore { -typedef SVGAnimatedPropertyTearOff<SVGPreserveAspectRatio> SVGAnimatedPreserveAspectRatio; +template<typename T> +class SVGPropertyTearOff; + +using SVGAnimatedPreserveAspectRatio = SVGAnimatedPropertyTearOff<SVGPreserveAspectRatio>; // Helper macros to declare/define a SVGAnimatedPreserveAspectRatio object #define DECLARE_ANIMATED_PRESERVEASPECTRATIO(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedPreserveAspectRatio, SVGPreserveAspectRatio, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedPreserveAspectRatio, SVGPreserveAspectRatioValue, UpperProperty, LowerProperty, ) #define DEFINE_ANIMATED_PRESERVEASPECTRATIO(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedPreserveAspectRatio, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -42,19 +43,16 @@ class SVGAnimatedPreserveAspectRatioAnimator final : public SVGAnimatedTypeAnima public: SVGAnimatedPreserveAspectRatioAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.idl b/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.idl index 2d2bbe08c..ffeb1b37f 100644 --- a/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.idl +++ b/Source/WebCore/svg/SVGAnimatedPreserveAspectRatio.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedPreserveAspectRatio { readonly attribute SVGPreserveAspectRatio baseVal; diff --git a/Source/WebCore/svg/SVGAnimatedRect.cpp b/Source/WebCore/svg/SVGAnimatedRect.cpp index 63046494e..b94abf59c 100644 --- a/Source/WebCore/svg/SVGAnimatedRect.cpp +++ b/Source/WebCore/svg/SVGAnimatedRect.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedRect.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" #include "SVGParserUtilities.h" namespace WebCore { @@ -49,7 +47,7 @@ void SVGAnimatedRectAnimator::stopAnimValAnimation(const SVGElementAnimatedPrope stopAnimValAnimationForType<SVGAnimatedRect>(animatedTypes); } -void SVGAnimatedRectAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedRectAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedRect>(animatedTypes, type, &SVGAnimatedType::rect); } @@ -101,5 +99,3 @@ float SVGAnimatedRectAnimator::calculateDistance(const String&, const String&) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedRect.h b/Source/WebCore/svg/SVGAnimatedRect.h index c369ec8ea..c8fce4bed 100644 --- a/Source/WebCore/svg/SVGAnimatedRect.h +++ b/Source/WebCore/svg/SVGAnimatedRect.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedRect_h -#define SVGAnimatedRect_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyMacros.h" #include "SVGAnimatedPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" @@ -28,11 +26,13 @@ namespace WebCore { -typedef SVGAnimatedPropertyTearOff<FloatRect> SVGAnimatedRect; +class SVGRect; + +using SVGAnimatedRect = SVGAnimatedPropertyTearOff<SVGRect>; // Helper macros to declare/define a SVGAnimatedRect object #define DECLARE_ANIMATED_RECT(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedRect, FloatRect, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedRect, FloatRect, UpperProperty, LowerProperty, ) #define DEFINE_ANIMATED_RECT(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedRect, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -43,21 +43,18 @@ class SVGAnimatedRectAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedRectAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; static bool parseSVGRect(const String&, FloatRect&); }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedRect.idl b/Source/WebCore/svg/SVGAnimatedRect.idl index e948fc7f5..c72effd84 100644 --- a/Source/WebCore/svg/SVGAnimatedRect.idl +++ b/Source/WebCore/svg/SVGAnimatedRect.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedRect { readonly attribute SVGRect baseVal; diff --git a/Source/WebCore/svg/SVGAnimatedString.cpp b/Source/WebCore/svg/SVGAnimatedString.cpp index 1000d0e6e..6985ecbed 100644 --- a/Source/WebCore/svg/SVGAnimatedString.cpp +++ b/Source/WebCore/svg/SVGAnimatedString.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedString.h" -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" namespace WebCore { @@ -48,7 +46,7 @@ void SVGAnimatedStringAnimator::stopAnimValAnimation(const SVGElementAnimatedPro stopAnimValAnimationForType<SVGAnimatedString>(animatedTypes); } -void SVGAnimatedStringAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedStringAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedString>(animatedTypes, type, &SVGAnimatedType::string); } @@ -96,5 +94,3 @@ float SVGAnimatedStringAnimator::calculateDistance(const String&, const String&) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedString.h b/Source/WebCore/svg/SVGAnimatedString.h index bf4d87b00..2c8c33546 100644 --- a/Source/WebCore/svg/SVGAnimatedString.h +++ b/Source/WebCore/svg/SVGAnimatedString.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedString_h -#define SVGAnimatedString_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyMacros.h" #include "SVGAnimatedStaticPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" @@ -31,7 +29,10 @@ typedef SVGAnimatedStaticPropertyTearOff<String> SVGAnimatedString; // Helper macros to declare/define a SVGAnimatedString object #define DECLARE_ANIMATED_STRING(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(SVGAnimatedString, String, UpperProperty, LowerProperty) +DECLARE_ANIMATED_PROPERTY(SVGAnimatedString, String, UpperProperty, LowerProperty, ) + +#define DECLARE_ANIMATED_STRING_OVERRIDE(UpperProperty, LowerProperty) \ +DECLARE_ANIMATED_PROPERTY(SVGAnimatedString, String, UpperProperty, LowerProperty, override) #define DEFINE_ANIMATED_STRING(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedString, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -42,19 +43,16 @@ class SVGAnimatedStringAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedStringAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedString.idl b/Source/WebCore/svg/SVGAnimatedString.idl index 73e60efc4..a1da5677e 100644 --- a/Source/WebCore/svg/SVGAnimatedString.idl +++ b/Source/WebCore/svg/SVGAnimatedString.idl @@ -24,10 +24,9 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedString { - [SetterRaisesException] attribute DOMString baseVal; + [SetterMayThrowException] attribute DOMString baseVal; readonly attribute DOMString animVal; }; diff --git a/Source/WebCore/svg/SVGAnimatedTransformList.cpp b/Source/WebCore/svg/SVGAnimatedTransformList.cpp index 57318692b..20356e0bb 100644 --- a/Source/WebCore/svg/SVGAnimatedTransformList.cpp +++ b/Source/WebCore/svg/SVGAnimatedTransformList.cpp @@ -22,8 +22,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedTransformList.h" #include "SVGAnimateTransformElement.h" @@ -35,7 +33,7 @@ namespace WebCore { SVGAnimatedTransformListAnimator::SVGAnimatedTransformListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement) : SVGAnimatedTypeAnimator(AnimatedTransformList, animationElement, contextElement) - , m_transformTypeString(SVGTransform::transformTypePrefixForParsing(toSVGAnimateTransformElement(animationElement)->transformType())) + , m_transformTypeString(SVGTransformValue::transformTypePrefixForParsing(downcast<SVGAnimateTransformElement>(animationElement)->transformType())) { // Only <animateTransform> uses this animator, as <animate> doesn't allow to animate transform lists directly. ASSERT(animationElement->hasTagName(SVGNames::animateTransformTag)); @@ -43,7 +41,7 @@ SVGAnimatedTransformListAnimator::SVGAnimatedTransformListAnimator(SVGAnimationE std::unique_ptr<SVGAnimatedType> SVGAnimatedTransformListAnimator::constructFromString(const String& string) { - auto animatedType = SVGAnimatedType::createTransformList(std::make_unique<SVGTransformList>()); + auto animatedType = SVGAnimatedType::createTransformList(std::make_unique<SVGTransformListValues>()); animatedType->transformList().parse(m_transformTypeString + string + ')'); ASSERT(animatedType->transformList().size() <= 1); return animatedType; @@ -59,7 +57,7 @@ void SVGAnimatedTransformListAnimator::stopAnimValAnimation(const SVGElementAnim stopAnimValAnimationForType<SVGAnimatedTransformList>(animatedTypes); } -void SVGAnimatedTransformListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type) +void SVGAnimatedTransformListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type) { resetFromBaseValue<SVGAnimatedTransformList>(animatedTypes, type, &SVGAnimatedType::transformList); } @@ -79,15 +77,15 @@ void SVGAnimatedTransformListAnimator::addAnimatedTypes(SVGAnimatedType* from, S ASSERT(from->type() == AnimatedTransformList); ASSERT(from->type() == to->type()); - const SVGTransformList& fromTransformList = from->transformList(); - SVGTransformList& toTransformList = to->transformList(); - unsigned fromTransformListSize = fromTransformList.size(); + const auto& fromTransformList = from->transformList(); + auto& toTransformList = to->transformList(); + auto fromTransformListSize = fromTransformList.size(); if (!fromTransformListSize || fromTransformListSize != toTransformList.size()) return; ASSERT(fromTransformListSize == 1); - const SVGTransform& fromTransform = fromTransformList[0]; - SVGTransform& toTransform = toTransformList[0]; + const auto& fromTransform = fromTransformList[0]; + auto& toTransform = toTransformList[0]; ASSERT(fromTransform.type() == toTransform.type()); toTransform = SVGTransformDistance::addSVGTransforms(fromTransform, toTransform); @@ -100,25 +98,25 @@ void SVGAnimatedTransformListAnimator::calculateAnimatedValue(float percentage, // Spec: To animations provide specific functionality to get a smooth change from the underlying value to the // ‘to’ attribute value, which conflicts mathematically with the requirement for additive transform animations // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations for ‘animateTransform’ is undefined. - const SVGTransformList& fromTransformList = from->transformList(); - const SVGTransformList& toTransformList = to->transformList(); - const SVGTransformList& toAtEndOfDurationTransformList = toAtEndOfDuration->transformList(); - SVGTransformList& animatedTransformList = animated->transformList(); + const auto& fromTransformList = from->transformList(); + const auto& toTransformList = to->transformList(); + const auto& toAtEndOfDurationTransformList = toAtEndOfDuration->transformList(); + auto& animatedTransformList = animated->transformList(); // Pass false to 'resizeAnimatedListIfNeeded' here, as the special post-multiplication behavior of <animateTransform> needs to be respected below. - if (!m_animationElement->adjustFromToListValues<SVGTransformList>(fromTransformList, toTransformList, animatedTransformList, percentage, false)) + if (!m_animationElement->adjustFromToListValues<SVGTransformListValues>(fromTransformList, toTransformList, animatedTransformList, percentage, false)) return; // Never resize the animatedTransformList to the toTransformList size, instead either clear the list or append to it. if (!animatedTransformList.isEmpty() && (!m_animationElement->isAdditive() || m_animationElement->animationMode() == ToAnimation)) animatedTransformList.clear(); - unsigned fromTransformListSize = fromTransformList.size(); - const SVGTransform& toTransform = toTransformList[0]; - const SVGTransform effectiveFrom = fromTransformListSize ? fromTransformList[0] : SVGTransform(toTransform.type(), SVGTransform::ConstructZeroTransform); - SVGTransform currentTransform = SVGTransformDistance(effectiveFrom, toTransform).scaledDistance(percentage).addToSVGTransform(effectiveFrom); + auto fromTransformListSize = fromTransformList.size(); + const auto& toTransform = toTransformList[0]; + const auto effectiveFrom = fromTransformListSize ? fromTransformList[0] : SVGTransformValue(toTransform.type(), SVGTransformValue::ConstructZeroTransform); + auto currentTransform = SVGTransformDistance(effectiveFrom, toTransform).scaledDistance(percentage).addToSVGTransform(effectiveFrom); if (m_animationElement->isAccumulated() && repeatCount) { - const SVGTransform effectiveToAtEnd = toAtEndOfDurationTransformList.size() ? toAtEndOfDurationTransformList[0] : SVGTransform(toTransform.type(), SVGTransform::ConstructZeroTransform); + const auto effectiveToAtEnd = toAtEndOfDurationTransformList.size() ? toAtEndOfDurationTransformList[0] : SVGTransformValue(toTransform.type(), SVGTransformValue::ConstructZeroTransform); animatedTransformList.append(SVGTransformDistance::addSVGTransforms(currentTransform, effectiveToAtEnd, repeatCount)); } else animatedTransformList.append(currentTransform); @@ -130,11 +128,11 @@ float SVGAnimatedTransformListAnimator::calculateDistance(const String& fromStri // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example) // is paced separately. To implement this we need to treat each component as individual animation everywhere. - std::unique_ptr<SVGAnimatedType> from = constructFromString(fromString); - std::unique_ptr<SVGAnimatedType> to = constructFromString(toString); + auto from = constructFromString(fromString); + auto to = constructFromString(toString); - SVGTransformList& fromTransformList = from->transformList(); - SVGTransformList& toTransformList = to->transformList(); + auto& fromTransformList = from->transformList(); + auto& toTransformList = to->transformList(); unsigned itemsCount = fromTransformList.size(); if (!itemsCount || itemsCount != toTransformList.size()) return -1; @@ -150,5 +148,3 @@ float SVGAnimatedTransformListAnimator::calculateDistance(const String& fromStri } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedTransformList.h b/Source/WebCore/svg/SVGAnimatedTransformList.h index 387229103..4c9022a5b 100644 --- a/Source/WebCore/svg/SVGAnimatedTransformList.h +++ b/Source/WebCore/svg/SVGAnimatedTransformList.h @@ -17,20 +17,19 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedTransformList_h -#define SVGAnimatedTransformList_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedTransformListPropertyTearOff.h" #include "SVGAnimatedTypeAnimator.h" +#include "SVGTransformList.h" namespace WebCore { -typedef SVGAnimatedTransformListPropertyTearOff SVGAnimatedTransformList; +using SVGAnimatedTransformList = SVGAnimatedTransformListPropertyTearOff; // Helper macros to declare/define a SVGAnimatedTransformList object #define DECLARE_ANIMATED_TRANSFORM_LIST(UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedTransformList, SVGTransformList, UpperProperty, LowerProperty) +DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedTransformList, SVGTransformListValues, UpperProperty, LowerProperty) #define DEFINE_ANIMATED_TRANSFORM_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \ DEFINE_ANIMATED_PROPERTY(AnimatedTransformList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty) @@ -41,22 +40,19 @@ class SVGAnimatedTransformListAnimator final : public SVGAnimatedTypeAnimator { public: SVGAnimatedTransformListAnimator(SVGAnimationElement*, SVGElement*); - virtual std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; - virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) override; - virtual void animValWillChange(const SVGElementAnimatedPropertyList&) override; - virtual void animValDidChange(const SVGElementAnimatedPropertyList&) override; + std::unique_ptr<SVGAnimatedType> constructFromString(const String&) override; + std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) override; + void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) override; + void animValWillChange(const SVGElementAnimatedPropertyList&) override; + void animValDidChange(const SVGElementAnimatedPropertyList&) override; - virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; - virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; - virtual float calculateDistance(const String& fromString, const String& toString) override; + void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) override; + void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) override; + float calculateDistance(const String& fromString, const String& toString) override; private: const String& m_transformTypeString; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGAnimatedTransformList.idl b/Source/WebCore/svg/SVGAnimatedTransformList.idl index de4c65937..a703ce1c9 100644 --- a/Source/WebCore/svg/SVGAnimatedTransformList.idl +++ b/Source/WebCore/svg/SVGAnimatedTransformList.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SkipVTableValidation ] interface SVGAnimatedTransformList { readonly attribute SVGTransformList baseVal; diff --git a/Source/WebCore/svg/SVGAnimatedType.cpp b/Source/WebCore/svg/SVGAnimatedType.cpp index 1e1185e2b..963f228a0 100644 --- a/Source/WebCore/svg/SVGAnimatedType.cpp +++ b/Source/WebCore/svg/SVGAnimatedType.cpp @@ -18,10 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedType.h" +#include "CSSParser.h" #include "SVGParserUtilities.h" #include "SVGPathByteStream.h" @@ -92,7 +91,7 @@ SVGAnimatedType::~SVGAnimatedType() } } -std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createAngleAndEnumeration(std::unique_ptr<std::pair<SVGAngle, unsigned>> angleAndEnumeration) +std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createAngleAndEnumeration(std::unique_ptr<std::pair<SVGAngleValue, unsigned>> angleAndEnumeration) { ASSERT(angleAndEnumeration); auto animatedType = std::make_unique<SVGAnimatedType>(AnimatedAngle); @@ -140,7 +139,7 @@ std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createIntegerOptionalInteger(s return animatedType; } -std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createLength(std::unique_ptr<SVGLength> length) +std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createLength(std::unique_ptr<SVGLengthValue> length) { ASSERT(length); auto animatedType = std::make_unique<SVGAnimatedType>(AnimatedLength); @@ -148,7 +147,7 @@ std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createLength(std::unique_ptr<S return animatedType; } -std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createLengthList(std::unique_ptr<SVGLengthList> lengthList) +std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createLengthList(std::unique_ptr<SVGLengthListValues> lengthList) { ASSERT(lengthList); auto animatedType = std::make_unique<SVGAnimatedType>(AnimatedLengthList); @@ -164,7 +163,7 @@ std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createNumber(std::unique_ptr<f return animatedType; } -std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createNumberList(std::unique_ptr<SVGNumberList> numberList) +std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createNumberList(std::unique_ptr<SVGNumberListValues> numberList) { ASSERT(numberList); auto animatedType = std::make_unique<SVGAnimatedType>(AnimatedNumberList); @@ -188,7 +187,7 @@ std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createPath(std::unique_ptr<SVG return animatedType; } -std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createPointList(std::unique_ptr<SVGPointList> pointList) +std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createPointList(std::unique_ptr<SVGPointListValues> pointList) { ASSERT(pointList); auto animatedType = std::make_unique<SVGAnimatedType>(AnimatedPoints); @@ -196,7 +195,7 @@ std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createPointList(std::unique_pt return animatedType; } -std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createPreserveAspectRatio(std::unique_ptr<SVGPreserveAspectRatio> preserveAspectRatio) +std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createPreserveAspectRatio(std::unique_ptr<SVGPreserveAspectRatioValue> preserveAspectRatio) { ASSERT(preserveAspectRatio); auto animatedType = std::make_unique<SVGAnimatedType>(AnimatedPreserveAspectRatio); @@ -220,7 +219,7 @@ std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createString(std::unique_ptr<S return animatedType; } -std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createTransformList(std::unique_ptr<SVGTransformList> transformList) +std::unique_ptr<SVGAnimatedType> SVGAnimatedType::createTransformList(std::unique_ptr<SVGTransformListValues> transformList) { ASSERT(transformList); auto animatedType = std::make_unique<SVGAnimatedType>(AnimatedTransformList); @@ -277,30 +276,27 @@ bool SVGAnimatedType::setValueAsString(const QualifiedName& attrName, const Stri switch (m_type) { case AnimatedColor: ASSERT(m_data.color); - *m_data.color = value.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(value); - break; - case AnimatedLength: { + *m_data.color = CSSParser::parseColor(value.stripWhiteSpace()); + return true; + case AnimatedLength: ASSERT(m_data.length); - ExceptionCode ec = 0; - m_data.length->setValueAsString(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName), ec); - return !ec; - } + return !m_data.length->setValueAsString(value, SVGLengthValue::lengthModeForAnimatedLengthAttribute(attrName)).hasException(); case AnimatedLengthList: ASSERT(m_data.lengthList); - m_data.lengthList->parse(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName)); - break; + m_data.lengthList->parse(value, SVGLengthValue::lengthModeForAnimatedLengthAttribute(attrName)); + return true; case AnimatedNumber: ASSERT(m_data.number); parseNumberFromString(value, *m_data.number); - break; + return true; case AnimatedRect: ASSERT(m_data.rect); parseRect(value, *m_data.rect); - break; + return true; case AnimatedString: ASSERT(m_data.string); *m_data.string = value; - break; + return true; // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need setValueAsString() support. case AnimatedAngle: @@ -329,5 +325,3 @@ bool SVGAnimatedType::supportsAnimVal(AnimatedPropertyType type) } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGAnimatedType.h b/Source/WebCore/svg/SVGAnimatedType.h index f38dcf460..a0c11ad1e 100644 --- a/Source/WebCore/svg/SVGAnimatedType.h +++ b/Source/WebCore/svg/SVGAnimatedType.h @@ -17,20 +17,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedType_h -#define SVGAnimatedType_h +#pragma once -#if ENABLE(SVG) +#include "Color.h" #include "FloatRect.h" -#include "SVGAngle.h" -#include "SVGColor.h" -#include "SVGLength.h" -#include "SVGLengthList.h" -#include "SVGNumberList.h" -#include "SVGPointList.h" -#include "SVGPreserveAspectRatio.h" +#include "SVGAngleValue.h" +#include "SVGLengthListValues.h" +#include "SVGLengthValue.h" +#include "SVGNumberListValues.h" +#include "SVGPointListValues.h" +#include "SVGPreserveAspectRatioValue.h" #include "SVGPropertyInfo.h" -#include "SVGTransformList.h" +#include "SVGTransformListValues.h" namespace WebCore { @@ -42,29 +40,29 @@ public: SVGAnimatedType(AnimatedPropertyType); virtual ~SVGAnimatedType(); - static std::unique_ptr<SVGAnimatedType> createAngleAndEnumeration(std::unique_ptr<std::pair<SVGAngle, unsigned>>); + static std::unique_ptr<SVGAnimatedType> createAngleAndEnumeration(std::unique_ptr<std::pair<SVGAngleValue, unsigned>>); static std::unique_ptr<SVGAnimatedType> createBoolean(std::unique_ptr<bool>); static std::unique_ptr<SVGAnimatedType> createColor(std::unique_ptr<Color>); static std::unique_ptr<SVGAnimatedType> createEnumeration(std::unique_ptr<unsigned>); static std::unique_ptr<SVGAnimatedType> createInteger(std::unique_ptr<int>); static std::unique_ptr<SVGAnimatedType> createIntegerOptionalInteger(std::unique_ptr<std::pair<int, int>>); - static std::unique_ptr<SVGAnimatedType> createLength(std::unique_ptr<SVGLength>); - static std::unique_ptr<SVGAnimatedType> createLengthList(std::unique_ptr<SVGLengthList>); + static std::unique_ptr<SVGAnimatedType> createLength(std::unique_ptr<SVGLengthValue>); + static std::unique_ptr<SVGAnimatedType> createLengthList(std::unique_ptr<SVGLengthListValues>); static std::unique_ptr<SVGAnimatedType> createNumber(std::unique_ptr<float>); - static std::unique_ptr<SVGAnimatedType> createNumberList(std::unique_ptr<SVGNumberList>); + static std::unique_ptr<SVGAnimatedType> createNumberList(std::unique_ptr<SVGNumberListValues>); static std::unique_ptr<SVGAnimatedType> createNumberOptionalNumber(std::unique_ptr<std::pair<float, float>>); static std::unique_ptr<SVGAnimatedType> createPath(std::unique_ptr<SVGPathByteStream>); - static std::unique_ptr<SVGAnimatedType> createPointList(std::unique_ptr<SVGPointList>); - static std::unique_ptr<SVGAnimatedType> createPreserveAspectRatio(std::unique_ptr<SVGPreserveAspectRatio>); + static std::unique_ptr<SVGAnimatedType> createPointList(std::unique_ptr<SVGPointListValues>); + static std::unique_ptr<SVGAnimatedType> createPreserveAspectRatio(std::unique_ptr<SVGPreserveAspectRatioValue>); static std::unique_ptr<SVGAnimatedType> createRect(std::unique_ptr<FloatRect>); static std::unique_ptr<SVGAnimatedType> createString(std::unique_ptr<String>); - static std::unique_ptr<SVGAnimatedType> createTransformList(std::unique_ptr<SVGTransformList>); + static std::unique_ptr<SVGAnimatedType> createTransformList(std::unique_ptr<SVGTransformListValues>); static bool supportsAnimVal(AnimatedPropertyType); AnimatedPropertyType type() const { return m_type; } // Non-mutable accessors. - const std::pair<SVGAngle, unsigned>& angleAndEnumeration() const + const std::pair<SVGAngleValue, unsigned>& angleAndEnumeration() const { ASSERT(m_type == AnimatedAngle); return *m_data.angleAndEnumeration; @@ -100,13 +98,13 @@ public: return *m_data.integerOptionalInteger; } - const SVGLength& length() const + const SVGLengthValue& length() const { ASSERT(m_type == AnimatedLength); return *m_data.length; } - const SVGLengthList& lengthList() const + const SVGLengthListValues& lengthList() const { ASSERT(m_type == AnimatedLengthList); return *m_data.lengthList; @@ -118,7 +116,7 @@ public: return *m_data.number; } - const SVGNumberList& numberList() const + const SVGNumberListValues& numberList() const { ASSERT(m_type == AnimatedNumberList); return *m_data.numberList; @@ -136,13 +134,13 @@ public: return m_data.path; } - const SVGPointList& pointList() const + const SVGPointListValues& pointList() const { ASSERT(m_type == AnimatedPoints); return *m_data.pointList; } - const SVGPreserveAspectRatio& preserveAspectRatio() const + const SVGPreserveAspectRatioValue& preserveAspectRatio() const { ASSERT(m_type == AnimatedPreserveAspectRatio); return *m_data.preserveAspectRatio; @@ -160,14 +158,14 @@ public: return *m_data.string; } - const SVGTransformList& transformList() const + const SVGTransformListValues& transformList() const { ASSERT(m_type == AnimatedTransformList); return *m_data.transformList; } // Mutable accessors. - std::pair<SVGAngle, unsigned>& angleAndEnumeration() + std::pair<SVGAngleValue, unsigned>& angleAndEnumeration() { ASSERT(m_type == AnimatedAngle); return *m_data.angleAndEnumeration; @@ -203,13 +201,13 @@ public: return *m_data.integerOptionalInteger; } - SVGLength& length() + SVGLengthValue& length() { ASSERT(m_type == AnimatedLength); return *m_data.length; } - SVGLengthList& lengthList() + SVGLengthListValues& lengthList() { ASSERT(m_type == AnimatedLengthList); return *m_data.lengthList; @@ -221,7 +219,7 @@ public: return *m_data.number; } - SVGNumberList& numberList() + SVGNumberListValues& numberList() { ASSERT(m_type == AnimatedNumberList); return *m_data.numberList; @@ -239,13 +237,13 @@ public: return m_data.path; } - SVGPointList& pointList() + SVGPointListValues& pointList() { ASSERT(m_type == AnimatedPoints); return *m_data.pointList; } - SVGPreserveAspectRatio& preserveAspectRatio() + SVGPreserveAspectRatioValue& preserveAspectRatio() { ASSERT(m_type == AnimatedPreserveAspectRatio); return *m_data.preserveAspectRatio; @@ -263,7 +261,7 @@ public: return *m_data.string; } - SVGTransformList& transformList() + SVGTransformListValues& transformList() { ASSERT(m_type == AnimatedTransformList); return *m_data.transformList; @@ -277,31 +275,28 @@ private: union DataUnion { DataUnion() - : length(0) + : length(nullptr) { } - std::pair<SVGAngle, unsigned>* angleAndEnumeration; + std::pair<SVGAngleValue, unsigned>* angleAndEnumeration; bool* boolean; Color* color; unsigned* enumeration; int* integer; std::pair<int, int>* integerOptionalInteger; - SVGLength* length; - SVGLengthList* lengthList; + SVGLengthValue* length; + SVGLengthListValues* lengthList; float* number; - SVGNumberList* numberList; + SVGNumberListValues* numberList; std::pair<float, float>* numberOptionalNumber; SVGPathByteStream* path; - SVGPreserveAspectRatio* preserveAspectRatio; - SVGPointList* pointList; + SVGPreserveAspectRatioValue* preserveAspectRatio; + SVGPointListValues* pointList; FloatRect* rect; String* string; - SVGTransformList* transformList; + SVGTransformListValues* transformList; } m_data; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimatedType_h diff --git a/Source/WebCore/svg/SVGAnimatedTypeAnimator.cpp b/Source/WebCore/svg/SVGAnimatedTypeAnimator.cpp index 8519088f5..a2d59b6e9 100644 --- a/Source/WebCore/svg/SVGAnimatedTypeAnimator.cpp +++ b/Source/WebCore/svg/SVGAnimatedTypeAnimator.cpp @@ -20,8 +20,6 @@ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedTypeAnimator.h" #include "SVGAttributeToPropertyMap.h" @@ -29,15 +27,6 @@ namespace WebCore { -SVGElementAnimatedProperties::SVGElementAnimatedProperties() - : element(0) -{ } - -SVGElementAnimatedProperties::SVGElementAnimatedProperties(SVGElement* element, Vector<RefPtr<SVGAnimatedProperty>>& properties) - : element(element) - , properties(properties) -{ } - SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* contextElement) : m_type(type) , m_animationElement(animationElement) @@ -46,7 +35,8 @@ SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(AnimatedPropertyType type, SVGA } SVGAnimatedTypeAnimator::~SVGAnimatedTypeAnimator() -{ } +{ +} void SVGAnimatedTypeAnimator::calculateFromAndToValues(std::unique_ptr<SVGAnimatedType>& from, std::unique_ptr<SVGAnimatedType>& to, const String& fromString, const String& toString) { @@ -61,41 +51,27 @@ void SVGAnimatedTypeAnimator::calculateFromAndByValues(std::unique_ptr<SVGAnimat addAnimatedTypes(from.get(), to.get()); } -SVGElementAnimatedPropertyList SVGAnimatedTypeAnimator::findAnimatedPropertiesForAttributeName(SVGElement* targetElement, const QualifiedName& attributeName) +SVGElementAnimatedPropertyList SVGAnimatedTypeAnimator::findAnimatedPropertiesForAttributeName(SVGElement& targetElement, const QualifiedName& attributeName) { - ASSERT(targetElement); - - SVGElementAnimatedPropertyList propertiesByInstance; - - Vector<RefPtr<SVGAnimatedProperty>> targetProperties; - targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(targetElement, attributeName, targetProperties); + SVGElementAnimatedPropertyList result; if (!SVGAnimatedType::supportsAnimVal(m_type)) - return SVGElementAnimatedPropertyList(); + return result; - SVGElementAnimatedProperties propertiesPair(targetElement, targetProperties); - propertiesByInstance.append(propertiesPair); + auto& propertyMap = targetElement.localAttributeToPropertyMap(); + auto targetProperties = propertyMap.properties(targetElement, attributeName); - 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(); - if (!shadowTreeElement) - continue; + if (targetProperties.isEmpty()) + return result; - Vector<RefPtr<SVGAnimatedProperty>> instanceProperties; - targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(shadowTreeElement, attributeName, instanceProperties); + result.append(SVGElementAnimatedProperties { &targetElement, WTFMove(targetProperties) }); - SVGElementAnimatedProperties instancePropertiesPair(shadowTreeElement, instanceProperties); - propertiesByInstance.append(instancePropertiesPair); - } + for (SVGElement* instance : targetElement.instances()) + result.append(SVGElementAnimatedProperties { instance, propertyMap.properties(*instance, attributeName) }); #if !ASSERT_DISABLED - SVGElementAnimatedPropertyList::const_iterator propertiesEnd = propertiesByInstance.end(); - for (SVGElementAnimatedPropertyList::const_iterator it = propertiesByInstance.begin(); it != propertiesEnd; ++it) { - size_t propertiesSize = it->properties.size(); - for (size_t i = 0; i < propertiesSize; ++i) { - RefPtr<SVGAnimatedProperty> property = it->properties[i]; + for (auto& animatedProperties : result) { + for (auto& property : animatedProperties.properties) { if (property->animatedPropertyType() != m_type) { ASSERT(m_type == AnimatedAngle); ASSERT(property->animatedPropertyType() == AnimatedEnumeration); @@ -104,9 +80,12 @@ SVGElementAnimatedPropertyList SVGAnimatedTypeAnimator::findAnimatedPropertiesFo } #endif - return propertiesByInstance; + return result; } -} // namespace WebCore +void SVGAnimatedTypeAnimator::setInstanceUpdatesBlocked(SVGElement& element, bool blocked) +{ + element.setInstanceUpdatesBlocked(blocked); +} -#endif // ENABLE(SVG) +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGAnimatedTypeAnimator.h b/Source/WebCore/svg/SVGAnimatedTypeAnimator.h index ec534656c..cb7352632 100644 --- a/Source/WebCore/svg/SVGAnimatedTypeAnimator.h +++ b/Source/WebCore/svg/SVGAnimatedTypeAnimator.h @@ -18,22 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedTypeAnimator_h -#define SVGAnimatedTypeAnimator_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedProperty.h" #include "SVGAnimatedType.h" -#include "SVGElementInstance.h" #include <wtf/StdLibExtras.h> namespace WebCore { struct SVGElementAnimatedProperties { - SVGElementAnimatedProperties(); - - SVGElementAnimatedProperties(SVGElement*, Vector<RefPtr<SVGAnimatedProperty>>&); - SVGElement* element; Vector<RefPtr<SVGAnimatedProperty>> properties; }; @@ -49,7 +42,7 @@ public: virtual std::unique_ptr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0; virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0; - virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) = 0; + virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType&) = 0; virtual void animValWillChange(const SVGElementAnimatedPropertyList&) = 0; virtual void animValDidChange(const SVGElementAnimatedPropertyList&) = 0; virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) = 0; @@ -63,7 +56,7 @@ public: void setContextElement(SVGElement* contextElement) { m_contextElement = contextElement; } AnimatedPropertyType type() const { return m_type; } - SVGElementAnimatedPropertyList findAnimatedPropertiesForAttributeName(SVGElement*, const QualifiedName&); + SVGElementAnimatedPropertyList findAnimatedPropertiesForAttributeName(SVGElement&, const QualifiedName&); protected: SVGAnimatedTypeAnimator(AnimatedPropertyType, SVGAnimationElement*, SVGElement*); @@ -81,12 +74,11 @@ protected: } template<typename AnimValType> - void resetFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, typename AnimValType::ContentType& (SVGAnimatedType::*getter)()) + void resetFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type, typename AnimValType::ContentType& (SVGAnimatedType::*getter)()) { ASSERT(animatedTypes[0].properties.size() == 1); - ASSERT(type); - ASSERT(type->type() == m_type); - typename AnimValType::ContentType& animatedTypeValue = (type->*getter)(); + ASSERT(type.type() == m_type); + typename AnimValType::ContentType& animatedTypeValue = (type.*getter)(); animatedTypeValue = castAnimatedPropertyToActualType<AnimValType>(animatedTypes[0].properties[0].get())->currentBaseValue(); executeAction<AnimValType>(StartAnimationAction, animatedTypes, 0, &animatedTypeValue); @@ -128,13 +120,12 @@ protected: } template<typename AnimValType1, typename AnimValType2> - void resetFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, std::pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& (SVGAnimatedType::*getter)()) + void resetFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType& type, std::pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& (SVGAnimatedType::*getter)()) { ASSERT(animatedTypes[0].properties.size() == 2); - ASSERT(type); - ASSERT(type->type() == m_type); + ASSERT(type.type() == m_type); - std::pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& animatedTypeValue = (type->*getter)(); + std::pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& animatedTypeValue = (type.*getter)(); animatedTypeValue.first = castAnimatedPropertyToActualType<AnimValType1>(animatedTypes[0].properties[0].get())->currentBaseValue(); animatedTypeValue.second = castAnimatedPropertyToActualType<AnimValType2>(animatedTypes[0].properties[1].get())->currentBaseValue(); @@ -194,12 +185,12 @@ private: template<typename AnimValType> void executeAction(AnimationAction action, const SVGElementAnimatedPropertyList& animatedTypes, unsigned whichProperty, typename AnimValType::ContentType* type = 0) { - SVGElementInstance::InstanceUpdateBlocker blocker(animatedTypes[0].element); + // FIXME: Can't use SVGElement::InstanceUpdateBlocker because of circular header dependency. Would be nice to untangle this. + setInstanceUpdatesBlocked(*animatedTypes[0].element, true); - SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end(); - for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) { - ASSERT_WITH_SECURITY_IMPLICATION(whichProperty < it->properties.size()); - AnimValType* property = castAnimatedPropertyToActualType<AnimValType>(it->properties[whichProperty].get()); + for (auto& animatedType : animatedTypes) { + ASSERT_WITH_SECURITY_IMPLICATION(whichProperty < animatedType.properties.size()); + AnimValType* property = castAnimatedPropertyToActualType<AnimValType>(animatedType.properties[whichProperty].get()); switch (action) { case StartAnimationAction: @@ -209,7 +200,8 @@ private: break; case StopAnimationAction: ASSERT(!type); - property->animationEnded(); + if (property->isAnimating()) + property->animationEnded(); break; case AnimValWillChangeAction: ASSERT(!type); @@ -221,10 +213,11 @@ private: break; } } + + setInstanceUpdatesBlocked(*animatedTypes[0].element, false); } + + static void setInstanceUpdatesBlocked(SVGElement&, bool); }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimatedTypeAnimator_h diff --git a/Source/WebCore/svg/SVGAnimationElement.cpp b/Source/WebCore/svg/SVGAnimationElement.cpp index 6f228f785..b1457f403 100644 --- a/Source/WebCore/svg/SVGAnimationElement.cpp +++ b/Source/WebCore/svg/SVGAnimationElement.cpp @@ -5,6 +5,7 @@ * Copyright (C) 2008 Apple Inc. All rights reserved. * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -23,23 +24,23 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimationElement.h" -#include "Attribute.h" #include "CSSComputedStyleDeclaration.h" -#include "CSSParser.h" #include "CSSPropertyNames.h" +#include "CSSPropertyParser.h" #include "Document.h" #include "FloatConversion.h" #include "RenderObject.h" +#include "SVGAnimateColorElement.h" #include "SVGAnimateElement.h" #include "SVGElement.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGParserUtilities.h" +#include "SVGStringList.h" #include <wtf/MathExtras.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/text/StringView.h> namespace WebCore { @@ -53,13 +54,6 @@ END_REGISTER_ANIMATED_PROPERTIES SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document& document) : SVGSMILElement(tagName, document) - , m_fromPropertyValueType(RegularPropertyValue) - , m_toPropertyValueType(RegularPropertyValue) - , m_animationValid(false) - , m_attributeType(AttributeTypeAuto) - , m_hasInvalidCSSAttributeType(false) - , m_calcMode(CalcModeLinear) - , m_animationMode(NoAnimation) { registerAnimatedPropertiesForSVGAnimationElement(); } @@ -94,7 +88,9 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result) result.clear(); if (parse.isEmpty()) return; - const UChar* cur = parse.deprecatedCharacters(); + + auto upconvertedCharacters = StringView(parse).upconvertedCharacters(); + const UChar* cur = upconvertedCharacters; const UChar* end = cur + parse.length(); skipOptionalSVGSpaces(cur, end); @@ -142,37 +138,32 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result) bool SVGAnimationElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGTests::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::valuesAttr); - supportedAttributes.add(SVGNames::keyTimesAttr); - supportedAttributes.add(SVGNames::keyPointsAttr); - supportedAttributes.add(SVGNames::keySplinesAttr); - supportedAttributes.add(SVGNames::attributeTypeAttr); - supportedAttributes.add(SVGNames::calcModeAttr); - supportedAttributes.add(SVGNames::fromAttr); - supportedAttributes.add(SVGNames::toAttr); - supportedAttributes.add(SVGNames::byAttr); + supportedAttributes.get().add(SVGNames::valuesAttr); + supportedAttributes.get().add(SVGNames::keyTimesAttr); + supportedAttributes.get().add(SVGNames::keyPointsAttr); + supportedAttributes.get().add(SVGNames::keySplinesAttr); + supportedAttributes.get().add(SVGNames::attributeTypeAttr); + supportedAttributes.get().add(SVGNames::calcModeAttr); + supportedAttributes.get().add(SVGNames::fromAttr); + supportedAttributes.get().add(SVGNames::toAttr); + supportedAttributes.get().add(SVGNames::byAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGAnimationElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGSMILElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::valuesAttr) { // Per the SMIL specification, leading and trailing white space, // and white space before and after semicolon separators, is allowed and will be ignored. // http://www.w3.org/TR/SVG11/animate.html#ValuesAttribute value.string().split(';', m_values); - for (unsigned i = 0; i < m_values.size(); ++i) - m_values[i] = m_values[i].stripWhiteSpace(); + for (auto& value : m_values) + value = value.stripWhiteSpace(); updateAnimationMode(); return; @@ -212,12 +203,9 @@ void SVGAnimationElement::parseAttribute(const QualifiedName& name, const Atomic return; } - if (SVGTests::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGSMILElement::parseAttribute(name, value); + SVGTests::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGAnimationElement::svgAttributeChanged(const QualifiedName& attrName) @@ -247,7 +235,7 @@ float SVGAnimationElement::getCurrentTime() const return narrowPrecisionToFloat(elapsed().value()); } -float SVGAnimationElement::getSimpleDuration(ExceptionCode&) const +float SVGAnimationElement::getSimpleDuration() const { return narrowPrecisionToFloat(simpleDuration().value()); } @@ -293,66 +281,70 @@ void SVGAnimationElement::updateAnimationMode() void SVGAnimationElement::setCalcMode(const AtomicString& calcMode) { - DEFINE_STATIC_LOCAL(const AtomicString, discrete, ("discrete", AtomicString::ConstructFromLiteral)); - DEFINE_STATIC_LOCAL(const AtomicString, linear, ("linear", AtomicString::ConstructFromLiteral)); - DEFINE_STATIC_LOCAL(const AtomicString, paced, ("paced", AtomicString::ConstructFromLiteral)); - DEFINE_STATIC_LOCAL(const AtomicString, spline, ("spline", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> discrete("discrete", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> linear("linear", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> paced("paced", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> spline("spline", AtomicString::ConstructFromLiteral); if (calcMode == discrete) - setCalcMode(CalcModeDiscrete); + setCalcMode(CalcMode::Discrete); else if (calcMode == linear) - setCalcMode(CalcModeLinear); + setCalcMode(CalcMode::Linear); else if (calcMode == paced) - setCalcMode(CalcModePaced); + setCalcMode(CalcMode::Paced); else if (calcMode == spline) - setCalcMode(CalcModeSpline); + setCalcMode(CalcMode::Spline); else - setCalcMode(hasTagName(SVGNames::animateMotionTag) ? CalcModePaced : CalcModeLinear); + setCalcMode(hasTagName(SVGNames::animateMotionTag) ? CalcMode::Paced : CalcMode::Linear); } void SVGAnimationElement::setAttributeType(const AtomicString& attributeType) { - DEFINE_STATIC_LOCAL(const AtomicString, css, ("CSS", AtomicString::ConstructFromLiteral)); - DEFINE_STATIC_LOCAL(const AtomicString, xml, ("XML", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> css("CSS", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> xml("XML", AtomicString::ConstructFromLiteral); if (attributeType == css) - m_attributeType = AttributeTypeCSS; + m_attributeType = AttributeType::CSS; else if (attributeType == xml) - m_attributeType = AttributeTypeXML; + m_attributeType = AttributeType::XML; else - m_attributeType = AttributeTypeAuto; + m_attributeType = AttributeType::Auto; checkInvalidCSSAttributeType(targetElement()); } String SVGAnimationElement::toValue() const { - return fastGetAttribute(SVGNames::toAttr); + return attributeWithoutSynchronization(SVGNames::toAttr); } String SVGAnimationElement::byValue() const { - return fastGetAttribute(SVGNames::byAttr); + return attributeWithoutSynchronization(SVGNames::byAttr); } String SVGAnimationElement::fromValue() const { - return fastGetAttribute(SVGNames::fromAttr); + return attributeWithoutSynchronization(SVGNames::fromAttr); } bool SVGAnimationElement::isAdditive() const { - DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral)); - const AtomicString& value = fastGetAttribute(SVGNames::additiveAttr); + static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::additiveAttr); return value == sum || animationMode() == ByAnimation; } bool SVGAnimationElement::isAccumulated() const { - DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral)); - const AtomicString& value = fastGetAttribute(SVGNames::accumulateAttr); + static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::accumulateAttr); return value == sum && animationMode() != ToAnimation; } -bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement*, const QualifiedName& attributeName) +bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* element, const QualifiedName& attributeName) { + if (element->isTextContent() + && (attributeName == SVGNames::xAttr || attributeName == SVGNames::yAttr)) + return false; + return SVGElement::isAnimatableCSSProperty(attributeName); } @@ -362,11 +354,15 @@ SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimat return DontApplyAnimation; // Always animate CSS properties, using the ApplyCSSAnimation code path, regardless of the attributeType value. - if (isTargetAttributeCSSProperty(targetElement, attributeName)) + if (isTargetAttributeCSSProperty(targetElement, attributeName)) { + if (targetElement->isPresentationAttributeWithSVGDOM(attributeName)) + return ApplyXMLandCSSAnimation; return ApplyCSSAnimation; + } + // If attributeType="CSS" and attributeName doesn't point to a CSS property, ignore the animation. - if (attributeType() == AttributeTypeCSS) + if (attributeType() == AttributeType::CSS) return DontApplyAnimation; return ApplyXMLAnimation; @@ -374,7 +370,7 @@ SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimat void SVGAnimationElement::calculateKeyTimesForCalcModePaced() { - ASSERT(calcMode() == CalcModePaced); + ASSERT(calcMode() == CalcMode::Paced); ASSERT(animationMode() == ValuesAnimation); unsigned valuesCount = m_values.size(); @@ -426,7 +422,7 @@ unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned splineIndex) const { - ASSERT(calcMode() == CalcModeSpline); + ASSERT(calcMode() == CalcMode::Spline); ASSERT_WITH_SECURITY_IMPLICATION(splineIndex < m_keySplines.size()); UnitBezier bezier = m_keySplines[splineIndex]; SMILTime duration = simpleDuration(); @@ -438,7 +434,7 @@ float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned spl float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const { ASSERT(!m_keyPoints.isEmpty()); - ASSERT(calcMode() != CalcModePaced); + ASSERT(calcMode() != CalcMode::Paced); ASSERT(m_keyTimes.size() > 1); ASSERT(m_keyPoints.size() == m_keyTimes.size()); @@ -451,12 +447,12 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const float fromKeyPoint = m_keyPoints[index]; float toKeyPoint = m_keyPoints[index + 1]; - if (calcMode() == CalcModeDiscrete) + if (calcMode() == CalcMode::Discrete) return fromKeyPoint; float keyPointPercent = (percent - fromPercent) / (toPercent - fromPercent); - if (calcMode() == CalcModeSpline) { + if (calcMode() == CalcMode::Spline) { ASSERT(m_keySplines.size() == m_keyPoints.size() - 1); keyPointPercent = calculatePercentForSpline(keyPointPercent, index); } @@ -465,7 +461,7 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const float SVGAnimationElement::calculatePercentForFromTo(float percent) const { - if (calcMode() == CalcModeDiscrete && m_keyTimes.size() == 2) + if (calcMode() == CalcMode::Discrete && m_keyTimes.size() == 2) return percent > m_keyTimes[1] ? 1 : 0; return percent; @@ -475,7 +471,7 @@ void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effec { ASSERT(!m_keyPoints.isEmpty()); ASSERT(m_keyPoints.size() == m_keyTimes.size()); - ASSERT(calcMode() != CalcModePaced); + ASSERT(calcMode() != CalcMode::Paced); effectivePercent = calculatePercentFromKeyPoints(percent); unsigned index = effectivePercent == 1 ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1)); from = m_values[index]; @@ -496,16 +492,13 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& } CalcMode calcMode = this->calcMode(); - if (hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::animateColorTag)) { - AnimatedPropertyType attributeType = toSVGAnimateElement(this)->determineAnimatedPropertyType(targetElement()); - // Fall back to discrete animations for Strings. - if (attributeType == AnimatedBoolean - || attributeType == AnimatedEnumeration - || attributeType == AnimatedPreserveAspectRatio - || attributeType == AnimatedString) - calcMode = CalcModeDiscrete; + if (is<SVGAnimateElement>(*this) || is<SVGAnimateColorElement>(*this)) { + ASSERT(targetElement()); + AnimatedPropertyType type = downcast<SVGAnimateElementBase>(*this).determineAnimatedPropertyType(*targetElement()); + if (type == AnimatedBoolean || type == AnimatedEnumeration || type == AnimatedPreserveAspectRatio || type == AnimatedString) + calcMode = CalcMode::Discrete; } - if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) + if (!m_keyPoints.isEmpty() && calcMode != CalcMode::Paced) return currentValuesFromKeyPoints(percent, effectivePercent, from, to); unsigned keyTimesCount = m_keyTimes.size(); @@ -513,7 +506,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& ASSERT(!keyTimesCount || (keyTimesCount > 1 && !m_keyTimes[0])); unsigned index = calculateKeyTimesIndex(percent); - if (calcMode == CalcModeDiscrete) { + if (calcMode == CalcMode::Discrete) { if (!keyTimesCount) index = static_cast<unsigned>(percent * valuesCount); from = m_values[index]; @@ -540,7 +533,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& ASSERT_WITH_SECURITY_IMPLICATION(toPercent > fromPercent); effectivePercent = (percent - fromPercent) / (toPercent - fromPercent); - if (calcMode == CalcModeSpline) { + if (calcMode == CalcMode::Spline) { ASSERT(m_keySplines.size() == m_values.size() - 1); effectivePercent = calculatePercentForSpline(effectivePercent, index); } @@ -554,17 +547,17 @@ void SVGAnimationElement::startedActiveInterval() return; // These validations are appropriate for all animation modes. - if (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_keyTimes.size()) + if (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && m_keyPoints.size() != m_keyTimes.size()) return; AnimationMode animationMode = this->animationMode(); CalcMode calcMode = this->calcMode(); - if (calcMode == CalcModeSpline) { + if (calcMode == CalcMode::Spline) { unsigned splinesCount = m_keySplines.size(); if (!splinesCount - || (fastHasAttribute(SVGNames::keyPointsAttr) && m_keyPoints.size() - 1 != splinesCount) + || (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && m_keyPoints.size() - 1 != splinesCount) || (animationMode == ValuesAnimation && m_values.size() - 1 != splinesCount) - || (fastHasAttribute(SVGNames::keyTimesAttr) && m_keyTimes.size() - 1 != splinesCount)) + || (hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) && m_keyTimes.size() - 1 != splinesCount)) return; } @@ -573,6 +566,9 @@ void SVGAnimationElement::startedActiveInterval() String by = byValue(); if (animationMode == NoAnimation) return; + if ((animationMode == FromToAnimation || animationMode == FromByAnimation || animationMode == ToAnimation || animationMode == ByAnimation) + && (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) && (m_keyTimes.size() < 2 || m_keyTimes.size() != m_keyPoints.size()))) + return; if (animationMode == FromToAnimation) m_animationValid = calculateFromAndToValues(from, to); else if (animationMode == ToAnimation) { @@ -585,16 +581,16 @@ void SVGAnimationElement::startedActiveInterval() m_animationValid = calculateFromAndByValues(emptyString(), by); else if (animationMode == ValuesAnimation) { m_animationValid = m_values.size() >= 1 - && (calcMode == CalcModePaced || !fastHasAttribute(SVGNames::keyTimesAttr) || fastHasAttribute(SVGNames::keyPointsAttr) || (m_values.size() == m_keyTimes.size())) - && (calcMode == CalcModeDiscrete || !m_keyTimes.size() || m_keyTimes.last() == 1) - && (calcMode != CalcModeSpline || ((m_keySplines.size() && (m_keySplines.size() == m_values.size() - 1)) || m_keySplines.size() == m_keyPoints.size() - 1)) - && (!fastHasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size())); + && (calcMode == CalcMode::Paced || !hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) || hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_values.size() == m_keyTimes.size())) + && (calcMode == CalcMode::Discrete || !m_keyTimes.size() || m_keyTimes.last() == 1) + && (calcMode != CalcMode::Spline || ((m_keySplines.size() && (m_keySplines.size() == m_values.size() - 1)) || m_keySplines.size() == m_keyPoints.size() - 1)) + && (!hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size())); if (m_animationValid) m_animationValid = calculateToAtEndOfDurationValue(m_values.last()); - if (calcMode == CalcModePaced && m_animationValid) + if (calcMode == CalcMode::Paced && m_animationValid) calculateKeyTimesForCalcModePaced(); } else if (animationMode == PathAnimation) - m_animationValid = calcMode == CalcModePaced || !fastHasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size()); + m_animationValid = calcMode == CalcMode::Paced || !hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size()); } void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, SVGSMILElement* resultElement) @@ -616,9 +612,9 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S m_lastValuesAnimationFrom = from; m_lastValuesAnimationTo = to; } - } else if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) + } else if (!m_keyPoints.isEmpty() && calcMode != CalcMode::Paced) effectivePercent = calculatePercentFromKeyPoints(percent); - else if (m_keyPoints.isEmpty() && calcMode == CalcModeSpline && m_keyTimes.size() > 1) + else if (m_keyPoints.isEmpty() && calcMode == CalcMode::Spline && m_keyTimes.size() > 1) effectivePercent = calculatePercentForSpline(percent, calculateKeyTimesIndex(percent)); else if (animationMode == FromToAnimation || animationMode == ToAnimation) effectivePercent = calculatePercentForFromTo(percent); @@ -649,13 +645,13 @@ void SVGAnimationElement::adjustForInheritance(SVGElement* targetElement, const if (!parent || !parent->isSVGElement()) return; - SVGElement* svgParent = toSVGElement(parent); - computeCSSPropertyValue(svgParent, cssPropertyID(attributeName.localName()), value); + SVGElement& svgParent = downcast<SVGElement>(*parent); + computeCSSPropertyValue(&svgParent, cssPropertyID(attributeName.localName()), value); } static bool inheritsFromProperty(SVGElement*, const QualifiedName& attributeName, const String& value) { - DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> inherit("inherit", AtomicString::ConstructFromLiteral); if (value.isEmpty() || value != inherit) return false; @@ -673,6 +669,11 @@ void SVGAnimationElement::determinePropertyValueTypes(const String& from, const if (inheritsFromProperty(targetElement, attributeName, to)) m_toPropertyValueType = InheritValue; } +void SVGAnimationElement::resetAnimatedPropertyType() +{ + m_lastValuesAnimationFrom = String(); + m_lastValuesAnimationTo = String(); +} void SVGAnimationElement::setTargetElement(SVGElement* target) { @@ -680,17 +681,24 @@ void SVGAnimationElement::setTargetElement(SVGElement* target) checkInvalidCSSAttributeType(target); } -void SVGAnimationElement::setAttributeName(const QualifiedName& attributeName) +void SVGAnimationElement::checkInvalidCSSAttributeType(SVGElement* target) { - SVGSMILElement::setAttributeName(attributeName); - checkInvalidCSSAttributeType(targetElement()); + m_hasInvalidCSSAttributeType = target && hasValidAttributeName() && attributeType() == AttributeType::CSS && !isTargetAttributeCSSProperty(target, attributeName()); } -void SVGAnimationElement::checkInvalidCSSAttributeType(SVGElement* target) +Ref<SVGStringList> SVGAnimationElement::requiredFeatures() { - m_hasInvalidCSSAttributeType = target && hasValidAttributeName() && attributeType() == AttributeTypeCSS && !isTargetAttributeCSSProperty(target, attributeName()); + return SVGTests::requiredFeatures(*this); } +Ref<SVGStringList> SVGAnimationElement::requiredExtensions() +{ + return SVGTests::requiredExtensions(*this); } -#endif // ENABLE(SVG) +Ref<SVGStringList> SVGAnimationElement::systemLanguage() +{ + return SVGTests::systemLanguage(*this); +} + +} diff --git a/Source/WebCore/svg/SVGAnimationElement.h b/Source/WebCore/svg/SVGAnimationElement.h index bbe4872b8..b8e258524 100644 --- a/Source/WebCore/svg/SVGAnimationElement.h +++ b/Source/WebCore/svg/SVGAnimationElement.h @@ -22,10 +22,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimationElement_h -#define SVGAnimationElement_h +#pragma once -#if ENABLE(SVG) #include "SMILTime.h" #include "SVGAnimatedBoolean.h" #include "SVGExternalResourcesRequired.h" @@ -35,6 +33,10 @@ namespace WebCore { +class ConditionEventListener; +class SVGAnimatedType; +class TimeContainer; + enum AnimationMode { NoAnimation, FromToAnimation, @@ -47,31 +49,15 @@ enum AnimationMode { // If we have 'currentColor' or 'inherit' as animation value, we need to grab // the value during the animation since the value can be animated itself. -enum AnimatedPropertyValueType { - RegularPropertyValue, - CurrentColorValue, - InheritValue -}; +enum AnimatedPropertyValueType { RegularPropertyValue, CurrentColorValue, InheritValue }; -enum CalcMode { - CalcModeDiscrete, - CalcModeLinear, - CalcModePaced, - CalcModeSpline -}; +enum class CalcMode { Discrete, Linear, Paced, Spline }; -class ConditionEventListener; -class TimeContainer; -class SVGAnimatedType; - -class SVGAnimationElement : public SVGSMILElement, - public SVGTests, - public SVGExternalResourcesRequired { +class SVGAnimationElement : public SVGSMILElement, public SVGTests, public SVGExternalResourcesRequired { public: - // SVGAnimationElement float getStartTime() const; float getCurrentTime() const; - float getSimpleDuration(ExceptionCode&) const; + float getSimpleDuration() const; void beginElement(); void beginElementAt(float offset); @@ -80,7 +66,7 @@ public: static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&); - virtual bool isAdditive() const override; + bool isAdditive() const override; bool isAccumulated() const; AnimationMode animationMode() const { return m_animationMode; } CalcMode calcMode() const { return m_calcMode; } @@ -88,7 +74,8 @@ public: enum ShouldApplyAnimation { DontApplyAnimation, ApplyCSSAnimation, - ApplyXMLAnimation + ApplyXMLAnimation, + ApplyXMLandCSSAnimation // For presentation attributes with SVG DOM properties. }; ShouldApplyAnimation shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName); @@ -96,9 +83,7 @@ public: AnimatedPropertyValueType fromPropertyValueType() const { return m_fromPropertyValueType; } AnimatedPropertyValueType toPropertyValueType() const { return m_toPropertyValueType; } - template<typename AnimatedType> - void adjustForInheritance(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&), - AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement) + template<typename AnimatedType> void adjustForInheritance(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&), AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement) { if (valueType != InheritValue) return; @@ -109,8 +94,7 @@ public: animatedType = (*parseTypeFromString)(this, typeString); } - template<typename AnimatedType> - bool adjustFromToListValues(const AnimatedType& fromList, const AnimatedType& toList, AnimatedType& animatedList, float percentage, bool resizeAnimatedListIfNeeded = true) + template<typename AnimatedType> bool adjustFromToListValues(const AnimatedType& fromList, const AnimatedType& toList, AnimatedType& animatedList, float percentage, bool resizeAnimatedListIfNeeded = true) { // If no 'to' value is given, nothing to animate. unsigned toListSize = toList.size(); @@ -136,8 +120,7 @@ public: return true; } - template<typename AnimatedType> - void animateDiscreteType(float percentage, const AnimatedType& fromType, const AnimatedType& toType, AnimatedType& animatedType) + template<typename AnimatedType> void animateDiscreteType(float percentage, const AnimatedType& fromType, const AnimatedType& toType, AnimatedType& animatedType) { if ((animationMode() == FromToAnimation && percentage > 0.5) || animationMode() == ToAnimation || percentage == 1) { animatedType = AnimatedType(toType); @@ -149,7 +132,7 @@ public: void animateAdditiveNumber(float percentage, unsigned repeatCount, float fromNumber, float toNumber, float toAtEndOfDurationNumber, float& animatedNumber) { float number; - if (calcMode() == CalcModeDiscrete) + if (calcMode() == CalcMode::Discrete) number = percentage < 0.5 ? fromNumber : toNumber; else number = (toNumber - fromNumber) * percentage + fromNumber; @@ -163,21 +146,23 @@ public: animatedNumber = number; } + // SVGTests + Ref<SVGStringList> requiredFeatures(); + Ref<SVGStringList> requiredExtensions(); + Ref<SVGStringList> systemLanguage(); + protected: SVGAnimationElement(const QualifiedName&, Document&); void computeCSSPropertyValue(SVGElement*, CSSPropertyID, String& value); virtual void determinePropertyValueTypes(const String& from, const String& to); + virtual void resetAnimatedPropertyType(); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; - enum AttributeType { - AttributeTypeCSS, - AttributeTypeXML, - AttributeTypeAuto - }; + enum class AttributeType { CSS, XML, Auto }; AttributeType attributeType() const { return m_attributeType; } String toValue() const; @@ -187,26 +172,25 @@ protected: String targetAttributeBaseValue(); // from SVGSMILElement - virtual void startedActiveInterval() override; - virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) override; + void startedActiveInterval() override; + void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) override; - AnimatedPropertyValueType m_fromPropertyValueType; - AnimatedPropertyValueType m_toPropertyValueType; + AnimatedPropertyValueType m_fromPropertyValueType { RegularPropertyValue }; + AnimatedPropertyValueType m_toPropertyValueType { RegularPropertyValue }; - virtual void setTargetElement(SVGElement*) override; - virtual void setAttributeName(const QualifiedName&) override; + void setTargetElement(SVGElement*) override; + void setAttributeName(const QualifiedName&) override { } bool hasInvalidCSSAttributeType() const { return m_hasInvalidCSSAttributeType; } + void checkInvalidCSSAttributeType(SVGElement*); virtual void updateAnimationMode(); void setAnimationMode(AnimationMode animationMode) { m_animationMode = animationMode; } void setCalcMode(CalcMode calcMode) { m_calcMode = calcMode; } private: - virtual void animationAttributeChanged() override; + void animationAttributeChanged() override; void setAttributeType(const AtomicString&); - void checkInvalidCSSAttributeType(SVGElement*); - virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) = 0; virtual bool calculateFromAndToValues(const String& fromString, const String& toString) = 0; virtual bool calculateFromAndByValues(const String& fromString, const String& byString) = 0; @@ -225,31 +209,28 @@ private: void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String&); BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAnimationElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES // SVGTests - virtual void synchronizeRequiredFeatures() override { SVGTests::synchronizeRequiredFeatures(this); } - virtual void synchronizeRequiredExtensions() override { SVGTests::synchronizeRequiredExtensions(this); } - virtual void synchronizeSystemLanguage() override { SVGTests::synchronizeSystemLanguage(this); } + void synchronizeRequiredFeatures() final { SVGTests::synchronizeRequiredFeatures(*this); } + void synchronizeRequiredExtensions() final { SVGTests::synchronizeRequiredExtensions(*this); } + void synchronizeSystemLanguage() final { SVGTests::synchronizeSystemLanguage(*this); } void setCalcMode(const AtomicString&); - bool m_animationValid; + bool m_animationValid { false }; - AttributeType m_attributeType; + AttributeType m_attributeType { AttributeType::Auto }; Vector<String> m_values; Vector<float> m_keyTimes; Vector<float> m_keyPoints; Vector<UnitBezier> m_keySplines; String m_lastValuesAnimationFrom; String m_lastValuesAnimationTo; - bool m_hasInvalidCSSAttributeType; - CalcMode m_calcMode; - AnimationMode m_animationMode; + bool m_hasInvalidCSSAttributeType { false }; + CalcMode m_calcMode { CalcMode::Linear }; + AnimationMode m_animationMode { NoAnimation }; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimationElement_h diff --git a/Source/WebCore/svg/SVGAnimationElement.idl b/Source/WebCore/svg/SVGAnimationElement.idl index 664f44a0d..839ca68a8 100644 --- a/Source/WebCore/svg/SVGAnimationElement.idl +++ b/Source/WebCore/svg/SVGAnimationElement.idl @@ -24,19 +24,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGAnimationElement : SVGElement { +interface SVGAnimationElement : SVGElement { readonly attribute SVGElement targetElement; - float getStartTime(); - float getCurrentTime(); - [RaisesException] float getSimpleDuration(); + unrestricted float getStartTime(); + unrestricted float getCurrentTime(); + unrestricted float getSimpleDuration(); void beginElement(); - void beginElementAt([Default=Undefined] optional float offset); + void beginElementAt(optional unrestricted float offset = NaN); void endElement(); - void endElementAt([Default=Undefined] optional float offset); + void endElementAt(optional unrestricted float offset = NaN); }; SVGAnimationElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGAnimatorFactory.h b/Source/WebCore/svg/SVGAnimatorFactory.h index 1feced63c..71a1993b1 100644 --- a/Source/WebCore/svg/SVGAnimatorFactory.h +++ b/Source/WebCore/svg/SVGAnimatorFactory.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatorFactory_h -#define SVGAnimatorFactory_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedAngle.h" #include "SVGAnimatedBoolean.h" #include "SVGAnimatedColor.h" @@ -56,7 +54,7 @@ public: case AnimatedBoolean: return std::make_unique<SVGAnimatedBooleanAnimator>(animationElement, contextElement); case AnimatedColor: - return std::make_unique<SVGAnimatedColorAnimator>(animationElement, contextElement); + return std::make_unique<SVGAnimatedColorAnimator>(*animationElement, *contextElement); case AnimatedEnumeration: return std::make_unique<SVGAnimatedEnumerationAnimator>(animationElement, contextElement); case AnimatedInteger: @@ -98,6 +96,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGAnimatorFactory_h diff --git a/Source/WebCore/svg/SVGCircleElement.cpp b/Source/WebCore/svg/SVGCircleElement.cpp index 0dccf19db..db8364fdb 100644 --- a/Source/WebCore/svg/SVGCircleElement.cpp +++ b/Source/WebCore/svg/SVGCircleElement.cpp @@ -19,19 +19,14 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGCircleElement.h" -#include "Attribute.h" -#include "ExceptionCode.h" #include "FloatPoint.h" #include "RenderSVGEllipse.h" #include "RenderSVGPath.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGException.h" -#include "SVGLength.h" +#include "SVGLengthValue.h" #include "SVGNames.h" namespace WebCore { @@ -60,90 +55,51 @@ inline SVGCircleElement::SVGCircleElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGCircleElement(); } -PassRefPtr<SVGCircleElement> SVGCircleElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGCircleElement> SVGCircleElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGCircleElement(tagName, document)); -} - -bool SVGCircleElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::cxAttr); - supportedAttributes.add(SVGNames::cyAttr); - supportedAttributes.add(SVGNames::rAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGCircleElement(tagName, document)); } void SVGCircleElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::cxAttr) - setCxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::cxAttr) + setCxBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::cyAttr) - setCyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setCyBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::rAttr) - setRBaseValue(SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setRBaseValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths)); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGGraphicsElement::svgAttributeChanged(attrName); + SVGGraphicsElement::svgAttributeChanged(attrName); + + if (attrName == SVGNames::cxAttr || attrName == SVGNames::cyAttr || attrName == SVGNames::rAttr) { + InstanceInvalidationGuard guard(*this); + invalidateSVGPresentationAttributeStyle(); return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - bool isLengthAttribute = attrName == SVGNames::cxAttr - || attrName == SVGNames::cyAttr - || attrName == SVGNames::rAttr; - - if (isLengthAttribute) - updateRelativeLengthsInformation(); - - RenderSVGShape* renderer = toRenderSVGShape(this->renderer()); + auto* renderer = downcast<RenderSVGShape>(this->renderer()); if (!renderer) return; - if (isLengthAttribute) { - renderer->setNeedsShapeUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); - return; - } - if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { + InstanceInvalidationGuard guard(*this); RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); - return; } - - ASSERT_NOT_REACHED(); } -bool SVGCircleElement::selfHasRelativeLengths() const +RenderPtr<RenderElement> SVGCircleElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return cx().isRelative() - || cy().isRelative() - || r().isRelative(); + return createRenderer<RenderSVGEllipse>(*this, WTFMove(style)); } -RenderPtr<RenderElement> SVGCircleElement::createElementRenderer(PassRef<RenderStyle> style) -{ - return createRenderer<RenderSVGEllipse>(*this, std::move(style)); } - -} - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGCircleElement.h b/Source/WebCore/svg/SVGCircleElement.h index c1c662f8b..74004fb63 100644 --- a/Source/WebCore/svg/SVGCircleElement.h +++ b/Source/WebCore/svg/SVGCircleElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGCircleElement_h -#define SVGCircleElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGExternalResourcesRequired.h" @@ -32,33 +30,26 @@ namespace WebCore { class SVGCircleElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGCircleElement> create(const QualifiedName&, Document&); + static Ref<SVGCircleElement> create(const QualifiedName&, Document&); private: SVGCircleElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final { return true; } - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGCircleElement) DECLARE_ANIMATED_LENGTH(Cx, cx) DECLARE_ANIMATED_LENGTH(Cy, cy) DECLARE_ANIMATED_LENGTH(R, r) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGCircleElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGCircleElement_h diff --git a/Source/WebCore/svg/SVGCircleElement.idl b/Source/WebCore/svg/SVGCircleElement.idl index bd5938640..26e9ef6da 100644 --- a/Source/WebCore/svg/SVGCircleElement.idl +++ b/Source/WebCore/svg/SVGCircleElement.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGCircleElement : SVGGraphicsElement { +interface SVGCircleElement : SVGGraphicsElement { readonly attribute SVGAnimatedLength cx; readonly attribute SVGAnimatedLength cy; readonly attribute SVGAnimatedLength r; diff --git a/Source/WebCore/svg/SVGClipPathElement.cpp b/Source/WebCore/svg/SVGClipPathElement.cpp index 446dabeac..fa1876347 100644 --- a/Source/WebCore/svg/SVGClipPathElement.cpp +++ b/Source/WebCore/svg/SVGClipPathElement.cpp @@ -20,17 +20,13 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGClipPathElement.h" -#include "Attribute.h" #include "Document.h" #include "RenderSVGResourceClipper.h" -#include "SVGElementInstance.h" #include "SVGNames.h" -#include "SVGTransformList.h" #include "StyleResolver.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -52,42 +48,33 @@ inline SVGClipPathElement::SVGClipPathElement(const QualifiedName& tagName, Docu registerAnimatedPropertiesForSVGClipPathElement(); } -PassRefPtr<SVGClipPathElement> SVGClipPathElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGClipPathElement> SVGClipPathElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGClipPathElement(tagName, document)); + return adoptRef(*new SVGClipPathElement(tagName, document)); } bool SVGClipPathElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::clipPathUnitsAttr); + supportedAttributes.get().add(SVGNames::clipPathUnitsAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGClipPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGGraphicsElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::clipPathUnitsAttr) { - SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); + auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); if (propertyValue > 0) setClipPathUnitsBaseValue(propertyValue); return; } - if (SVGLangSpace::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName) @@ -97,7 +84,7 @@ void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (RenderObject* object = renderer()) object->setNeedsLayout(); @@ -114,11 +101,9 @@ void SVGClipPathElement::childrenChanged(const ChildChange& change) object->setNeedsLayout(); } -RenderPtr<RenderElement> SVGClipPathElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGClipPathElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceClipper>(*this, std::move(style)); + return createRenderer<RenderSVGResourceClipper>(*this, WTFMove(style)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGClipPathElement.h b/Source/WebCore/svg/SVGClipPathElement.h index d163097d4..8bb257b6c 100644 --- a/Source/WebCore/svg/SVGClipPathElement.h +++ b/Source/WebCore/svg/SVGClipPathElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGClipPathElement_h -#define SVGClipPathElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" #include "SVGExternalResourcesRequired.h" @@ -35,30 +33,26 @@ class RenderObject; class SVGClipPathElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGClipPathElement> create(const QualifiedName&, Document&); + static Ref<SVGClipPathElement> create(const QualifiedName&, Document&); private: SVGClipPathElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool needsPendingResourceHandling() const override { return false; } + bool isValid() const final { return SVGTests::isValid(); } + bool supportsFocus() const final { return false; } + bool needsPendingResourceHandling() const final { return false; } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void childrenChanged(const ChildChange&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; + void childrenChanged(const ChildChange&) final; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGClipPathElement) DECLARE_ANIMATED_ENUMERATION(ClipPathUnits, clipPathUnits, SVGUnitTypes::SVGUnitType) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGClipPathElement) - -} - -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGClipPathElement.idl b/Source/WebCore/svg/SVGClipPathElement.idl index 9c07f86db..96b5af116 100644 --- a/Source/WebCore/svg/SVGClipPathElement.idl +++ b/Source/WebCore/svg/SVGClipPathElement.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGClipPathElement : SVGGraphicsElement { +interface SVGClipPathElement : SVGGraphicsElement { readonly attribute SVGAnimatedEnumeration clipPathUnits; }; diff --git a/Source/WebCore/svg/SVGColor.cpp b/Source/WebCore/svg/SVGColor.cpp deleted file mode 100644 index 2cb386268..000000000 --- a/Source/WebCore/svg/SVGColor.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) Research In Motion Limited 2011. 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 "SVGColor.h" - -#include "CSSParser.h" -#include "RGBColor.h" -#include "SVGException.h" - -namespace WebCore { - -SVGColor::SVGColor(const SVGColorType& colorType) - : CSSValue(SVGColorClass) - , m_colorType(colorType) -{ -} - -SVGColor::SVGColor(ClassType classType, const SVGColorType& colorType) - : CSSValue(classType) - , m_colorType(colorType) -{ -} - -PassRefPtr<RGBColor> SVGColor::rgbColor() const -{ - return RGBColor::create(m_color.rgb()); -} - -Color SVGColor::colorFromRGBColorString(const String& colorString) -{ - // FIXME: Rework css parser so it is more SVG aware. - RGBA32 color; - if (CSSParser::parseColor(color, colorString.stripWhiteSpace())) - return color; - return Color(); -} - -void SVGColor::setRGBColor(const String&, ExceptionCode& ec) -{ - // The whole SVGColor interface is deprecated in SVG 1.1 (2nd edition). - // The setters are the most problematic part so we remove the support for those first. - ec = NO_MODIFICATION_ALLOWED_ERR; -} - -void SVGColor::setRGBColorICCColor(const String&, const String&, ExceptionCode& ec) -{ - ec = NO_MODIFICATION_ALLOWED_ERR; -} - -void SVGColor::setColor(unsigned short, const String&, const String&, ExceptionCode& ec) -{ - ec = NO_MODIFICATION_ALLOWED_ERR; -} - -String SVGColor::customCSSText() const -{ - switch (m_colorType) { - case SVG_COLORTYPE_UNKNOWN: - return String(); - case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR: - case SVG_COLORTYPE_RGBCOLOR: - // FIXME: No ICC color support. - return m_color.serialized(); - case SVG_COLORTYPE_CURRENTCOLOR: - if (m_color.isValid()) - return m_color.serialized(); - return "currentColor"; - } - - ASSERT_NOT_REACHED(); - return String(); -} - -SVGColor::SVGColor(ClassType classType, const SVGColor& cloneFrom) - : CSSValue(classType, /*isCSSOMSafe*/ true) - , m_color(cloneFrom.m_color) - , m_colorType(cloneFrom.m_colorType) -{ -} - -PassRefPtr<SVGColor> SVGColor::cloneForCSSOM() const -{ - return adoptRef(new SVGColor(SVGColorClass, *this)); -} - -bool SVGColor::equals(const SVGColor& other) const -{ - return m_colorType == other.m_colorType && m_color == other.m_color; -} - -} - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGColor.h b/Source/WebCore/svg/SVGColor.h deleted file mode 100644 index cdbec06f9..000000000 --- a/Source/WebCore/svg/SVGColor.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) Research In Motion Limited 2011. 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 SVGColor_h -#define SVGColor_h - -#if ENABLE(SVG) -#include "CSSValue.h" -#include "Color.h" -#include <wtf/PassRefPtr.h> - -namespace WebCore { - -class RGBColor; - -class SVGColor : public CSSValue { -public: - enum SVGColorType { - SVG_COLORTYPE_UNKNOWN = 0, - SVG_COLORTYPE_RGBCOLOR = 1, - SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2, - SVG_COLORTYPE_CURRENTCOLOR = 3 - }; - - static PassRef<SVGColor> createFromString(const String& rgbColor) - { - auto color = adoptRef(*new SVGColor(SVG_COLORTYPE_RGBCOLOR)); - color.get().setColor(colorFromRGBColorString(rgbColor)); - return color; - } - - static PassRef<SVGColor> createFromColor(const Color& rgbColor) - { - auto color = adoptRef(*new SVGColor(SVG_COLORTYPE_RGBCOLOR)); - color.get().setColor(rgbColor); - return color; - } - - static PassRef<SVGColor> createCurrentColor() - { - return adoptRef(*new SVGColor(SVG_COLORTYPE_CURRENTCOLOR)); - } - - const Color& color() const { return m_color; } - const SVGColorType& colorType() const { return m_colorType; } - PassRefPtr<RGBColor> rgbColor() const; - - static Color colorFromRGBColorString(const String&); - - void setRGBColor(const String& rgbColor, ExceptionCode&); - void setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionCode&); - void setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionCode&); - - String customCSSText() const; - - ~SVGColor() { } - - PassRefPtr<SVGColor> cloneForCSSOM() const; - - bool equals(const SVGColor&) const; - -protected: - friend class CSSComputedStyleDeclaration; - - SVGColor(ClassType, const SVGColorType&); - SVGColor(ClassType, const SVGColor& cloneFrom); - - void setColor(const Color& color) { m_color = color; } - void setColorType(const SVGColorType& type) { m_colorType = type; } - -private: - SVGColor(const SVGColorType&); - - Color m_color; - SVGColorType m_colorType; -}; - -CSS_VALUE_TYPE_CASTS(SVGColor, isSVGColor()); - -} // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGColor_h diff --git a/Source/WebCore/svg/SVGColor.idl b/Source/WebCore/svg/SVGColor.idl deleted file mode 100644 index cea7d16a6..000000000 --- a/Source/WebCore/svg/SVGColor.idl +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> - * Copyright (C) 2006 Apple Inc. 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. - */ - -[ - Conditional=SVG, - ImplementationLacksVTable, -] interface SVGColor : CSSValue { - const unsigned short SVG_COLORTYPE_UNKNOWN = 0; - const unsigned short SVG_COLORTYPE_RGBCOLOR = 1; - const unsigned short SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2; - const unsigned short SVG_COLORTYPE_CURRENTCOLOR = 3; - - readonly attribute unsigned short colorType; - readonly attribute RGBColor rgbColor; - // FIXME: readonly attribute SVGICCColor iccColor; - - [StrictTypeChecking, RaisesException] void setRGBColor(DOMString rgbColor); - - [StrictTypeChecking, RaisesException] void setRGBColorICCColor(DOMString rgbColor, DOMString iccColor); - - [StrictTypeChecking, RaisesException] void setColor(unsigned short colorType, DOMString rgbColor, DOMString iccColor); -}; - diff --git a/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp b/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp index 6fefcf596..ae2dc6521 100644 --- a/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp +++ b/Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp @@ -19,15 +19,12 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGComponentTransferFunctionElement.h" -#include "Attribute.h" -#include "SVGElementInstance.h" #include "SVGFEComponentTransferElement.h" #include "SVGNames.h" -#include "SVGNumberList.h" +#include "SVGNumberListValues.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -62,26 +59,21 @@ SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const Q bool SVGComponentTransferFunctionElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::typeAttr); - supportedAttributes.add(SVGNames::tableValuesAttr); - supportedAttributes.add(SVGNames::slopeAttr); - supportedAttributes.add(SVGNames::interceptAttr); - supportedAttributes.add(SVGNames::amplitudeAttr); - supportedAttributes.add(SVGNames::exponentAttr); - supportedAttributes.add(SVGNames::offsetAttr); + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { + supportedAttributes.get().add(SVGNames::typeAttr); + supportedAttributes.get().add(SVGNames::tableValuesAttr); + supportedAttributes.get().add(SVGNames::slopeAttr); + supportedAttributes.get().add(SVGNames::interceptAttr); + supportedAttributes.get().add(SVGNames::amplitudeAttr); + supportedAttributes.get().add(SVGNames::exponentAttr); + supportedAttributes.get().add(SVGNames::offsetAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGComponentTransferFunctionElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::typeAttr) { ComponentTransferType propertyValue = SVGPropertyTraits<ComponentTransferType>::fromString(value); if (propertyValue > 0) @@ -90,7 +82,7 @@ void SVGComponentTransferFunctionElement::parseAttribute(const QualifiedName& na } if (name == SVGNames::tableValuesAttr) { - SVGNumberList newList; + SVGNumberListValues newList; newList.parse(value); detachAnimatedTableValuesListWrappers(newList.size()); setTableValuesBaseValue(newList); @@ -122,7 +114,7 @@ void SVGComponentTransferFunctionElement::parseAttribute(const QualifiedName& na return; } - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); } void SVGComponentTransferFunctionElement::svgAttributeChanged(const QualifiedName& attrName) @@ -132,7 +124,7 @@ void SVGComponentTransferFunctionElement::svgAttributeChanged(const QualifiedNam return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); invalidateFilterPrimitiveParent(this); } @@ -151,5 +143,3 @@ ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction( } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGComponentTransferFunctionElement.h b/Source/WebCore/svg/SVGComponentTransferFunctionElement.h index d1910c737..5a2c0b7c6 100644 --- a/Source/WebCore/svg/SVGComponentTransferFunctionElement.h +++ b/Source/WebCore/svg/SVGComponentTransferFunctionElement.h @@ -18,14 +18,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGComponentTransferFunctionElement_h -#define SVGComponentTransferFunctionElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEComponentTransfer.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedNumber.h" #include "SVGAnimatedNumberList.h" +#include "SVGElement.h" namespace WebCore { @@ -39,15 +38,15 @@ struct SVGPropertyTraits<ComponentTransferType> { case FECOMPONENTTRANSFER_TYPE_UNKNOWN: return emptyString(); case FECOMPONENTTRANSFER_TYPE_IDENTITY: - return "identity"; + return ASCIILiteral("identity"); case FECOMPONENTTRANSFER_TYPE_TABLE: - return "table"; + return ASCIILiteral("table"); case FECOMPONENTTRANSFER_TYPE_DISCRETE: - return "discrete"; + return ASCIILiteral("discrete"); case FECOMPONENTTRANSFER_TYPE_LINEAR: - return "linear"; + return ASCIILiteral("linear"); case FECOMPONENTTRANSFER_TYPE_GAMMA: - return "gamma"; + return ASCIILiteral("gamma"); } ASSERT_NOT_REACHED(); @@ -77,13 +76,14 @@ public: protected: SVGComponentTransferFunctionElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) override { return false; } private: + static bool isSupportedAttribute(const QualifiedName&); + BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGComponentTransferFunctionElement) DECLARE_ANIMATED_ENUMERATION(Type, type, ComponentTransferType) DECLARE_ANIMATED_NUMBER_LIST(TableValues, tableValues) @@ -96,6 +96,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) -#endif diff --git a/Source/WebCore/svg/SVGComponentTransferFunctionElement.idl b/Source/WebCore/svg/SVGComponentTransferFunctionElement.idl index bc0ce067d..a5b045dba 100644 --- a/Source/WebCore/svg/SVGComponentTransferFunctionElement.idl +++ b/Source/WebCore/svg/SVGComponentTransferFunctionElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG&FILTERS, DoNotCheckConstants ] interface SVGComponentTransferFunctionElement : SVGElement { // Component Transfer Types diff --git a/Source/WebCore/svg/SVGCursorElement.cpp b/Source/WebCore/svg/SVGCursorElement.cpp index 1c62ef4c3..28938d75c 100644 --- a/Source/WebCore/svg/SVGCursorElement.cpp +++ b/Source/WebCore/svg/SVGCursorElement.cpp @@ -19,15 +19,14 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGCursorElement.h" -#include "Attr.h" +#include "CSSCursorImageValue.h" #include "Document.h" -#include "SVGElementInstance.h" #include "SVGNames.h" +#include "SVGStringList.h" #include "XLinkNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -54,65 +53,55 @@ inline SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGCursorElement(); } -PassRefPtr<SVGCursorElement> SVGCursorElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGCursorElement> SVGCursorElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGCursorElement(tagName, document)); + return adoptRef(*new SVGCursorElement(tagName, document)); } SVGCursorElement::~SVGCursorElement() { - HashSet<SVGElement*>::iterator end = m_clients.end(); - for (HashSet<SVGElement*>::iterator it = m_clients.begin(); it != end; ++it) - (*it)->cursorElementRemoved(); + for (auto& client : m_clients) + client->cursorElementRemoved(*this); } bool SVGCursorElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGTests::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); SVGURIReference::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); + supportedAttributes.get().add(SVGNames::xAttr); + supportedAttributes.get().add(SVGNames::yAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGCursorElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGElement::parseAttribute(name, value); - else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (SVGTests::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value) - || SVGURIReference::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); - + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); + reportAttributeParsingError(parseError, name, value); -} -void SVGCursorElement::addClient(SVGElement* element) -{ - m_clients.add(element); - element->setCursorElement(this); + SVGElement::parseAttribute(name, value); + SVGTests::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); } -void SVGCursorElement::removeClient(SVGElement* element) +void SVGCursorElement::addClient(CSSCursorImageValue& value) { - if (m_clients.remove(element)) - element->cursorElementRemoved(); + m_clients.add(&value); } -void SVGCursorElement::removeReferencedElement(SVGElement* element) +void SVGCursorElement::removeClient(CSSCursorImageValue& value) { - m_clients.remove(element); + m_clients.remove(&value); } void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName) @@ -122,14 +111,9 @@ void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - // Any change of a cursor specific attribute triggers this recalc. - HashSet<SVGElement*>::const_iterator it = m_clients.begin(); - HashSet<SVGElement*>::const_iterator end = m_clients.end(); - - for (; it != end; ++it) - (*it)->setNeedsStyleRecalc(); + InstanceInvalidationGuard guard(*this); + for (auto& client : m_clients) + client->cursorElementChanged(*this); } void SVGCursorElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const @@ -139,6 +123,19 @@ void SVGCursorElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const addSubresourceURL(urls, document().completeURL(href())); } +Ref<SVGStringList> SVGCursorElement::requiredFeatures() +{ + return SVGTests::requiredFeatures(*this); } -#endif // ENABLE(SVG) +Ref<SVGStringList> SVGCursorElement::requiredExtensions() +{ + return SVGTests::requiredExtensions(*this); +} + +Ref<SVGStringList> SVGCursorElement::systemLanguage() +{ + return SVGTests::systemLanguage(*this); +} + +} diff --git a/Source/WebCore/svg/SVGCursorElement.h b/Source/WebCore/svg/SVGCursorElement.h index 3cfe5794e..e93d44175 100644 --- a/Source/WebCore/svg/SVGCursorElement.h +++ b/Source/WebCore/svg/SVGCursorElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGCursorElement_h -#define SVGCursorElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGAnimatedString.h" @@ -32,50 +30,48 @@ namespace WebCore { -class SVGCursorElement final : public SVGElement, - public SVGTests, - public SVGExternalResourcesRequired, - public SVGURIReference { +class CSSCursorImageValue; + +class SVGCursorElement final : public SVGElement, public SVGTests, public SVGExternalResourcesRequired, public SVGURIReference { public: - static PassRefPtr<SVGCursorElement> create(const QualifiedName&, Document&); + static Ref<SVGCursorElement> create(const QualifiedName&, Document&); virtual ~SVGCursorElement(); - void addClient(SVGElement*); - void removeClient(SVGElement*); - void removeReferencedElement(SVGElement*); + void addClient(CSSCursorImageValue&); + void removeClient(CSSCursorImageValue&); + + // SVGTests + Ref<SVGStringList> requiredFeatures(); + Ref<SVGStringList> requiredExtensions(); + Ref<SVGStringList> systemLanguage(); private: SVGCursorElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } - virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override; + void addSubresourceAttributeURLs(ListHashSet<URL>&) const final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGCursorElement) DECLARE_ANIMATED_LENGTH(X, x) DECLARE_ANIMATED_LENGTH(Y, y) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES // SVGTests - virtual void synchronizeRequiredFeatures() override { SVGTests::synchronizeRequiredFeatures(this); } - virtual void synchronizeRequiredExtensions() override { SVGTests::synchronizeRequiredExtensions(this); } - virtual void synchronizeSystemLanguage() override { SVGTests::synchronizeSystemLanguage(this); } + void synchronizeRequiredFeatures() final { SVGTests::synchronizeRequiredFeatures(*this); } + void synchronizeRequiredExtensions() final { SVGTests::synchronizeRequiredExtensions(*this); } + void synchronizeSystemLanguage() final { SVGTests::synchronizeSystemLanguage(*this); } - HashSet<SVGElement*> m_clients; + HashSet<CSSCursorImageValue*> m_clients; }; -NODE_TYPE_CASTS(SVGCursorElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGCursorElement.idl b/Source/WebCore/svg/SVGCursorElement.idl index e531aa763..203f07934 100644 --- a/Source/WebCore/svg/SVGCursorElement.idl +++ b/Source/WebCore/svg/SVGCursorElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGCursorElement : SVGElement { +interface SVGCursorElement : SVGElement { readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; }; diff --git a/Source/WebCore/svg/SVGDefsElement.cpp b/Source/WebCore/svg/SVGDefsElement.cpp index 6ff2f6abb..f2fd3ed31 100644 --- a/Source/WebCore/svg/SVGDefsElement.cpp +++ b/Source/WebCore/svg/SVGDefsElement.cpp @@ -19,8 +19,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGDefsElement.h" #include "RenderSVGHiddenContainer.h" @@ -43,9 +41,9 @@ inline SVGDefsElement::SVGDefsElement(const QualifiedName& tagName, Document& do registerAnimatedPropertiesForSVGDefsElement(); } -PassRefPtr<SVGDefsElement> SVGDefsElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGDefsElement> SVGDefsElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGDefsElement(tagName, document)); + return adoptRef(*new SVGDefsElement(tagName, document)); } bool SVGDefsElement::isValid() const @@ -53,11 +51,9 @@ bool SVGDefsElement::isValid() const return SVGTests::isValid(); } -RenderPtr<RenderElement> SVGDefsElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGDefsElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGHiddenContainer>(*this, std::move(style)); + return createRenderer<RenderSVGHiddenContainer>(*this, WTFMove(style)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGDefsElement.h b/Source/WebCore/svg/SVGDefsElement.h index dc75b836a..ba0819cd6 100644 --- a/Source/WebCore/svg/SVGDefsElement.h +++ b/Source/WebCore/svg/SVGDefsElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGDefsElement_h -#define SVGDefsElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGExternalResourcesRequired.h" #include "SVGGraphicsElement.h" @@ -31,21 +29,19 @@ namespace WebCore { class SVGDefsElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGDefsElement> create(const QualifiedName&, Document&); + static Ref<SVGDefsElement> create(const QualifiedName&, Document&); private: SVGDefsElement(const QualifiedName&, Document&); - virtual bool isValid() const override; + bool isValid() const final; + bool supportsFocus() const final { return false; } - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGDefsElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGDefsElement.idl b/Source/WebCore/svg/SVGDefsElement.idl index 28dc07dac..5cd565ea4 100644 --- a/Source/WebCore/svg/SVGDefsElement.idl +++ b/Source/WebCore/svg/SVGDefsElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGDefsElement : SVGGraphicsElement { +interface SVGDefsElement : SVGGraphicsElement { }; SVGDefsElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGDescElement.cpp b/Source/WebCore/svg/SVGDescElement.cpp index edd2b79e5..a46c98cd8 100644 --- a/Source/WebCore/svg/SVGDescElement.cpp +++ b/Source/WebCore/svg/SVGDescElement.cpp @@ -19,8 +19,8 @@ */ #include "config.h" -#if ENABLE(SVG) #include "SVGDescElement.h" + #include "SVGNames.h" namespace WebCore { @@ -31,9 +31,9 @@ inline SVGDescElement::SVGDescElement(const QualifiedName& tagName, Document& do ASSERT(hasTagName(SVGNames::descTag)); } -PassRefPtr<SVGDescElement> SVGDescElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGDescElement> SVGDescElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGDescElement(tagName, document)); + return adoptRef(*new SVGDescElement(tagName, document)); } String SVGDescElement::description() const @@ -42,7 +42,3 @@ String SVGDescElement::description() const } } - -// vim:ts=4:noet -#endif // ENABLE(SVG) - diff --git a/Source/WebCore/svg/SVGDescElement.h b/Source/WebCore/svg/SVGDescElement.h index dc7cb0524..4607f696e 100644 --- a/Source/WebCore/svg/SVGDescElement.h +++ b/Source/WebCore/svg/SVGDescElement.h @@ -18,27 +18,22 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGDescElement_h -#define SVGDescElement_h +#pragma once -#if ENABLE(SVG) #include "SVGElement.h" namespace WebCore { class SVGDescElement final : public SVGElement { public: - static PassRefPtr<SVGDescElement> create(const QualifiedName&, Document&); + static Ref<SVGDescElement> create(const QualifiedName&, Document&); String description() const; private: SVGDescElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGDescElement.idl b/Source/WebCore/svg/SVGDescElement.idl index db7b7d816..11abd57a0 100644 --- a/Source/WebCore/svg/SVGDescElement.idl +++ b/Source/WebCore/svg/SVGDescElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGDescElement : SVGElement { +interface SVGDescElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGDocument.cpp b/Source/WebCore/svg/SVGDocument.cpp index d735da465..391e0494f 100644 --- a/Source/WebCore/svg/SVGDocument.cpp +++ b/Source/WebCore/svg/SVGDocument.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2015 Apple Inc. All right reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,93 +20,53 @@ */ #include "config.h" -#if ENABLE(SVG) #include "SVGDocument.h" -#include "EventNames.h" -#include "ExceptionCode.h" -#include "FrameView.h" -#include "RenderView.h" -#include "SVGElement.h" -#include "SVGNames.h" #include "SVGSVGElement.h" #include "SVGViewSpec.h" -#include "SVGZoomAndPan.h" -#include "SVGZoomEvent.h" namespace WebCore { SVGDocument::SVGDocument(Frame* frame, const URL& url) - : Document(frame, url, SVGDocumentClass) + : XMLDocument(frame, url, SVGDocumentClass) { } -SVGSVGElement* SVGDocument::rootElement() const +SVGSVGElement* SVGDocument::rootElement(const Document& document) { - Element* elem = documentElement(); - if (elem && elem->hasTagName(SVGNames::svgTag)) - return toSVGSVGElement(elem); - - return 0; -} - -void SVGDocument::dispatchZoomEvent(float prevScale, float newScale) -{ - RefPtr<SVGZoomEvent> event = static_pointer_cast<SVGZoomEvent>(createEvent("SVGZoomEvents", IGNORE_EXCEPTION)); - event->initEvent(eventNames().zoomEvent, true, false); - event->setPreviousScale(prevScale); - event->setNewScale(newScale); - rootElement()->dispatchEvent(event.release(), IGNORE_EXCEPTION); -} - -void SVGDocument::dispatchScrollEvent() -{ - RefPtr<Event> event = createEvent("SVGEvents", IGNORE_EXCEPTION); - event->initEvent(eventNames().scrollEvent, true, false); - rootElement()->dispatchEvent(event.release(), IGNORE_EXCEPTION); + auto* element = document.documentElement(); + if (!is<SVGSVGElement>(element)) + return nullptr; + return downcast<SVGSVGElement>(element); } bool SVGDocument::zoomAndPanEnabled() const { - if (rootElement()) { - if (rootElement()->useCurrentView()) { - if (rootElement()->currentView()) - return rootElement()->currentView()->zoomAndPan() == SVGZoomAndPanMagnify; - } else - return rootElement()->zoomAndPan() == SVGZoomAndPanMagnify; - } - - return false; + auto* element = rootElement(*this); + if (!element) + return false; + return (element->useCurrentView() ? element->currentView().zoomAndPan() : element->zoomAndPan()) == SVGZoomAndPanMagnify; } void SVGDocument::startPan(const FloatPoint& start) { - if (rootElement()) - m_translate = FloatPoint(start.x() - rootElement()->currentTranslate().x(), start.y() - rootElement()->currentTranslate().y()); -} - -void SVGDocument::updatePan(const FloatPoint& pos) const -{ - if (rootElement()) { - rootElement()->setCurrentTranslate(FloatPoint(pos.x() - m_translate.x(), pos.y() - m_translate.y())); - if (renderView()) - renderView()->repaint(); - } + auto* element = rootElement(*this); + if (!element) + return; + m_panningOffset = start - element->currentTranslateValue(); } -bool SVGDocument::childShouldCreateRenderer(const Node& child) const +void SVGDocument::updatePan(const FloatPoint& position) const { - if (isSVGSVGElement(child)) - return toSVGSVGElement(child).isValid(); - return true; + auto* element = rootElement(*this); + if (!element) + return; + element->setCurrentTranslate(position - m_panningOffset); } -PassRefPtr<Document> SVGDocument::cloneDocumentWithoutChildren() const +Ref<Document> SVGDocument::cloneDocumentWithoutChildren() const { return create(nullptr, url()); } } - -// vim:ts=4:noet -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGDocument.h b/Source/WebCore/svg/SVGDocument.h index 573dcec4f..233f11b74 100644 --- a/Source/WebCore/svg/SVGDocument.h +++ b/Source/WebCore/svg/SVGDocument.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2015 Apple Inc. 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 @@ -18,54 +19,40 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGDocument_h -#define SVGDocument_h -#if ENABLE(SVG) +#pragma once -#include "Document.h" -#include "FloatPoint.h" +#include "XMLDocument.h" namespace WebCore { -class DOMImplementation; -class SVGElement; class SVGSVGElement; -class SVGDocument final : public Document { +class SVGDocument final : public XMLDocument { public: - static PassRefPtr<SVGDocument> create(Frame* frame, const URL& url) - { - return adoptRef(new SVGDocument(frame, url)); - } + static Ref<SVGDocument> create(Frame*, const URL&); - SVGSVGElement* rootElement() const; - - void dispatchZoomEvent(float prevScale, float newScale); - void dispatchScrollEvent(); + static SVGSVGElement* rootElement(const Document&); bool zoomAndPanEnabled() const; - void startPan(const FloatPoint& start); - void updatePan(const FloatPoint& pos) const; + void updatePan(const FloatPoint& position) const; private: SVGDocument(Frame*, const URL&); - virtual bool childShouldCreateRenderer(const Node&) const override; - - virtual PassRefPtr<Document> cloneDocumentWithoutChildren() const override; + Ref<Document> cloneDocumentWithoutChildren() const override; - FloatPoint m_translate; + FloatSize m_panningOffset; }; -inline bool isSVGDocument(const Document& document) { return document.isSVGDocument(); } -void isSVGDocument(const SVGDocument&); // Catch unnecessary runtime check of type known at compile time. - -DOCUMENT_TYPE_CASTS(SVGDocument) +inline Ref<SVGDocument> SVGDocument::create(Frame* frame, const URL& url) +{ + return adoptRef(*new SVGDocument(frame, url)); +} } // namespace WebCore -#endif // ENABLE(SVG) -#endif // SVGDocument_h - -// vim:ts=4:noet +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGDocument) + static bool isType(const WebCore::Document& document) { return document.isSVGDocument(); } + static bool isType(const WebCore::Node& node) { return is<WebCore::Document>(node) && isType(downcast<WebCore::Document>(node)); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/SVGDocument.idl b/Source/WebCore/svg/SVGDocument.idl index 5e048d711..cdee3a5e7 100644 --- a/Source/WebCore/svg/SVGDocument.idl +++ b/Source/WebCore/svg/SVGDocument.idl @@ -19,12 +19,6 @@ * Boston, MA 02110-1301, USA. */ -[ - Conditional=SVG, -] interface SVGDocument : Document { - readonly attribute SVGSVGElement rootElement; - - // Overwrite the one in events::DocumentEvent - [RaisesException] Event createEvent([Default=Undefined] optional DOMString eventType); +partial interface Document { + readonly attribute SVGSVGElement? rootElement; }; - diff --git a/Source/WebCore/svg/SVGDocumentExtensions.cpp b/Source/WebCore/svg/SVGDocumentExtensions.cpp index 655b2a15c..cad83c9cf 100644 --- a/Source/WebCore/svg/SVGDocumentExtensions.cpp +++ b/Source/WebCore/svg/SVGDocumentExtensions.cpp @@ -20,23 +20,20 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGDocumentExtensions.h" -#include "Console.h" #include "DOMWindow.h" #include "Document.h" #include "EventListener.h" #include "Frame.h" #include "FrameLoader.h" -#include "Page.h" #include "SMILTimeContainer.h" #include "SVGElement.h" #include "SVGResourcesCache.h" #include "SVGSMILElement.h" #include "SVGSVGElement.h" #include "ScriptableDocumentParser.h" +#include "ShadowRoot.h" #include "XLinkNames.h" #include <wtf/text/AtomicString.h> @@ -97,23 +94,22 @@ void SVGDocumentExtensions::startAnimations() // In the future we should refactor the use-element to avoid this. See https://webkit.org/b/53704 Vector<RefPtr<SVGSVGElement>> timeContainers; timeContainers.appendRange(m_timeContainers.begin(), m_timeContainers.end()); - auto end = timeContainers.end(); - for (auto it = timeContainers.begin(); it != end; ++it) - (*it)->timeContainer()->begin(); + for (auto& element : timeContainers) + element->timeContainer().begin(); } void SVGDocumentExtensions::pauseAnimations() { - auto end = m_timeContainers.end(); - for (auto it = m_timeContainers.begin(); it != end; ++it) - (*it)->pauseAnimations(); + for (auto& container : m_timeContainers) + container->pauseAnimations(); + m_areAnimationsPaused = true; } void SVGDocumentExtensions::unpauseAnimations() { - auto end = m_timeContainers.end(); - for (auto it = m_timeContainers.begin(); it != end; ++it) - (*it)->unpauseAnimations(); + for (auto& container : m_timeContainers) + container->unpauseAnimations(); + m_areAnimationsPaused = false; } void SVGDocumentExtensions::dispatchSVGLoadEventToOutermostSVGElements() @@ -121,29 +117,27 @@ void SVGDocumentExtensions::dispatchSVGLoadEventToOutermostSVGElements() Vector<RefPtr<SVGSVGElement>> timeContainers; timeContainers.appendRange(m_timeContainers.begin(), m_timeContainers.end()); - auto end = timeContainers.end(); - for (auto it = timeContainers.begin(); it != end; ++it) { - SVGSVGElement* outerSVG = (*it).get(); - if (!outerSVG->isOutermostSVGSVGElement()) + for (auto& container : timeContainers) { + if (!container->isOutermostSVGSVGElement()) continue; - outerSVG->sendSVGLoadEventIfPossible(); + container->sendSVGLoadEventIfPossible(); } } static void reportMessage(Document* document, MessageLevel level, const String& message) { if (document->frame()) - document->addConsoleMessage(RenderingMessageSource, level, message); + document->addConsoleMessage(MessageSource::Rendering, level, message); } void SVGDocumentExtensions::reportWarning(const String& message) { - reportMessage(m_document, WarningMessageLevel, "Warning: " + message); + reportMessage(m_document, MessageLevel::Warning, "Warning: " + message); } void SVGDocumentExtensions::reportError(const String& message) { - reportMessage(m_document, ErrorMessageLevel, "Error: " + message); + reportMessage(m_document, MessageLevel::Error, "Error: " + message); } void SVGDocumentExtensions::addPendingResource(const AtomicString& id, Element* element) @@ -174,9 +168,7 @@ bool SVGDocumentExtensions::isElementWithPendingResources(Element* element) cons // This algorithm takes time proportional to the number of pending resources and need not. // If performance becomes an issue we can keep a counted set of elements and answer the question efficiently. ASSERT(element); - auto end = m_pendingResources.end(); - for (auto it = m_pendingResources.begin(); it != end; ++it) { - PendingElements* elements = it->value.get(); + for (auto& elements : m_pendingResources.values()) { ASSERT(elements); if (elements->contains(element)) @@ -208,43 +200,39 @@ void SVGDocumentExtensions::removeElementFromPendingResources(Element* element) // Remove the element from pending resources. if (!m_pendingResources.isEmpty() && element->hasPendingResources()) { Vector<AtomicString> toBeRemoved; - auto end = m_pendingResources.end(); - for (auto it = m_pendingResources.begin(); it != end; ++it) { - PendingElements* elements = it->value.get(); + for (auto& resource : m_pendingResources) { + PendingElements* elements = resource.value.get(); ASSERT(elements); ASSERT(!elements->isEmpty()); elements->remove(element); if (elements->isEmpty()) - toBeRemoved.append(it->key); + toBeRemoved.append(resource.key); } clearHasPendingResourcesIfPossible(element); // We use the removePendingResource function here because it deals with set lifetime correctly. - auto vectorEnd = toBeRemoved.end(); - for (auto it = toBeRemoved.begin(); it != vectorEnd; ++it) - removePendingResource(*it); + for (auto& resource : toBeRemoved) + removePendingResource(resource); } // Remove the element from pending resources that were scheduled for removal. if (!m_pendingResourcesForRemoval.isEmpty()) { Vector<AtomicString> toBeRemoved; - auto end = m_pendingResourcesForRemoval.end(); - for (auto it = m_pendingResourcesForRemoval.begin(); it != end; ++it) { - PendingElements* elements = it->value.get(); + for (auto& resource : m_pendingResourcesForRemoval) { + PendingElements* elements = resource.value.get(); ASSERT(elements); ASSERT(!elements->isEmpty()); elements->remove(element); if (elements->isEmpty()) - toBeRemoved.append(it->key); + toBeRemoved.append(resource.key); } // We use the removePendingResourceForRemoval function here because it deals with set lifetime correctly. - auto vectorEnd = toBeRemoved.end(); - for (auto it = toBeRemoved.begin(); it != vectorEnd; ++it) - removePendingResourceForRemoval(*it); + for (auto& resource : toBeRemoved) + removePendingResourceForRemoval(resource); } } @@ -269,7 +257,7 @@ void SVGDocumentExtensions::markPendingResourcesForRemoval(const AtomicString& i std::unique_ptr<PendingElements> existing = m_pendingResources.take(id); if (existing && !existing->isEmpty()) - m_pendingResourcesForRemoval.add(id, std::move(existing)); + m_pendingResourcesForRemoval.add(id, WTFMove(existing)); } Element* SVGDocumentExtensions::removeElementFromPendingResourcesForRemovalMap(const AtomicString& id) @@ -313,55 +301,66 @@ void SVGDocumentExtensions::addElementReferencingTarget(SVGElement* referencingE auto elements = std::make_unique<HashSet<SVGElement*>>(); elements->add(referencingElement); - m_elementDependencies.set(referencedElement, std::move(elements)); + m_elementDependencies.set(referencedElement, WTFMove(elements)); } void SVGDocumentExtensions::removeAllTargetReferencesForElement(SVGElement* referencingElement) { Vector<SVGElement*> toBeRemoved; - auto end = m_elementDependencies.end(); - for (auto it = m_elementDependencies.begin(); it != end; ++it) { - SVGElement* referencedElement = it->key; - HashSet<SVGElement*>& referencingElements = *it->value; + for (auto& dependency : m_elementDependencies) { + SVGElement* referencedElement = dependency.key; + HashSet<SVGElement*>& referencingElements = *dependency.value; referencingElements.remove(referencingElement); if (referencingElements.isEmpty()) toBeRemoved.append(referencedElement); } - auto vectorEnd = toBeRemoved.end(); - for (auto it = toBeRemoved.begin(); it != vectorEnd; ++it) - m_elementDependencies.remove(*it); + for (auto& element : toBeRemoved) + m_elementDependencies.remove(element); } -void SVGDocumentExtensions::rebuildAllElementReferencesForTarget(SVGElement* referencedElement) +void SVGDocumentExtensions::rebuildElements() { - ASSERT(referencedElement); - auto it = m_elementDependencies.find(referencedElement); + Vector<SVGElement*> shadowRebuildElements = WTFMove(m_rebuildElements); + for (auto* element : shadowRebuildElements) + element->svgAttributeChanged(XLinkNames::hrefAttr); +} + +void SVGDocumentExtensions::clearTargetDependencies(SVGElement& referencedElement) +{ + auto it = m_elementDependencies.find(&referencedElement); if (it == m_elementDependencies.end()) return; - ASSERT(it->key == referencedElement); - Vector<SVGElement*> toBeNotified; - + ASSERT(it->key == &referencedElement); HashSet<SVGElement*>* referencingElements = it->value.get(); - auto setEnd = referencingElements->end(); - for (auto setIt = referencingElements->begin(); setIt != setEnd; ++setIt) - toBeNotified.append(*setIt); - - // Force rebuilding the referencingElement so it knows about this change. - auto vectorEnd = toBeNotified.end(); - for (auto vectorIt = toBeNotified.begin(); vectorIt != vectorEnd; ++vectorIt) { - // Before rebuilding referencingElement ensure it was not removed from under us. - if (HashSet<SVGElement*>* referencingElements = setOfElementsReferencingTarget(referencedElement)) { - if (referencingElements->contains(*vectorIt)) - (*vectorIt)->svgAttributeChanged(XLinkNames::hrefAttr); - } + for (auto* element : *referencingElements) { + m_rebuildElements.append(element); + element->callClearTarget(); } } +void SVGDocumentExtensions::rebuildAllElementReferencesForTarget(SVGElement& referencedElement) +{ + auto it = m_elementDependencies.find(&referencedElement); + if (it == m_elementDependencies.end()) + return; + ASSERT(it->key == &referencedElement); + + HashSet<SVGElement*>* referencingElements = it->value.get(); + Vector<SVGElement*> elementsToRebuild; + elementsToRebuild.reserveInitialCapacity(referencingElements->size()); + for (auto* element : *referencingElements) + elementsToRebuild.uncheckedAppend(element); + + for (auto* element : elementsToRebuild) + element->svgAttributeChanged(XLinkNames::hrefAttr); +} + void SVGDocumentExtensions::removeAllElementReferencesForTarget(SVGElement* referencedElement) { m_elementDependencies.remove(referencedElement); + m_rebuildElements.removeFirst(referencedElement); } #if ENABLE(SVG_FONTS) @@ -378,5 +377,3 @@ void SVGDocumentExtensions::unregisterSVGFontFaceElement(SVGFontFaceElement* ele #endif } - -#endif diff --git a/Source/WebCore/svg/SVGDocumentExtensions.h b/Source/WebCore/svg/SVGDocumentExtensions.h index 460b14570..058f20da7 100644 --- a/Source/WebCore/svg/SVGDocumentExtensions.h +++ b/Source/WebCore/svg/SVGDocumentExtensions.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGDocumentExtensions_h -#define SVGDocumentExtensions_h +#pragma once -#if ENABLE(SVG) #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/HashSet.h> @@ -30,21 +28,19 @@ namespace WebCore { class Document; +class Element; class RenderSVGResourceContainer; class SVGElement; -#if ENABLE(SVG_FONTS) class SVGFontFaceElement; -#endif class SVGResourcesCache; class SVGSMILElement; class SVGSVGElement; -class Element; class SVGDocumentExtensions { WTF_MAKE_NONCOPYABLE(SVGDocumentExtensions); WTF_MAKE_FAST_ALLOCATED; public: typedef HashSet<Element*> PendingElements; - SVGDocumentExtensions(Document*); + explicit SVGDocumentExtensions(Document*); ~SVGDocumentExtensions(); void addTimeContainer(SVGSVGElement*); @@ -58,18 +54,22 @@ public: void pauseAnimations(); void unpauseAnimations(); void dispatchSVGLoadEventToOutermostSVGElements(); + bool areAnimationsPaused() const { return m_areAnimationsPaused; } void reportWarning(const String&); void reportError(const String&); - SVGResourcesCache* resourcesCache() const { return m_resourcesCache.get(); } + SVGResourcesCache& resourcesCache() { return *m_resourcesCache; } HashSet<SVGElement*>* setOfElementsReferencingTarget(SVGElement* referencedElement) const; void addElementReferencingTarget(SVGElement* referencingElement, SVGElement* referencedElement); void removeAllTargetReferencesForElement(SVGElement*); - void rebuildAllElementReferencesForTarget(SVGElement*); + void rebuildAllElementReferencesForTarget(SVGElement&); void removeAllElementReferencesForTarget(SVGElement*); + void clearTargetDependencies(SVGElement&); + void rebuildElements(); + #if ENABLE(SVG_FONTS) const HashSet<SVGFontFaceElement*>& svgFontFaceElements() const { return m_svgFontFaceElements; } void registerSVGFontFaceElement(SVGFontFaceElement*); @@ -88,6 +88,9 @@ private: HashMap<SVGElement*, std::unique_ptr<HashSet<SVGElement*>>> m_elementDependencies; std::unique_ptr<SVGResourcesCache> m_resourcesCache; + Vector<SVGElement*> m_rebuildElements; + bool m_areAnimationsPaused { false }; // For testing. + 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. @@ -108,7 +111,4 @@ private: std::unique_ptr<PendingElements> removePendingResourceForRemoval(const AtomicString&); }; -} - -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGElement.cpp b/Source/WebCore/svg/SVGElement.cpp index bdb7ea1fc..49195090c 100644 --- a/Source/WebCore/svg/SVGElement.cpp +++ b/Source/WebCore/svg/SVGElement.cpp @@ -1,10 +1,11 @@ /* * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2014 Apple Inc. All rights reserved. * Copyright (C) 2008 Alp Toker <alp@atoker.com> * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> * Copyright (C) 2013 Samsung Electronics. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -23,27 +24,22 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGElement.h" -#include "Attr.h" -#include "CSSCursorImageValue.h" -#include "CSSParser.h" -#include "DOMImplementation.h" +#include "CSSPropertyParser.h" +#include "DeprecatedCSSOMValue.h" #include "Document.h" #include "ElementIterator.h" #include "Event.h" #include "EventNames.h" +#include "HTMLElement.h" #include "HTMLNames.h" +#include "HTMLParserIdioms.h" #include "RenderObject.h" #include "RenderSVGResource.h" -#include "RenderSVGResourceClipper.h" #include "RenderSVGResourceFilter.h" #include "RenderSVGResourceMasker.h" -#include "SVGCursorElement.h" #include "SVGDocumentExtensions.h" -#include "SVGElementInstance.h" #include "SVGElementRareData.h" #include "SVGGraphicsElement.h" #include "SVGImageElement.h" @@ -72,11 +68,11 @@ BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGElement) REGISTER_LOCAL_ANIMATED_PROPERTY(className) END_REGISTER_ANIMATED_PROPERTIES -using namespace HTMLNames; -using namespace SVGNames; - static NEVER_INLINE void populateAttributeNameToCSSPropertyIDMap(HashMap<AtomicStringImpl*, CSSPropertyID>& map) { + using namespace HTMLNames; + using namespace SVGNames; + // This list should include all base CSS and SVG CSS properties which are exposed as SVG XML attributes. static const QualifiedName* const attributeNames[] = { &alignment_baselineAttr, @@ -91,6 +87,8 @@ static NEVER_INLINE void populateAttributeNameToCSSPropertyIDMap(HashMap<AtomicS &color_profileAttr, &color_renderingAttr, &cursorAttr, + &cxAttr, + &cyAttr, &SVGNames::directionAttr, &displayAttr, &dominant_baselineAttr, @@ -110,6 +108,7 @@ static NEVER_INLINE void populateAttributeNameToCSSPropertyIDMap(HashMap<AtomicS &glyph_orientation_horizontalAttr, &glyph_orientation_verticalAttr, &image_renderingAttr, + &SVGNames::heightAttr, &kerningAttr, &letter_spacingAttr, &lighting_colorAttr, @@ -120,7 +119,11 @@ static NEVER_INLINE void populateAttributeNameToCSSPropertyIDMap(HashMap<AtomicS &mask_typeAttr, &opacityAttr, &overflowAttr, + &paint_orderAttr, &pointer_eventsAttr, + &rAttr, + &rxAttr, + &ryAttr, &shape_renderingAttr, &stop_colorAttr, &stop_opacityAttr, @@ -138,22 +141,28 @@ static NEVER_INLINE void populateAttributeNameToCSSPropertyIDMap(HashMap<AtomicS &unicode_bidiAttr, &vector_effectAttr, &visibilityAttr, + &SVGNames::widthAttr, &word_spacingAttr, &writing_modeAttr, + &xAttr, + &yAttr, }; - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(attributeNames); ++i) { - const AtomicString& localName = attributeNames[i]->localName(); + for (auto& name : attributeNames) { + const AtomicString& localName = name->localName(); map.add(localName.impl(), cssPropertyID(localName)); } // FIXME: When CSS supports "transform-origin" this special case can be removed, // and we can add transform_originAttr to the table above instead. - map.add(transform_originAttr.localName().impl(), CSSPropertyWebkitTransformOrigin); + map.add(transform_originAttr.localName().impl(), CSSPropertyTransformOrigin); } static NEVER_INLINE void populateAttributeNameToAnimatedPropertyTypeMap(HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& map) { + using namespace HTMLNames; + using namespace SVGNames; + struct TableEntry { const QualifiedName& attributeName; AnimatedPropertyType type; @@ -197,6 +206,7 @@ static NEVER_INLINE void populateAttributeNameToAnimatedPropertyTypeMap(HashMap< { mask_typeAttr, AnimatedString }, { opacityAttr, AnimatedNumber }, { overflowAttr, AnimatedString }, + { paint_orderAttr, AnimatedString }, { pointer_eventsAttr, AnimatedString }, { shape_renderingAttr, AnimatedString }, { stop_colorAttr, AnimatedColor }, @@ -217,8 +227,8 @@ static NEVER_INLINE void populateAttributeNameToAnimatedPropertyTypeMap(HashMap< { word_spacingAttr, AnimatedLength }, }; - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(table); ++i) - map.add(table[i].attributeName.impl(), table[i].type); + for (auto& entry : table) + map.add(entry.attributeName.impl(), entry.type); } static inline HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& attributeNameToAnimatedPropertyTypeMap() @@ -229,6 +239,40 @@ static inline HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& return map; } +static NEVER_INLINE void populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap(HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& map) +{ + using namespace HTMLNames; + using namespace SVGNames; + + struct TableEntry { + const QualifiedName& attributeName; + AnimatedPropertyType type; + }; + + static const TableEntry table[] = { + { cxAttr, AnimatedLength }, + { cyAttr, AnimatedLength }, + { rAttr, AnimatedLength }, + { rxAttr, AnimatedLength }, + { ryAttr, AnimatedLength }, + { SVGNames::heightAttr, AnimatedLength }, + { SVGNames::widthAttr, AnimatedLength }, + { xAttr, AnimatedLength }, + { yAttr, AnimatedLength }, + }; + + for (auto& entry : table) + map.add(entry.attributeName.impl(), entry.type); +} + +static inline HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>& cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap() +{ + static NeverDestroyed<HashMap<QualifiedName::QualifiedNameImpl*, AnimatedPropertyType>> map; + if (map.get().isEmpty()) + populateCSSPropertyWithSVGDOMNameToAnimatedPropertyTypeMap(map); + return map; +} + SVGElement::SVGElement(const QualifiedName& tagName, Document& document) : StyledElement(tagName, document, CreateSVGElement) { @@ -238,27 +282,32 @@ SVGElement::SVGElement(const QualifiedName& tagName, Document& document) SVGElement::~SVGElement() { if (m_svgRareData) { - m_svgRareData->destroyAnimatedSMILStyleProperties(); - if (SVGCursorElement* cursorElement = m_svgRareData->cursorElement()) - cursorElement->removeClient(this); - if (CSSCursorImageValue* cursorImageValue = m_svgRareData->cursorImageValue()) - cursorImageValue->removeReferencedElement(this); + for (SVGElement* instance : m_svgRareData->instances()) + instance->m_svgRareData->setCorrespondingElement(nullptr); + if (SVGElement* correspondingElement = m_svgRareData->correspondingElement()) + correspondingElement->m_svgRareData->instances().remove(this); m_svgRareData = nullptr; } - document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this); - document().accessSVGExtensions()->removeAllElementReferencesForTarget(this); + document().accessSVGExtensions().rebuildAllElementReferencesForTarget(*this); + document().accessSVGExtensions().removeAllElementReferencesForTarget(this); } -bool SVGElement::willRecalcStyle(Style::Change change) +int SVGElement::tabIndex() const { - if (!m_svgRareData || styleChangeType() == SyntheticStyleChange) - return true; + if (supportsFocus()) + return Element::tabIndex(); + return -1; +} + +void SVGElement::willRecalcStyle(Style::Change change) +{ + if (!m_svgRareData || styleResolutionShouldRecompositeLayer()) + return; // If the style changes because of a regular property change (not induced by SMIL animations themselves) // reset the "computed style without SMIL style properties", so the base value change gets reflected. if (change > Style::NoChange || needsStyleRecalc()) m_svgRareData->setNeedsOverrideComputedStyleUpdate(); - return true; } SVGElementRareData& SVGElement::ensureSVGRareData() @@ -270,7 +319,7 @@ SVGElementRareData& SVGElement::ensureSVGRareData() bool SVGElement::isOutermostSVGSVGElement() const { - if (!isSVGSVGElement(this)) + if (!is<SVGSVGElement>(*this)) return false; // If we're living in a shadow tree, we're a <svg> element that got created as replacement @@ -297,233 +346,161 @@ void SVGElement::reportAttributeParsingError(SVGParsingError error, const Qualif return; String errorString = "<" + tagName() + "> attribute " + name.toString() + "=\"" + value + "\""; - SVGDocumentExtensions* extensions = document().accessSVGExtensions(); + SVGDocumentExtensions& extensions = document().accessSVGExtensions(); if (error == NegativeValueForbiddenError) { - extensions->reportError("Invalid negative value for " + errorString); + extensions.reportError("Invalid negative value for " + errorString); return; } if (error == ParsingAttributeFailedError) { - extensions->reportError("Invalid value for " + errorString); + extensions.reportError("Invalid value for " + errorString); return; } ASSERT_NOT_REACHED(); } - -bool SVGElement::isSupported(StringImpl* feature, StringImpl* version) const -{ - return DOMImplementation::hasFeature(feature, version); -} - -String SVGElement::xmlbase() const -{ - return fastGetAttribute(XMLNames::baseAttr); -} - -void SVGElement::setXmlbase(const String& value, ExceptionCode&) -{ - setAttribute(XMLNames::baseAttr, value); -} - void SVGElement::removedFrom(ContainerNode& rootParent) { - bool wasInDocument = rootParent.inDocument(); + bool wasInDocument = rootParent.isConnected(); if (wasInDocument) updateRelativeLengthsInformation(false, this); StyledElement::removedFrom(rootParent); if (wasInDocument) { - document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this); - document().accessSVGExtensions()->removeAllElementReferencesForTarget(this); + document().accessSVGExtensions().clearTargetDependencies(*this); + document().accessSVGExtensions().removeAllElementReferencesForTarget(this); } - SVGElementInstance::invalidateAllInstancesOfElement(this); + invalidateInstances(); } SVGSVGElement* SVGElement::ownerSVGElement() const { - ContainerNode* n = parentOrShadowHostNode(); - while (n) { - if (n->hasTagName(SVGNames::svgTag)) - return toSVGSVGElement(n); + ContainerNode* node = parentOrShadowHostNode(); + while (node) { + if (is<SVGSVGElement>(*node)) + return downcast<SVGSVGElement>(node); - n = n->parentOrShadowHostNode(); + node = node->parentOrShadowHostNode(); } - return 0; + return nullptr; } SVGElement* SVGElement::viewportElement() const { // This function needs shadow tree support - as RenderSVGContainer uses this function // to determine the "overflow" property. <use> on <symbol> wouldn't work otherwhise. - ContainerNode* n = parentOrShadowHostNode(); - while (n) { - if (n->hasTagName(SVGNames::svgTag) || isSVGImageElement(n) || n->hasTagName(SVGNames::symbolTag)) - return toSVGElement(n); + ContainerNode* node = parentOrShadowHostNode(); + while (node) { + if (is<SVGSVGElement>(*node) || is<SVGImageElement>(*node) || node->hasTagName(SVGNames::symbolTag)) + return downcast<SVGElement>(node); - n = n->parentOrShadowHostNode(); + node = node->parentOrShadowHostNode(); } - return 0; -} - -SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions() -{ - // This function is provided for use by SVGAnimatedProperty to avoid - // global inclusion of Document.h in SVG code. - return document().accessSVGExtensions(); -} - -void SVGElement::mapInstanceToElement(SVGElementInstance* instance) -{ - ASSERT(instance); - - HashSet<SVGElementInstance*>& instances = ensureSVGRareData().elementInstances(); - ASSERT(!instances.contains(instance)); - - instances.add(instance); + return nullptr; } -void SVGElement::removeInstanceMapping(SVGElementInstance* instance) -{ - ASSERT(instance); - ASSERT(m_svgRareData); - - HashSet<SVGElementInstance*>& instances = m_svgRareData->elementInstances(); - ASSERT(instances.contains(instance)); - - instances.remove(instance); -} - -const HashSet<SVGElementInstance*>& SVGElement::instancesForElement() const +const HashSet<SVGElement*>& SVGElement::instances() const { if (!m_svgRareData) { - DEFINE_STATIC_LOCAL(HashSet<SVGElementInstance*>, emptyInstances, ()); + static NeverDestroyed<HashSet<SVGElement*>> emptyInstances; return emptyInstances; } - return m_svgRareData->elementInstances(); + return m_svgRareData->instances(); } bool SVGElement::getBoundingBox(FloatRect& rect, SVGLocatable::StyleUpdateStrategy styleUpdateStrategy) { - if (isSVGGraphicsElement()) { - rect = toSVGGraphicsElement(this)->getBBox(styleUpdateStrategy); + if (is<SVGGraphicsElement>(*this)) { + rect = downcast<SVGGraphicsElement>(*this).getBBox(styleUpdateStrategy); return true; } return false; } -void SVGElement::setCursorElement(SVGCursorElement* cursorElement) +SVGElement* SVGElement::correspondingElement() const { - SVGElementRareData& rareData = ensureSVGRareData(); - if (SVGCursorElement* oldCursorElement = rareData.cursorElement()) { - if (cursorElement == oldCursorElement) - return; - oldCursorElement->removeReferencedElement(this); - } - rareData.setCursorElement(cursorElement); + return m_svgRareData ? m_svgRareData->correspondingElement() : nullptr; } -void SVGElement::cursorElementRemoved() +SVGUseElement* SVGElement::correspondingUseElement() const { - ASSERT(m_svgRareData); - m_svgRareData->setCursorElement(0); + auto* root = containingShadowRoot(); + if (!root) + return nullptr; + if (root->mode() != ShadowRootMode::UserAgent) + return nullptr; + auto* host = root->host(); + if (!is<SVGUseElement>(host)) + return nullptr; + return &downcast<SVGUseElement>(*host); } -void SVGElement::setCursorImageValue(CSSCursorImageValue* cursorImageValue) +void SVGElement::setCorrespondingElement(SVGElement* correspondingElement) { - SVGElementRareData& rareData = ensureSVGRareData(); - if (CSSCursorImageValue* oldCursorImageValue = rareData.cursorImageValue()) { - if (cursorImageValue == oldCursorImageValue) - return; - oldCursorImageValue->removeReferencedElement(this); + if (m_svgRareData) { + if (SVGElement* oldCorrespondingElement = m_svgRareData->correspondingElement()) + oldCorrespondingElement->m_svgRareData->instances().remove(this); } - rareData.setCursorImageValue(cursorImageValue); + if (m_svgRareData || correspondingElement) + ensureSVGRareData().setCorrespondingElement(correspondingElement); + if (correspondingElement) + correspondingElement->ensureSVGRareData().instances().add(this); } -void SVGElement::cursorImageValueRemoved() +void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - ASSERT(m_svgRareData); - m_svgRareData->setCursorImageValue(0); -} + if (name == HTMLNames::classAttr) { + setClassNameBaseValue(value); + return; + } -SVGElement* SVGElement::correspondingElement() -{ - ASSERT(!m_svgRareData || !m_svgRareData->correspondingElement() || containingShadowRoot()); - return m_svgRareData ? m_svgRareData->correspondingElement() : 0; -} + if (name == HTMLNames::tabindexAttr) { + if (value.isEmpty()) + clearTabIndexExplicitlyIfNeeded(); + else if (std::optional<int> tabIndex = parseHTMLInteger(value)) + setTabIndexExplicitly(tabIndex.value()); + return; + } -void SVGElement::setCorrespondingElement(SVGElement* correspondingElement) -{ - ensureSVGRareData().setCorrespondingElement(correspondingElement); -} + auto& eventName = HTMLElement::eventNameForEventHandlerAttribute(name); + if (!eventName.isNull()) { + setAttributeEventListener(eventName, name, value); + return; + } -void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value) -{ - // standard events - if (name == onloadAttr) - setAttributeEventListener(eventNames().loadEvent, name, value); - else if (name == onclickAttr) - setAttributeEventListener(eventNames().clickEvent, name, value); - else if (name == onmousedownAttr) - setAttributeEventListener(eventNames().mousedownEvent, name, value); - else if (name == onmouseenterAttr) - setAttributeEventListener(eventNames().mouseenterEvent, name, value); - else if (name == onmouseleaveAttr) - setAttributeEventListener(eventNames().mouseleaveEvent, name, value); - else if (name == onmousemoveAttr) - setAttributeEventListener(eventNames().mousemoveEvent, name, value); - else if (name == onmouseoutAttr) - setAttributeEventListener(eventNames().mouseoutEvent, name, value); - else if (name == onmouseoverAttr) - setAttributeEventListener(eventNames().mouseoverEvent, name, value); - else if (name == onmouseupAttr) - setAttributeEventListener(eventNames().mouseupEvent, name, value); - else if (name == SVGNames::onfocusinAttr) - setAttributeEventListener(eventNames().focusinEvent, name, value); - else if (name == SVGNames::onfocusoutAttr) - setAttributeEventListener(eventNames().focusoutEvent, name, value); - else if (name == SVGNames::onactivateAttr) - setAttributeEventListener(eventNames().DOMActivateEvent, name, value); - else if (name == HTMLNames::classAttr) - setClassNameBaseValue(value); -#if ENABLE(TOUCH_EVENTS) - else if (name == ontouchstartAttr) - setAttributeEventListener(eventNames().touchstartEvent, name, value); - else if (name == ontouchmoveAttr) - setAttributeEventListener(eventNames().touchmoveEvent, name, value); - else if (name == ontouchendAttr) - setAttributeEventListener(eventNames().touchendEvent, name, value); - else if (name == ontouchcancelAttr) - setAttributeEventListener(eventNames().touchcancelEvent, name, value); -#endif -#if ENABLE(IOS_GESTURE_EVENTS) - else if (name == ongesturestartAttr) - setAttributeEventListener(eventNames().gesturestartEvent, name, value); - else if (name == ongesturechangeAttr) - setAttributeEventListener(eventNames().gesturechangeEvent, name, value); - else if (name == ongestureendAttr) - setAttributeEventListener(eventNames().gestureendEvent, name, value); -#endif - else if (SVGLangSpace::parseAttribute(name, value)) { - } else - StyledElement::parseAttribute(name, value); + SVGLangSpace::parseAttribute(name, value); } -void SVGElement::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes) +Vector<AnimatedPropertyType> SVGElement::animatedPropertyTypesForAttribute(const QualifiedName& attributeName) { - localAttributeToPropertyMap().animatedPropertyTypeForAttribute(attributeName, propertyTypes); - if (!propertyTypes.isEmpty()) - return; + auto types = localAttributeToPropertyMap().types(attributeName); + if (!types.isEmpty()) + return types; + + { + auto& map = attributeNameToAnimatedPropertyTypeMap(); + auto it = map.find(attributeName.impl()); + if (it != map.end()) { + types.append(it->value); + return types; + } + } + + { + auto& map = cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap(); + auto it = map.find(attributeName.impl()); + if (it != map.end()) { + types.append(it->value); + return types; + } + } - auto& map = attributeNameToAnimatedPropertyTypeMap(); - auto it = map.find(attributeName.impl()); - if (it != map.end()) - propertyTypes.append(it->value); + return types; } bool SVGElement::haveLoadedRequiredResources() @@ -535,82 +512,61 @@ bool SVGElement::haveLoadedRequiredResources() return true; } -static inline void collectInstancesForSVGElement(SVGElement* element, HashSet<SVGElementInstance*>& instances) -{ - ASSERT(element); - if (element->containingShadowRoot()) - return; - - ASSERT(!element->instanceUpdatesBlocked()); - - instances = element->instancesForElement(); -} - -bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> prpListener, bool useCapture) -{ - RefPtr<EventListener> listener = prpListener; - +bool SVGElement::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options) +{ // Add event listener to regular DOM element - if (!Node::addEventListener(eventType, listener, useCapture)) + if (!Node::addEventListener(eventType, listener.copyRef(), options)) return false; + if (containingShadowRoot()) + return true; + // Add event listener to all shadow tree DOM element instances - HashSet<SVGElementInstance*> instances; - collectInstancesForSVGElement(this, instances); - const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); - for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { - ASSERT((*it)->shadowTreeElement()); - ASSERT((*it)->correspondingElement() == this); - - bool result = (*it)->shadowTreeElement()->Node::addEventListener(eventType, listener, useCapture); + ASSERT(!instanceUpdatesBlocked()); + for (auto* instance : instances()) { + ASSERT(instance->correspondingElement() == this); + bool result = instance->Node::addEventListener(eventType, listener.copyRef(), options); ASSERT_UNUSED(result, result); } return true; } -bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) +bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options) { - HashSet<SVGElementInstance*> instances; - collectInstancesForSVGElement(this, instances); - if (instances.isEmpty()) - return Node::removeEventListener(eventType, listener, useCapture); + if (containingShadowRoot()) + return Node::removeEventListener(eventType, listener, options); - // EventTarget::removeEventListener creates a PassRefPtr around the given EventListener + // EventTarget::removeEventListener creates a Ref around the given EventListener // object when creating a temporary RegisteredEventListener object used to look up the // event listener in a cache. If we want to be able to call removeEventListener() multiple // times on different nodes, we have to delay its immediate destruction, which would happen // after the first call below. - RefPtr<EventListener> protector(listener); + Ref<EventListener> protector(listener); // Remove event listener from regular DOM element - if (!Node::removeEventListener(eventType, listener, useCapture)) + if (!Node::removeEventListener(eventType, listener, options)) return false; // Remove event listener from all shadow tree DOM element instances - const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); - for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { - ASSERT((*it)->correspondingElement() == this); - - SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); - ASSERT(shadowTreeElement); + ASSERT(!instanceUpdatesBlocked()); + for (auto& instance : instances()) { + ASSERT(instance->correspondingElement() == this); - if (shadowTreeElement->Node::removeEventListener(eventType, listener, useCapture)) + if (instance->Node::removeEventListener(eventType, listener, options)) continue; // This case can only be hit for event listeners created from markup - ASSERT(listener->wasCreatedFromMarkup()); + ASSERT(listener.wasCreatedFromMarkup()); // If the event listener 'listener' has been created from markup and has been fired before // then JSLazyEventListener::parseCode() has been called and m_jsFunction of that listener // has been created (read: it's not 0 anymore). During shadow tree creation, the event // listener DOM attribute has been cloned, and another event listener has been setup in // the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0, - // and tryRemoveEventListener() above will fail. Work around that very seldom problem. - EventTargetData* data = shadowTreeElement->eventTargetData(); - ASSERT(data); - - data->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType); + // and tryRemoveEventListener() above will fail. Work around that very rare problem. + ASSERT(instance->eventTargetData()); + instance->eventTargetData()->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType); } return true; @@ -622,11 +578,8 @@ static bool hasLoadListener(Element* element) return true; for (element = element->parentOrShadowHostElement(); element; element = element->parentOrShadowHostElement()) { - const EventListenerVector& entry = element->getEventListeners(eventNames().loadEvent); - for (size_t i = 0; i < entry.size(); ++i) { - if (entry[i].useCapture) - return true; - } + if (element->hasCapturingEventListeners(eventNames().loadEvent)) + return true; } return false; @@ -642,6 +595,9 @@ bool SVGElement::shouldMoveToFlowThread(const RenderStyle& styleToUse) const void SVGElement::sendSVGLoadEventIfPossible(bool sendParentLoadEvents) { + if (!isConnected() || !document().frame()) + return; + RefPtr<SVGElement> currentTarget = this; while (currentTarget && currentTarget->haveLoadedRequiredResources()) { RefPtr<Element> parent; @@ -672,12 +628,12 @@ void SVGElement::sendSVGLoadEventIfPossibleAsynchronously() svgLoadEventTimer()->startOneShot(0); } -void SVGElement::svgLoadEventTimerFired(Timer<SVGElement>*) +void SVGElement::svgLoadEventTimerFired() { sendSVGLoadEventIfPossible(); } -Timer<SVGElement>* SVGElement::svgLoadEventTimer() +Timer* SVGElement::svgLoadEventTimer() { ASSERT_NOT_REACHED(); return 0; @@ -694,23 +650,27 @@ void SVGElement::finishParsingChildren() // finishParsingChildren() is called when the close tag is reached for an element (e.g. </svg>) // we send SVGLoad events here if we can, otherwise they'll be sent when any required loads finish sendSVGLoadEventIfPossible(); + + // Notify all the elements which have references to this element to rebuild their shadow and render + // trees, e.g. a <use> element references a target element before this target element is defined. + invalidateInstances(); } bool SVGElement::childShouldCreateRenderer(const Node& child) const { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, invalidTextContent, ()); + static NeverDestroyed<HashSet<QualifiedName>> invalidTextContent; - if (invalidTextContent.isEmpty()) { - invalidTextContent.add(SVGNames::textPathTag); + if (invalidTextContent.get().isEmpty()) { + invalidTextContent.get().add(SVGNames::textPathTag); #if ENABLE(SVG_FONTS) - invalidTextContent.add(SVGNames::altGlyphTag); + invalidTextContent.get().add(SVGNames::altGlyphTag); #endif - invalidTextContent.add(SVGNames::trefTag); - invalidTextContent.add(SVGNames::tspanTag); + invalidTextContent.get().add(SVGNames::trefTag); + invalidTextContent.get().add(SVGNames::tspanTag); } if (child.isSVGElement()) { - const SVGElement& svgChild = toSVGElement(child); - if (invalidTextContent.contains(svgChild.tagQName())) + const SVGElement& svgChild = downcast<SVGElement>(child); + if (invalidTextContent.get().contains(svgChild.tagQName())) return false; return svgChild.isValid(); @@ -722,8 +682,8 @@ void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString& { StyledElement::attributeChanged(name, oldValue, newValue); - if (isIdAttributeName(name)) - document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this); + if (name == HTMLNames::idAttr) + document().accessSVGExtensions().rebuildAllElementReferencesForTarget(*this); // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods), // so we don't want changes to the style attribute to result in extra work here. @@ -731,17 +691,25 @@ void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString& svgAttributeChanged(name); } +void SVGElement::synchronizeAllAnimatedSVGAttribute(SVGElement* svgElement) +{ + ASSERT(svgElement->elementData()); + ASSERT(svgElement->elementData()->animatedSVGAttributesAreDirty()); + + svgElement->localAttributeToPropertyMap().synchronizeProperties(*svgElement); + svgElement->elementData()->setAnimatedSVGAttributesAreDirty(false); +} + void SVGElement::synchronizeAnimatedSVGAttribute(const QualifiedName& name) const { if (!elementData() || !elementData()->animatedSVGAttributesAreDirty()) return; SVGElement* nonConstThis = const_cast<SVGElement*>(this); - if (name == anyQName()) { - nonConstThis->localAttributeToPropertyMap().synchronizeProperties(nonConstThis); - elementData()->setAnimatedSVGAttributesAreDirty(false); - } else - nonConstThis->localAttributeToPropertyMap().synchronizeProperty(nonConstThis, name); + if (name == anyQName()) + synchronizeAllAnimatedSVGAttribute(nonConstThis); + else + nonConstThis->localAttributeToPropertyMap().synchronizeProperty(*nonConstThis, name); } void SVGElement::synchronizeRequiredFeatures(SVGElement* contextElement) @@ -762,18 +730,13 @@ void SVGElement::synchronizeSystemLanguage(SVGElement* contextElement) contextElement->synchronizeSystemLanguage(); } -PassRefPtr<RenderStyle> SVGElement::customStyleForRenderer() +std::optional<ElementStyle> SVGElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle*) { - if (!correspondingElement()) - return document().ensureStyleResolver().styleForElement(this); - - RenderStyle* style = 0; - if (Element* parent = parentOrShadowHostElement()) { - if (auto renderer = parent->renderer()) - style = &renderer->style(); - } + // If the element is in a <use> tree we get the style from the definition tree. + if (auto* styleElement = this->correspondingElement()) + return styleElement->resolveStyle(&parentStyle); - return document().ensureStyleResolver().styleForElement(correspondingElement(), style, DisallowStyleSharing); + return resolveStyle(&parentStyle); } MutableStyleProperties* SVGElement::animatedSMILStyleProperties() const @@ -794,155 +757,152 @@ void SVGElement::setUseOverrideComputedStyle(bool value) m_svgRareData->setUseOverrideComputedStyle(value); } -RenderStyle* SVGElement::computedStyle(PseudoId pseudoElementSpecifier) +const RenderStyle* SVGElement::computedStyle(PseudoId pseudoElementSpecifier) { if (!m_svgRareData || !m_svgRareData->useOverrideComputedStyle()) return Element::computedStyle(pseudoElementSpecifier); - RenderStyle* parentStyle = nullptr; + const RenderStyle* parentStyle = nullptr; if (Element* parent = parentOrShadowHostElement()) { if (auto renderer = parent->renderer()) parentStyle = &renderer->style(); } - return m_svgRareData->overrideComputedStyle(this, parentStyle); + return m_svgRareData->overrideComputedStyle(*this, parentStyle); } -#ifndef NDEBUG -bool SVGElement::isAnimatableAttribute(const QualifiedName& name) const +static void addQualifiedName(HashMap<AtomicString, QualifiedName>& map, const QualifiedName& name) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, animatableAttributes, ()); + HashMap<AtomicString, QualifiedName>::AddResult addResult = map.add(name.localName(), name); + ASSERT_UNUSED(addResult, addResult.isNewEntry); +} + +QualifiedName SVGElement::animatableAttributeForName(const AtomicString& localName) +{ + static NeverDestroyed<HashMap<AtomicString, QualifiedName>> neverDestroyedAnimatableAttributes; + HashMap<AtomicString, QualifiedName>& animatableAttributes = neverDestroyedAnimatableAttributes; if (animatableAttributes.isEmpty()) { - animatableAttributes.add(XLinkNames::hrefAttr); - animatableAttributes.add(SVGNames::amplitudeAttr); - animatableAttributes.add(SVGNames::azimuthAttr); - animatableAttributes.add(SVGNames::baseFrequencyAttr); - animatableAttributes.add(SVGNames::biasAttr); - animatableAttributes.add(SVGNames::clipPathUnitsAttr); - animatableAttributes.add(SVGNames::cxAttr); - animatableAttributes.add(SVGNames::cyAttr); - animatableAttributes.add(SVGNames::diffuseConstantAttr); - animatableAttributes.add(SVGNames::divisorAttr); - animatableAttributes.add(SVGNames::dxAttr); - animatableAttributes.add(SVGNames::dyAttr); - animatableAttributes.add(SVGNames::edgeModeAttr); - animatableAttributes.add(SVGNames::elevationAttr); - animatableAttributes.add(SVGNames::exponentAttr); - animatableAttributes.add(SVGNames::externalResourcesRequiredAttr); - animatableAttributes.add(SVGNames::filterResAttr); - animatableAttributes.add(SVGNames::filterUnitsAttr); - animatableAttributes.add(SVGNames::fxAttr); - animatableAttributes.add(SVGNames::fyAttr); - animatableAttributes.add(SVGNames::gradientTransformAttr); - animatableAttributes.add(SVGNames::gradientUnitsAttr); - animatableAttributes.add(SVGNames::heightAttr); - animatableAttributes.add(SVGNames::in2Attr); - animatableAttributes.add(SVGNames::inAttr); - animatableAttributes.add(SVGNames::interceptAttr); - animatableAttributes.add(SVGNames::k1Attr); - animatableAttributes.add(SVGNames::k2Attr); - animatableAttributes.add(SVGNames::k3Attr); - animatableAttributes.add(SVGNames::k4Attr); - animatableAttributes.add(SVGNames::kernelMatrixAttr); - animatableAttributes.add(SVGNames::kernelUnitLengthAttr); - animatableAttributes.add(SVGNames::lengthAdjustAttr); - animatableAttributes.add(SVGNames::limitingConeAngleAttr); - animatableAttributes.add(SVGNames::markerHeightAttr); - animatableAttributes.add(SVGNames::markerUnitsAttr); - animatableAttributes.add(SVGNames::markerWidthAttr); - animatableAttributes.add(SVGNames::maskContentUnitsAttr); - animatableAttributes.add(SVGNames::maskUnitsAttr); - animatableAttributes.add(SVGNames::methodAttr); - animatableAttributes.add(SVGNames::modeAttr); - animatableAttributes.add(SVGNames::numOctavesAttr); - animatableAttributes.add(SVGNames::offsetAttr); - animatableAttributes.add(SVGNames::operatorAttr); - animatableAttributes.add(SVGNames::orderAttr); - animatableAttributes.add(SVGNames::orientAttr); - animatableAttributes.add(SVGNames::pathLengthAttr); - animatableAttributes.add(SVGNames::patternContentUnitsAttr); - animatableAttributes.add(SVGNames::patternTransformAttr); - animatableAttributes.add(SVGNames::patternUnitsAttr); - animatableAttributes.add(SVGNames::pointsAtXAttr); - animatableAttributes.add(SVGNames::pointsAtYAttr); - animatableAttributes.add(SVGNames::pointsAtZAttr); - animatableAttributes.add(SVGNames::preserveAlphaAttr); - animatableAttributes.add(SVGNames::preserveAspectRatioAttr); - animatableAttributes.add(SVGNames::primitiveUnitsAttr); - animatableAttributes.add(SVGNames::radiusAttr); - animatableAttributes.add(SVGNames::rAttr); - animatableAttributes.add(SVGNames::refXAttr); - animatableAttributes.add(SVGNames::refYAttr); - animatableAttributes.add(SVGNames::resultAttr); - animatableAttributes.add(SVGNames::rotateAttr); - animatableAttributes.add(SVGNames::rxAttr); - animatableAttributes.add(SVGNames::ryAttr); - animatableAttributes.add(SVGNames::scaleAttr); - animatableAttributes.add(SVGNames::seedAttr); - animatableAttributes.add(SVGNames::slopeAttr); - animatableAttributes.add(SVGNames::spacingAttr); - animatableAttributes.add(SVGNames::specularConstantAttr); - animatableAttributes.add(SVGNames::specularExponentAttr); - animatableAttributes.add(SVGNames::spreadMethodAttr); - animatableAttributes.add(SVGNames::startOffsetAttr); - animatableAttributes.add(SVGNames::stdDeviationAttr); - animatableAttributes.add(SVGNames::stitchTilesAttr); - animatableAttributes.add(SVGNames::surfaceScaleAttr); - animatableAttributes.add(SVGNames::tableValuesAttr); - animatableAttributes.add(SVGNames::targetAttr); - animatableAttributes.add(SVGNames::targetXAttr); - animatableAttributes.add(SVGNames::targetYAttr); - animatableAttributes.add(SVGNames::transformAttr); - animatableAttributes.add(SVGNames::typeAttr); - animatableAttributes.add(SVGNames::valuesAttr); - animatableAttributes.add(SVGNames::viewBoxAttr); - animatableAttributes.add(SVGNames::widthAttr); - animatableAttributes.add(SVGNames::x1Attr); - animatableAttributes.add(SVGNames::x2Attr); - animatableAttributes.add(SVGNames::xAttr); - animatableAttributes.add(SVGNames::xChannelSelectorAttr); - animatableAttributes.add(SVGNames::y1Attr); - animatableAttributes.add(SVGNames::y2Attr); - animatableAttributes.add(SVGNames::yAttr); - animatableAttributes.add(SVGNames::yChannelSelectorAttr); - animatableAttributes.add(SVGNames::zAttr); + addQualifiedName(animatableAttributes, HTMLNames::classAttr); + addQualifiedName(animatableAttributes, SVGNames::amplitudeAttr); + addQualifiedName(animatableAttributes, SVGNames::azimuthAttr); + addQualifiedName(animatableAttributes, SVGNames::baseFrequencyAttr); + addQualifiedName(animatableAttributes, SVGNames::biasAttr); + addQualifiedName(animatableAttributes, SVGNames::clipPathUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::cxAttr); + addQualifiedName(animatableAttributes, SVGNames::cyAttr); + addQualifiedName(animatableAttributes, SVGNames::diffuseConstantAttr); + addQualifiedName(animatableAttributes, SVGNames::divisorAttr); + addQualifiedName(animatableAttributes, SVGNames::dxAttr); + addQualifiedName(animatableAttributes, SVGNames::dyAttr); + addQualifiedName(animatableAttributes, SVGNames::edgeModeAttr); + addQualifiedName(animatableAttributes, SVGNames::elevationAttr); + addQualifiedName(animatableAttributes, SVGNames::exponentAttr); + addQualifiedName(animatableAttributes, SVGNames::externalResourcesRequiredAttr); + addQualifiedName(animatableAttributes, SVGNames::filterResAttr); + addQualifiedName(animatableAttributes, SVGNames::filterUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::fxAttr); + addQualifiedName(animatableAttributes, SVGNames::fyAttr); + addQualifiedName(animatableAttributes, SVGNames::gradientTransformAttr); + addQualifiedName(animatableAttributes, SVGNames::gradientUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::heightAttr); + addQualifiedName(animatableAttributes, SVGNames::in2Attr); + addQualifiedName(animatableAttributes, SVGNames::inAttr); + addQualifiedName(animatableAttributes, SVGNames::interceptAttr); + addQualifiedName(animatableAttributes, SVGNames::k1Attr); + addQualifiedName(animatableAttributes, SVGNames::k2Attr); + addQualifiedName(animatableAttributes, SVGNames::k3Attr); + addQualifiedName(animatableAttributes, SVGNames::k4Attr); + addQualifiedName(animatableAttributes, SVGNames::kernelMatrixAttr); + addQualifiedName(animatableAttributes, SVGNames::kernelUnitLengthAttr); + addQualifiedName(animatableAttributes, SVGNames::lengthAdjustAttr); + addQualifiedName(animatableAttributes, SVGNames::limitingConeAngleAttr); + addQualifiedName(animatableAttributes, SVGNames::markerHeightAttr); + addQualifiedName(animatableAttributes, SVGNames::markerUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::markerWidthAttr); + addQualifiedName(animatableAttributes, SVGNames::maskContentUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::maskUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::methodAttr); + addQualifiedName(animatableAttributes, SVGNames::modeAttr); + addQualifiedName(animatableAttributes, SVGNames::numOctavesAttr); + addQualifiedName(animatableAttributes, SVGNames::offsetAttr); + addQualifiedName(animatableAttributes, SVGNames::operatorAttr); + addQualifiedName(animatableAttributes, SVGNames::orderAttr); + addQualifiedName(animatableAttributes, SVGNames::orientAttr); + addQualifiedName(animatableAttributes, SVGNames::pathLengthAttr); + addQualifiedName(animatableAttributes, SVGNames::patternContentUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::patternTransformAttr); + addQualifiedName(animatableAttributes, SVGNames::patternUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::pointsAtXAttr); + addQualifiedName(animatableAttributes, SVGNames::pointsAtYAttr); + addQualifiedName(animatableAttributes, SVGNames::pointsAtZAttr); + addQualifiedName(animatableAttributes, SVGNames::preserveAlphaAttr); + addQualifiedName(animatableAttributes, SVGNames::preserveAspectRatioAttr); + addQualifiedName(animatableAttributes, SVGNames::primitiveUnitsAttr); + addQualifiedName(animatableAttributes, SVGNames::radiusAttr); + addQualifiedName(animatableAttributes, SVGNames::rAttr); + addQualifiedName(animatableAttributes, SVGNames::refXAttr); + addQualifiedName(animatableAttributes, SVGNames::refYAttr); + addQualifiedName(animatableAttributes, SVGNames::resultAttr); + addQualifiedName(animatableAttributes, SVGNames::rotateAttr); + addQualifiedName(animatableAttributes, SVGNames::rxAttr); + addQualifiedName(animatableAttributes, SVGNames::ryAttr); + addQualifiedName(animatableAttributes, SVGNames::scaleAttr); + addQualifiedName(animatableAttributes, SVGNames::seedAttr); + addQualifiedName(animatableAttributes, SVGNames::slopeAttr); + addQualifiedName(animatableAttributes, SVGNames::spacingAttr); + addQualifiedName(animatableAttributes, SVGNames::specularConstantAttr); + addQualifiedName(animatableAttributes, SVGNames::specularExponentAttr); + addQualifiedName(animatableAttributes, SVGNames::spreadMethodAttr); + addQualifiedName(animatableAttributes, SVGNames::startOffsetAttr); + addQualifiedName(animatableAttributes, SVGNames::stdDeviationAttr); + addQualifiedName(animatableAttributes, SVGNames::stitchTilesAttr); + addQualifiedName(animatableAttributes, SVGNames::surfaceScaleAttr); + addQualifiedName(animatableAttributes, SVGNames::tableValuesAttr); + addQualifiedName(animatableAttributes, SVGNames::targetAttr); + addQualifiedName(animatableAttributes, SVGNames::targetXAttr); + addQualifiedName(animatableAttributes, SVGNames::targetYAttr); + addQualifiedName(animatableAttributes, SVGNames::transformAttr); + addQualifiedName(animatableAttributes, SVGNames::typeAttr); + addQualifiedName(animatableAttributes, SVGNames::valuesAttr); + addQualifiedName(animatableAttributes, SVGNames::viewBoxAttr); + addQualifiedName(animatableAttributes, SVGNames::widthAttr); + addQualifiedName(animatableAttributes, SVGNames::x1Attr); + addQualifiedName(animatableAttributes, SVGNames::x2Attr); + addQualifiedName(animatableAttributes, SVGNames::xAttr); + addQualifiedName(animatableAttributes, SVGNames::xChannelSelectorAttr); + addQualifiedName(animatableAttributes, SVGNames::y1Attr); + addQualifiedName(animatableAttributes, SVGNames::y2Attr); + addQualifiedName(animatableAttributes, SVGNames::yAttr); + addQualifiedName(animatableAttributes, SVGNames::yChannelSelectorAttr); + addQualifiedName(animatableAttributes, SVGNames::zAttr); + addQualifiedName(animatableAttributes, XLinkNames::hrefAttr); } + return animatableAttributes.get(localName); +} - if (name == classAttr) - return true; +#ifndef NDEBUG +bool SVGElement::isAnimatableAttribute(const QualifiedName& name) const +{ + if (SVGElement::animatableAttributeForName(name.localName()) == name) + return !filterOutAnimatableAttribute(name); + return false; +} - return animatableAttributes.contains(name); +bool SVGElement::filterOutAnimatableAttribute(const QualifiedName&) const +{ + return false; } #endif String SVGElement::title() const { - // According to spec, we should not return titles when hovering over root <svg> elements (those - // <title> elements are the title of the document, not a tooltip) so we instantly return. - if (isOutermostSVGSVGElement()) + // According to spec, for stand-alone SVG documents we should not return a title when + // hovering over the rootmost SVG element (the first <title> element is the title of + // the document, not a tooltip) so we instantly return. + if (isOutermostSVGSVGElement() && document().topDocument().isSVGDocument()) return String(); - - // Walk up the tree, to find out whether we're inside a <use> shadow tree, to find the right title. - if (isInShadowTree()) { - Element* shadowHostElement = toShadowRoot(treeScope().rootNode())->hostElement(); - // At this time, SVG nodes are not allowed in non-<use> shadow trees, so any shadow root we do - // have should be a use. The assert and following test is here to catch future shadow DOM changes - // that do enable SVG in a shadow tree. - ASSERT(!shadowHostElement || shadowHostElement->hasTagName(SVGNames::useTag)); - if (shadowHostElement && shadowHostElement->hasTagName(SVGNames::useTag)) { - SVGUseElement* useElement = toSVGUseElement(shadowHostElement); - - // If the <use> title is not empty we found the title to use. - String useTitle(useElement->title()); - if (!useTitle.isEmpty()) - return useTitle; - } - } - - // If we aren't an instance in a <use> or the <use> title was not found, then find the first - // <title> child of this element. - auto firstTitle = descendantsOfType<SVGTitleElement>(*this).first(); + auto firstTitle = childrenOfType<SVGTitleElement>(*this).first(); return firstTitle ? const_cast<SVGTitleElement*>(firstTitle)->innerText() : String(); } @@ -973,7 +933,13 @@ CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName(const QualifiedName& bool SVGElement::isAnimatableCSSProperty(const QualifiedName& attributeName) { - return attributeNameToAnimatedPropertyTypeMap().contains(attributeName.impl()); + return attributeNameToAnimatedPropertyTypeMap().contains(attributeName.impl()) + || cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap().contains(attributeName.impl()); +} + +bool SVGElement::isPresentationAttributeWithSVGDOM(const QualifiedName& attributeName) +{ + return !localAttributeToPropertyMap().types(attributeName).isEmpty(); } bool SVGElement::isPresentationAttribute(const QualifiedName& name) const @@ -992,31 +958,31 @@ void SVGElement::collectStyleForPresentationAttribute(const QualifiedName& name, bool SVGElement::isKnownAttribute(const QualifiedName& attrName) { - return isIdAttributeName(attrName); + return attrName == HTMLNames::idAttr; } void SVGElement::svgAttributeChanged(const QualifiedName& attrName) { CSSPropertyID propId = cssPropertyIdForSVGAttributeName(attrName); if (propId > 0) { - SVGElementInstance::invalidateAllInstancesOfElement(this); + invalidateInstances(); return; } if (attrName == HTMLNames::classAttr) { classAttributeChanged(className()); - SVGElementInstance::invalidateAllInstancesOfElement(this); + invalidateInstances(); return; } - if (isIdAttributeName(attrName)) { - RenderObject* object = renderer(); + if (attrName == HTMLNames::idAttr) { + auto renderer = this->renderer(); // Notify resources about id changes, this is important as we cache resources by id in SVGDocumentExtensions - if (object && object->isSVGResourceContainer()) - object->toRenderSVGResourceContainer()->idChanged(); - if (inDocument()) + if (is<RenderSVGResourceContainer>(renderer)) + downcast<RenderSVGResourceContainer>(*renderer).idChanged(); + if (isConnected()) buildPendingResourcesIfNeeded(); - SVGElementInstance::invalidateAllInstancesOfElement(this); + invalidateInstances(); return; } } @@ -1031,23 +997,23 @@ Node::InsertionNotificationRequest SVGElement::insertedInto(ContainerNode& rootP void SVGElement::buildPendingResourcesIfNeeded() { - if (!needsPendingResourceHandling() || !inDocument() || isInShadowTree()) + if (!needsPendingResourceHandling() || !isConnected() || isInShadowTree()) return; - SVGDocumentExtensions* extensions = document().accessSVGExtensions(); + SVGDocumentExtensions& extensions = document().accessSVGExtensions(); String resourceId = getIdAttribute(); - if (!extensions->isIdOfPendingResource(resourceId)) + if (!extensions.isIdOfPendingResource(resourceId)) return; // Mark pending resources as pending for removal. - extensions->markPendingResourcesForRemoval(resourceId); + extensions.markPendingResourcesForRemoval(resourceId); // Rebuild pending resources for each client of a pending resource that is being removed. - while (Element* clientElement = extensions->removeElementFromPendingResourcesForRemovalMap(resourceId)) { + while (Element* clientElement = extensions.removeElementFromPendingResourcesForRemovalMap(resourceId)) { ASSERT(clientElement->hasPendingResources()); if (clientElement->hasPendingResources()) { clientElement->buildPendingResource(); - extensions->clearHasPendingResourcesIfPossible(clientElement); + extensions.clearHasPendingResourcesIfPossible(clientElement); } } } @@ -1058,10 +1024,10 @@ void SVGElement::childrenChanged(const ChildChange& change) if (change.source == ChildChangeSourceParser) return; - SVGElementInstance::invalidateAllInstancesOfElement(this); + invalidateInstances(); } -PassRefPtr<CSSValue> SVGElement::getPresentationAttribute(const String& name) +RefPtr<DeprecatedCSSOMValue> SVGElement::getPresentationAttribute(const String& name) { if (!hasAttributesWithoutUpdate()) return 0; @@ -1074,8 +1040,10 @@ PassRefPtr<CSSValue> SVGElement::getPresentationAttribute(const String& name) RefPtr<MutableStyleProperties> style = MutableStyleProperties::create(SVGAttributeMode); CSSPropertyID propertyID = cssPropertyIdForSVGAttributeName(attribute->name()); style->setProperty(propertyID, attribute->value()); - RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(propertyID); - return cssValue ? cssValue->cloneForCSSOM() : 0; + auto cssValue = style->getPropertyCSSValue(propertyID); + if (!cssValue) + return nullptr; + return cssValue->createDeprecatedCSSOMWrapper(); } bool SVGElement::instanceUpdatesBlocked() const @@ -1085,6 +1053,10 @@ bool SVGElement::instanceUpdatesBlocked() const void SVGElement::setInstanceUpdatesBlocked(bool value) { + // Catch any callers that calls setInstanceUpdatesBlocked(true) twice in a row. + // That probably indicates nested use of InstanceUpdateBlocker and a bug. + ASSERT(!value || !instanceUpdatesBlocked()); + if (m_svgRareData) m_svgRareData->setInstanceUpdatesBlocked(value); } @@ -1098,7 +1070,7 @@ AffineTransform SVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope void SVGElement::updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement* element) { // If we're not yet in a document, this function will be called again from insertedInto(). Do nothing now. - if (!inDocument()) + if (!isConnected()) return; // An element wants to notify us that its own relative lengths state changed. @@ -1126,22 +1098,29 @@ void SVGElement::updateRelativeLengthsInformation(bool hasRelativeLengths, SVGEl break; // Register us in the parent element map. - toSVGElement(node)->updateRelativeLengthsInformation(hasRelativeLengths, this); + downcast<SVGElement>(*node).updateRelativeLengthsInformation(hasRelativeLengths, this); break; } } -bool SVGElement::isMouseFocusable() const +bool SVGElement::hasFocusEventListeners() const { - if (!isFocusable()) - return false; Element* eventTarget = const_cast<SVGElement*>(this); - return eventTarget->hasEventListeners(eventNames().focusinEvent) || eventTarget->hasEventListeners(eventNames().focusoutEvent); + return eventTarget->hasEventListeners(eventNames().focusinEvent) + || eventTarget->hasEventListeners(eventNames().focusoutEvent) + || eventTarget->hasEventListeners(eventNames().focusEvent) + || eventTarget->hasEventListeners(eventNames().blurEvent); } -bool SVGElement::isKeyboardFocusable(KeyboardEvent*) const +bool SVGElement::isMouseFocusable() const { - return isMouseFocusable(); + if (!isFocusable()) + return false; + Element* eventTarget = const_cast<SVGElement*>(this); + return hasFocusEventListeners() + || eventTarget->hasEventListeners(eventNames().keydownEvent) + || eventTarget->hasEventListeners(eventNames().keyupEvent) + || eventTarget->hasEventListeners(eventNames().keypressEvent); } void SVGElement::accessKeyAction(bool sendMouseEvents) @@ -1149,6 +1128,18 @@ void SVGElement::accessKeyAction(bool sendMouseEvents) dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); } +void SVGElement::invalidateInstances() +{ + if (instanceUpdatesBlocked()) + return; + + auto& instances = this->instances(); + while (!instances.isEmpty()) { + SVGElement* instance = *instances.begin(); + if (SVGUseElement* useElement = instance->correspondingUseElement()) + useElement->invalidateShadowTree(); + instance->setCorrespondingElement(nullptr); + } while (!instances.isEmpty()); } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGElement.h b/Source/WebCore/svg/SVGElement.h index 14321e846..283e6c896 100644 --- a/Source/WebCore/svg/SVGElement.h +++ b/Source/WebCore/svg/SVGElement.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009-2016 Apple Inc. All rights reserved. * Copyright (C) 2013 Samsung Electronics. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -20,36 +20,29 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGElement_h -#define SVGElement_h +#pragma once -#if ENABLE(SVG) -#include "CSSPropertyNames.h" #include "SVGAnimatedString.h" -#include "SVGElementTypeHelpers.h" #include "SVGLangSpace.h" #include "SVGLocatable.h" +#include "SVGNames.h" #include "SVGParsingError.h" #include "SVGPropertyInfo.h" #include "StyledElement.h" -#include "Timer.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> namespace WebCore { class AffineTransform; -class CSSCursorImageValue; class CSSStyleDeclaration; -class CSSValue; +class DeprecatedCSSOMValue; class Document; class SVGAttributeToPropertyMap; -class SVGCursorElement; class SVGDocumentExtensions; -class SVGElementInstance; class SVGElementRareData; class SVGSVGElement; +class SVGUseElement; void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName); @@ -57,16 +50,14 @@ class SVGElement : public StyledElement, public SVGLangSpace { public: bool isOutermostSVGSVGElement() const; - String xmlbase() const; - void setXmlbase(const String&, ExceptionCode&); - SVGSVGElement* ownerSVGElement() const; SVGElement* viewportElement() const; - virtual String title() const override; + String title() const override; static bool isAnimatableCSSProperty(const QualifiedName&); + bool isPresentationAttributeWithSVGDOM(const QualifiedName&); bool isKnownAttribute(const QualifiedName&); - PassRefPtr<CSSValue> getPresentationAttribute(const String& name); + RefPtr<DeprecatedCSSOMValue> getPresentationAttribute(const String& name); virtual bool supportsMarkers() const { return false; } bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); } virtual bool needsPendingResourceHandling() const { return true; } @@ -74,8 +65,6 @@ public: void setInstanceUpdatesBlocked(bool); virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const; - SVGDocumentExtensions* accessDocumentSVGExtensions(); - virtual bool isSVGGraphicsElement() const { return false; } virtual bool isFilterEffect() const { return false; } virtual bool isGradientStop() const { return false; } @@ -87,32 +76,37 @@ public: virtual void svgAttributeChanged(const QualifiedName&); - virtual void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&); + Vector<AnimatedPropertyType> animatedPropertyTypesForAttribute(const QualifiedName&); void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false); void sendSVGLoadEventIfPossibleAsynchronously(); - void svgLoadEventTimerFired(Timer<SVGElement>*); - virtual Timer<SVGElement>* svgLoadEventTimer(); + void svgLoadEventTimerFired(); + virtual Timer* svgLoadEventTimer(); - virtual AffineTransform* supplementalTransform() { return 0; } + virtual AffineTransform* supplementalTransform() { return nullptr; } void invalidateSVGAttributes() { ensureUniqueElementData().setAnimatedSVGAttributesAreDirty(true); } + void invalidateSVGPresentationAttributeStyle() + { + ensureUniqueElementData().setPresentationAttributeStyleIsDirty(true); + // Trigger style recalculation for "elements as resource" (e.g. referenced by feImage). + invalidateStyle(); + } - const HashSet<SVGElementInstance*>& instancesForElement() const; + // The instances of an element are clones made in shadow trees to implement <use>. + const HashSet<SVGElement*>& instances() const; bool getBoundingBox(FloatRect&, SVGLocatable::StyleUpdateStrategy = SVGLocatable::AllowStyleUpdate); - void setCursorElement(SVGCursorElement*); - void cursorElementRemoved(); - void setCursorImageValue(CSSCursorImageValue*); - void cursorImageValueRemoved(); + SVGElement* correspondingElement() const; + SVGUseElement* correspondingUseElement() const; - SVGElement* correspondingElement(); void setCorrespondingElement(SVGElement*); void synchronizeAnimatedSVGAttribute(const QualifiedName&) const; + static void synchronizeAllAnimatedSVGAttribute(SVGElement*); - virtual PassRefPtr<RenderStyle> customStyleForRenderer() override; + std::optional<ElementStyle> resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle) override; static void synchronizeRequiredFeatures(SVGElement* contextElement); static void synchronizeRequiredExtensions(SVGElement* contextElement); @@ -122,8 +116,9 @@ public: virtual void synchronizeRequiredExtensions() { } virtual void synchronizeSystemLanguage() { } + static QualifiedName animatableAttributeForName(const AtomicString&); #ifndef NDEBUG - virtual bool isAnimatableAttribute(const QualifiedName&) const; + bool isAnimatableAttribute(const QualifiedName&) const; #endif MutableStyleProperties* animatedSMILStyleProperties() const; @@ -132,68 +127,93 @@ public: virtual bool haveLoadedRequiredResources(); - virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override; - virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override; + bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override; + bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override; + bool hasFocusEventListeners() const; #if ENABLE(CSS_REGIONS) - virtual bool shouldMoveToFlowThread(const RenderStyle&) const override; + bool shouldMoveToFlowThread(const RenderStyle&) const override; #endif + bool hasTagName(const SVGQualifiedName& name) const { return hasLocalName(name.localName()); } + int tabIndex() const override; + + void callClearTarget() { clearTarget(); } + + class InstanceUpdateBlocker; + protected: SVGElement(const QualifiedName&, Document&); virtual ~SVGElement(); - virtual bool rendererIsNeeded(const RenderStyle&) override; - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool isMouseFocusable() const override; + bool supportsFocus() const override { return false; } + + bool rendererIsNeeded(const RenderStyle&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void finishParsingChildren() override; - virtual void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly) override; - virtual bool childShouldCreateRenderer(const Node&) const override; + void finishParsingChildren() override; + void attributeChanged(const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason = ModifiedDirectly) override; + bool childShouldCreateRenderer(const Node&) const override; SVGElementRareData& ensureSVGRareData(); void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomicString&); static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&); - virtual bool isPresentationAttribute(const QualifiedName&) const override; - virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - virtual void childrenChanged(const ChildChange&) override; + bool isPresentationAttribute(const QualifiedName&) const override; + void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; + void childrenChanged(const ChildChange&) override; virtual bool selfHasRelativeLengths() const { return false; } void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); } void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*); -private: - friend class SVGElementInstance; - - // FIXME: Author shadows should be allowed - // https://bugs.webkit.org/show_bug.cgi?id=77938 - virtual bool areAuthorShadowsAllowed() const override { return false; } + void willRecalcStyle(Style::Change) override; - virtual RenderStyle* computedStyle(PseudoId = NOPSEUDO) override final; - virtual bool willRecalcStyle(Style::Change) override; + class InstanceInvalidationGuard; - virtual bool isSupported(StringImpl* feature, StringImpl* version) const; +private: + const RenderStyle* computedStyle(PseudoId = NOPSEUDO) final; - void mapInstanceToElement(SVGElementInstance*); - void removeInstanceMapping(SVGElementInstance*); + virtual void clearTarget() { } void buildPendingResourcesIfNeeded(); - virtual bool isKeyboardFocusable(KeyboardEvent*) const override; - virtual bool isMouseFocusable() const override; - virtual void accessKeyAction(bool sendMouseEvents) override; + void accessKeyAction(bool sendMouseEvents) override; + +#ifndef NDEBUG + virtual bool filterOutAnimatableAttribute(const QualifiedName&) const; +#endif + + void invalidateInstances(); std::unique_ptr<SVGElementRareData> m_svgRareData; HashSet<SVGElement*> m_elementsWithRelativeLengths; - BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGElement) + BEGIN_DECLARE_ANIMATED_PROPERTIES_BASE(SVGElement) DECLARE_ANIMATED_STRING(ClassName, className) END_DECLARE_ANIMATED_PROPERTIES }; +class SVGElement::InstanceInvalidationGuard { +public: + InstanceInvalidationGuard(SVGElement&); + ~InstanceInvalidationGuard(); +private: + SVGElement& m_element; +}; + +class SVGElement::InstanceUpdateBlocker { +public: + InstanceUpdateBlocker(SVGElement&); + ~InstanceUpdateBlocker(); +private: + SVGElement& m_element; +}; + struct SVGAttributeHashTranslator { static unsigned hash(const QualifiedName& key) { @@ -206,13 +226,36 @@ struct SVGAttributeHashTranslator { static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); } }; -void isSVGElement(const SVGElement&); // Catch unnecessary runtime check of type known at compile time. -inline bool isSVGElement(const Node& node) { return node.isSVGElement(); } -template <> inline bool isElementOfType<const SVGElement>(const Element& element) { return element.isSVGElement(); } +inline SVGElement::InstanceInvalidationGuard::InstanceInvalidationGuard(SVGElement& element) + : m_element(element) +{ +} -NODE_TYPE_CASTS(SVGElement) +inline SVGElement::InstanceInvalidationGuard::~InstanceInvalidationGuard() +{ + m_element.invalidateInstances(); +} +inline SVGElement::InstanceUpdateBlocker::InstanceUpdateBlocker(SVGElement& element) + : m_element(element) +{ + m_element.setInstanceUpdatesBlocked(true); } -#endif -#endif +inline SVGElement::InstanceUpdateBlocker::~InstanceUpdateBlocker() +{ + m_element.setInstanceUpdatesBlocked(false); +} + +inline bool Node::hasTagName(const SVGQualifiedName& name) const +{ + return isSVGElement() && downcast<SVGElement>(*this).hasTagName(name); +} + +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGElement) + static bool isType(const WebCore::Node& node) { return node.isSVGElement(); } +SPECIALIZE_TYPE_TRAITS_END() + +#include "SVGElementTypeHelpers.h" diff --git a/Source/WebCore/svg/SVGElement.idl b/Source/WebCore/svg/SVGElement.idl index 1a8c23047..fcb64aedc 100644 --- a/Source/WebCore/svg/SVGElement.idl +++ b/Source/WebCore/svg/SVGElement.idl @@ -22,9 +22,7 @@ [ JSGenerateToNativeObject, - Conditional=SVG, ] interface SVGElement : Element { - [TreatNullAs=NullString, SetterRaisesException] attribute DOMString xmlbase; readonly attribute SVGSVGElement ownerSVGElement; readonly attribute SVGElement viewportElement; @@ -32,8 +30,18 @@ attribute DOMString xmlspace; readonly attribute SVGAnimatedString className; - readonly attribute CSSStyleDeclaration style; + [ImplementedAs=cssomStyle] readonly attribute CSSStyleDeclaration style; - CSSValue getPresentationAttribute([Default=Undefined] optional DOMString name); + attribute long tabIndex; + + // FIXME: Using "undefined" as default parameter value is wrong. + // This method is deprecated, and we'd like to remove it someday. + DeprecatedCSSOMValue getPresentationAttribute(optional DOMString name = "undefined"); + + void focus(); + void blur(); + + readonly attribute DOMStringMap dataset; }; +SVGElement implements GlobalEventHandlers; diff --git a/Source/WebCore/svg/SVGElementInstance.cpp b/Source/WebCore/svg/SVGElementInstance.cpp deleted file mode 100644 index b0029868b..000000000 --- a/Source/WebCore/svg/SVGElementInstance.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) Research In Motion Limited 2010. All rights reserved. - * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. 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 "SVGElementInstance.h" - -#include "ContainerNodeAlgorithms.h" -#include "Event.h" -#include "EventException.h" -#include "EventListener.h" -#include "EventNames.h" -#include "FrameView.h" -#include "SVGDocumentExtensions.h" -#include "SVGElement.h" -#include "SVGElementInstanceList.h" -#include "SVGUseElement.h" - -#include <wtf/RefCountedLeakCounter.h> - -namespace WebCore { - -DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, instanceCounter, ("WebCoreSVGElementInstance")); - -// EventTarget API -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), abort); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), blur); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), change); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), click); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), contextmenu); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dblclick); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), error); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), focus); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), input); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), keydown); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), keypress); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), keyup); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), load); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mousedown); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseenter); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseleave); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mousemove); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseout); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseover); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseup); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mousewheel); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), wheel); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), beforecut); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), cut); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), beforecopy); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), copy); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), beforepaste); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), paste); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragenter); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragover); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragleave); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), drop); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragstart); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), drag); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragend); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), reset); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), resize); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), scroll); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), search); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), select); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), selectstart); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), submit); -DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), unload); - -PassRefPtr<SVGElementInstance> SVGElementInstance::create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement) -{ - return adoptRef(new SVGElementInstance(correspondingUseElement, directUseElement, originalElement)); -} - -SVGElementInstance::SVGElementInstance(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement) - : m_parentInstance(0) - , m_correspondingUseElement(correspondingUseElement) - , m_directUseElement(directUseElement) - , m_element(originalElement) - , m_previousSibling(0) - , m_nextSibling(0) - , m_firstChild(0) - , m_lastChild(0) -{ - ASSERT(m_correspondingUseElement); - ASSERT(m_element); - - // Register as instance for passed element. - m_element->mapInstanceToElement(this); - -#ifndef NDEBUG - instanceCounter.increment(); -#endif -} - -SVGElementInstance::~SVGElementInstance() -{ - // Call detach because we may be deleted directly if we are a child of a detached instance. - detach(); - -#ifndef NDEBUG - instanceCounter.decrement(); -#endif - - m_element = 0; -} - -// It's important not to inline removedLastRef, because we don't want to inline the code to -// delete an SVGElementInstance at each deref call site. -void SVGElementInstance::removedLastRef() -{ -#ifndef NDEBUG - m_deletionHasBegun = true; -#endif - delete this; -} - -Node* SVGElementInstance::toNode() -{ - return shadowTreeElement(); -} - -void SVGElementInstance::detach() -{ - // Clear all pointers. When the node is detached from the shadow DOM it should be removed but, - // due to ref counting, it may not be. So clear everything to avoid dangling pointers. - - for (SVGElementInstance* node = firstChild(); node; node = node->nextSibling()) - node->detach(); - - // Deregister as instance for passed element, if we haven't already. - if (m_element->instancesForElement().contains(this)) - m_element->removeInstanceMapping(this); - // DO NOT clear ref to m_element because JavaScriptCore uses it for garbage collection - - m_shadowTreeElement = 0; - - m_directUseElement = 0; - m_correspondingUseElement = 0; - - removeDetachedChildrenInContainer<SVGElementInstance, SVGElementInstance>(*this); -} - -PassRefPtr<SVGElementInstanceList> SVGElementInstance::childNodes() -{ - return SVGElementInstanceList::create(this); -} - -Document* SVGElementInstance::ownerDocument() const -{ - return m_element ? &m_element->document() : 0; -} - -void SVGElementInstance::setShadowTreeElement(SVGElement* element) -{ - ASSERT(element); - m_shadowTreeElement = element; -} - -void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child) -{ - appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), *this); -} - -void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element) -{ - if (!element || !element->inDocument()) - return; - - if (element->instanceUpdatesBlocked()) - return; - - const HashSet<SVGElementInstance*>& set = element->instancesForElement(); - if (set.isEmpty()) - return; - - // Mark all use elements referencing 'element' for rebuilding - const HashSet<SVGElementInstance*>::const_iterator end = set.end(); - for (HashSet<SVGElementInstance*>::const_iterator it = set.begin(); it != end; ++it) { - ASSERT((*it)->shadowTreeElement()); - ASSERT((*it)->shadowTreeElement()->correspondingElement()); - ASSERT((*it)->shadowTreeElement()->correspondingElement() == (*it)->correspondingElement()); - ASSERT((*it)->correspondingElement() == element); - (*it)->shadowTreeElement()->setCorrespondingElement(0); - - if (SVGUseElement* element = (*it)->correspondingUseElement()) { - ASSERT(element->inDocument()); - element->invalidateShadowTree(); - } - } - - element->document().updateStyleIfNeeded(); -} - -EventTargetInterface SVGElementInstance::eventTargetInterface() const -{ - return SVGElementInstanceEventTargetInterfaceType; -} - -ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const -{ - return &m_element->document(); -} - -bool SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) -{ - return m_element->addEventListener(eventType, listener, useCapture); -} - -bool SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) -{ - return m_element->removeEventListener(eventType, listener, useCapture); -} - -void SVGElementInstance::removeAllEventListeners() -{ - m_element->removeAllEventListeners(); -} - -bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> event) -{ - SVGElement* element = shadowTreeElement(); - if (!element) - return false; - - return element->dispatchEvent(event); -} - -EventTargetData* SVGElementInstance::eventTargetData() -{ - // Since no event listeners are added to an SVGElementInstance, we don't have eventTargetData. - return 0; -} - -EventTargetData& SVGElementInstance::ensureEventTargetData() -{ - // EventTarget would use these methods if we were actually using its add/removeEventListener logic. - // As we're forwarding those calls to the correspondingElement(), no one should ever call this function. - ASSERT_NOT_REACHED(); - return *eventTargetData(); -} - -SVGElementInstance::InstanceUpdateBlocker::InstanceUpdateBlocker(SVGElement* targetElement) - : m_targetElement(targetElement) -{ - if (m_targetElement) - m_targetElement->setInstanceUpdatesBlocked(true); -} - -SVGElementInstance::InstanceUpdateBlocker::~InstanceUpdateBlocker() -{ - if (m_targetElement) - m_targetElement->setInstanceUpdatesBlocked(false); -} - -} - -#endif diff --git a/Source/WebCore/svg/SVGElementInstance.h b/Source/WebCore/svg/SVGElementInstance.h deleted file mode 100644 index 586f2ae4f..000000000 --- a/Source/WebCore/svg/SVGElementInstance.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. 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 SVGElementInstance_h -#define SVGElementInstance_h - -#if ENABLE(SVG) -#include "EventTarget.h" -#include "TreeShared.h" - -namespace WebCore { - -namespace Private { -template<class GenericNode, class GenericNodeContainer> -void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container); -}; - -class Document; -class SVGElement; -class SVGElementInstanceList; -class SVGElement; -class SVGUseElement; - -// SVGElementInstance mimics Node, but without providing all its functionality -class SVGElementInstance : public EventTarget, public TreeShared<SVGElementInstance> { -public: - static PassRefPtr<SVGElementInstance> create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement); - - virtual ~SVGElementInstance(); - - void setParentNode(SVGElementInstance* instance) { m_parentInstance = instance; } - - virtual EventTargetInterface eventTargetInterface() const override; - virtual ScriptExecutionContext* scriptExecutionContext() const override; - - virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override; - virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override; - virtual void removeAllEventListeners() override; - - using EventTarget::dispatchEvent; - virtual bool dispatchEvent(PassRefPtr<Event>) override; - - SVGElement* correspondingElement() const { return m_element.get(); } - SVGUseElement* correspondingUseElement() const { return m_correspondingUseElement; } - SVGUseElement* directUseElement() const { return m_directUseElement; } - SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); } - - void detach(); - - SVGElementInstance* parentNode() const { return m_parentInstance; } - PassRefPtr<SVGElementInstanceList> childNodes(); - - SVGElementInstance* previousSibling() const { return m_previousSibling; } - SVGElementInstance* nextSibling() const { return m_nextSibling; } - - SVGElementInstance* firstChild() const { return m_firstChild; } - SVGElementInstance* lastChild() const { return m_lastChild; } - - Document* ownerDocument() const; - - class InvalidationGuard { - WTF_MAKE_NONCOPYABLE(InvalidationGuard); - public: - InvalidationGuard(SVGElement* element) : m_element(element) { } - ~InvalidationGuard() { SVGElementInstance::invalidateAllInstancesOfElement(m_element); } - private: - SVGElement* m_element; - }; - - class InstanceUpdateBlocker { - WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker); - public: - InstanceUpdateBlocker(SVGElement* targetElement); - ~InstanceUpdateBlocker(); - - private: - SVGElement* m_targetElement; - }; - - static void invalidateAllInstancesOfElement(SVGElement*); - - using TreeShared<SVGElementInstance>::ref; - using TreeShared<SVGElementInstance>::deref; - - // EventTarget API - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseenter); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseleave); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), wheel); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit); - DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload); - -private: - friend class SVGUseElement; - friend class TreeShared<SVGElementInstance>; - - SVGElementInstance(SVGUseElement*, SVGUseElement*, PassRefPtr<SVGElement> originalElement); - - void removedLastRef(); - bool hasTreeSharedParent() const { return !!m_parentInstance; } - - virtual Node* toNode() override; - - void appendChild(PassRefPtr<SVGElementInstance> child); - void setShadowTreeElement(SVGElement*); - - template<class GenericNode, class GenericNodeContainer> - friend void appendChildToContainer(GenericNode* child, GenericNodeContainer& container); - - template<class GenericNode, class GenericNodeContainer> - friend void removeDetachedChildrenInContainer(GenericNodeContainer&); - - template<class GenericNode, class GenericNodeContainer> - friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container); - - bool hasChildNodes() const { return m_firstChild; } - - void setFirstChild(SVGElementInstance* child) { m_firstChild = child; } - void setLastChild(SVGElementInstance* child) { m_lastChild = child; } - - void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; } - void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; } - - virtual void refEventTarget() override { ref(); } - virtual void derefEventTarget() override { deref(); } - virtual EventTargetData* eventTargetData() override; - virtual EventTargetData& ensureEventTargetData() override; - - SVGElementInstance* m_parentInstance; - - SVGUseElement* m_correspondingUseElement; - SVGUseElement* m_directUseElement; - RefPtr<SVGElement> m_element; - RefPtr<SVGElement> m_shadowTreeElement; - - SVGElementInstance* m_previousSibling; - SVGElementInstance* m_nextSibling; - - SVGElementInstance* m_firstChild; - SVGElementInstance* m_lastChild; -}; - -} // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGElementInstance.idl b/Source/WebCore/svg/SVGElementInstance.idl deleted file mode 100644 index 9bbb132d6..000000000 --- a/Source/WebCore/svg/SVGElementInstance.idl +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -[ - Conditional=SVG, - JSCustomMarkFunction, - JSGenerateToNativeObject, - JSGenerateToJSObject, - EventTarget -] interface SVGElementInstance -#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C - : Object, EventTarget -#else - : EventTarget -#endif /* defined(LANGUAGE_OBJECTIVE_C) */ -{ - readonly attribute SVGElement correspondingElement; - readonly attribute SVGUseElement correspondingUseElement; - readonly attribute SVGElementInstance parentNode; - readonly attribute SVGElementInstanceList childNodes; - readonly attribute SVGElementInstance firstChild; - readonly attribute SVGElementInstance lastChild; - readonly attribute SVGElementInstance previousSibling; - readonly attribute SVGElementInstance nextSibling; - - // EventTarget -#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C - [NotEnumerable] attribute EventListener onabort; - [NotEnumerable] attribute EventListener onblur; - [NotEnumerable] attribute EventListener onchange; - [NotEnumerable] attribute EventListener onclick; - [NotEnumerable] attribute EventListener oncontextmenu; - [NotEnumerable] attribute EventListener ondblclick; - [NotEnumerable] attribute EventListener onerror; - [NotEnumerable] attribute EventListener onfocus; - [NotEnumerable] attribute EventListener oninput; - [NotEnumerable] attribute EventListener onkeydown; - [NotEnumerable] attribute EventListener onkeypress; - [NotEnumerable] attribute EventListener onkeyup; - [NotEnumerable] attribute EventListener onload; - [NotEnumerable] attribute EventListener onmousedown; - [NotEnumerable] attribute EventListener onmouseenter; - [NotEnumerable] attribute EventListener onmouseleave; - [NotEnumerable] attribute EventListener onmousemove; - [NotEnumerable] attribute EventListener onmouseout; - [NotEnumerable] attribute EventListener onmouseover; - [NotEnumerable] attribute EventListener onmouseup; - [NotEnumerable] attribute EventListener onmousewheel; - [NotEnumerable] attribute EventListener onwheel; - [NotEnumerable] attribute EventListener onbeforecut; - [NotEnumerable] attribute EventListener oncut; - [NotEnumerable] attribute EventListener onbeforecopy; - [NotEnumerable] attribute EventListener oncopy; - [NotEnumerable] attribute EventListener onbeforepaste; - [NotEnumerable] attribute EventListener onpaste; - [NotEnumerable] attribute EventListener ondragenter; - [NotEnumerable] attribute EventListener ondragover; - [NotEnumerable] attribute EventListener ondragleave; - [NotEnumerable] attribute EventListener ondrop; - [NotEnumerable] attribute EventListener ondragstart; - [NotEnumerable] attribute EventListener ondrag; - [NotEnumerable] attribute EventListener ondragend; - [NotEnumerable] attribute EventListener onreset; - [NotEnumerable] attribute EventListener onresize; - [NotEnumerable] attribute EventListener onscroll; - [NotEnumerable] attribute EventListener onsearch; - [NotEnumerable] attribute EventListener onselect; - [NotEnumerable] attribute EventListener onselectstart; - [NotEnumerable] attribute EventListener onsubmit; - [NotEnumerable] attribute EventListener onunload; -#endif /* defined(LANGUAGE_OBJECTIVE_C) */ -}; diff --git a/Source/WebCore/svg/SVGElementInstanceList.cpp b/Source/WebCore/svg/SVGElementInstanceList.cpp deleted file mode 100644 index 0c5abcde1..000000000 --- a/Source/WebCore/svg/SVGElementInstanceList.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2007 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. - */ - -#include "config.h" - -#if ENABLE(SVG) -#include "SVGElementInstanceList.h" - -#include "SVGElementInstance.h" - -namespace WebCore { - -SVGElementInstanceList::SVGElementInstanceList(PassRefPtr<SVGElementInstance> rootInstance) - : m_rootInstance(rootInstance) -{ -} - -SVGElementInstanceList::~SVGElementInstanceList() -{ -} - -unsigned SVGElementInstanceList::length() const -{ - // NOTE: We could use the same caching facilities, like the ones "ChildNodeList" uses. - unsigned length = 0; - for (SVGElementInstance* instance = m_rootInstance->firstChild(); instance; instance = instance->nextSibling()) - length++; - return length; -} - -SVGElementInstance* SVGElementInstanceList::item(unsigned index) -{ - unsigned pos = 0; - SVGElementInstance* instance = m_rootInstance->firstChild(); - while (instance && pos < index) { - instance = instance->nextSibling(); - pos++; - } - return instance; -} - -} - -#endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGElementInstanceList.idl b/Source/WebCore/svg/SVGElementInstanceList.idl deleted file mode 100644 index 8e0a177fc..000000000 --- a/Source/WebCore/svg/SVGElementInstanceList.idl +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -[ - Conditional=SVG, -] interface SVGElementInstanceList { - readonly attribute unsigned long length; - - SVGElementInstance item([Default=Undefined] optional unsigned long index); -}; diff --git a/Source/WebCore/svg/SVGElementRareData.h b/Source/WebCore/svg/SVGElementRareData.h index 981481b97..60dc538d5 100644 --- a/Source/WebCore/svg/SVGElementRareData.h +++ b/Source/WebCore/svg/SVGElementRareData.h @@ -17,8 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGElementRareData_h -#define SVGElementRareData_h +#pragma once #include "StyleProperties.h" #include "StyleResolver.h" @@ -31,36 +30,26 @@ namespace WebCore { class CSSCursorImageValue; class SVGCursorElement; class SVGElement; -class SVGElementInstance; class SVGElementRareData { WTF_MAKE_NONCOPYABLE(SVGElementRareData); WTF_MAKE_FAST_ALLOCATED; public: SVGElementRareData() - : m_cursorElement(0) - , m_cursorImageValue(0) - , m_correspondingElement(0) - , m_instancesUpdatesBlocked(false) + : m_instancesUpdatesBlocked(false) , m_useOverrideComputedStyle(false) , m_needsOverrideComputedStyleUpdate(false) { } - HashSet<SVGElementInstance*>& elementInstances() { return m_elementInstances; } - const HashSet<SVGElementInstance*>& elementInstances() const { return m_elementInstances; } + HashSet<SVGElement*>& instances() { return m_instances; } + const HashSet<SVGElement*>& instances() const { return m_instances; } 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; } - SVGElement* correspondingElement() { return m_correspondingElement; } void setCorrespondingElement(SVGElement* correspondingElement) { m_correspondingElement = correspondingElement; } - CSSCursorImageValue* cursorImageValue() const { return m_cursorImageValue; } - void setCursorImageValue(CSSCursorImageValue* cursorImageValue) { m_cursorImageValue = cursorImageValue; } - MutableStyleProperties* animatedSMILStyleProperties() const { return m_animatedSMILStyleProperties.get(); } MutableStyleProperties& ensureAnimatedSMILStyleProperties() { @@ -69,19 +58,13 @@ public: return *m_animatedSMILStyleProperties; } - void destroyAnimatedSMILStyleProperties() - { - m_animatedSMILStyleProperties.clear(); - } - - RenderStyle* overrideComputedStyle(Element* element, RenderStyle* parentStyle) + const RenderStyle* overrideComputedStyle(Element& element, const RenderStyle* parentStyle) { - ASSERT(element); if (!m_useOverrideComputedStyle) - return 0; + return nullptr; if (!m_overrideComputedStyle || m_needsOverrideComputedStyleUpdate) { // The style computed here contains no CSS Animations/Transitions or SMIL induced rules - this is needed to compute the "base value" for the SMIL animation sandwhich model. - m_overrideComputedStyle = element->document().ensureStyleResolver().styleForElement(element, parentStyle, DisallowStyleSharing, MatchAllRulesExcludingSMIL); + m_overrideComputedStyle = element.styleResolver().styleForElement(element, parentStyle, nullptr, MatchAllRulesExcludingSMIL).renderStyle; m_needsOverrideComputedStyleUpdate = false; } ASSERT(m_overrideComputedStyle); @@ -93,17 +76,13 @@ public: void setNeedsOverrideComputedStyleUpdate() { m_needsOverrideComputedStyleUpdate = true; } private: - HashSet<SVGElementInstance*> m_elementInstances; - SVGCursorElement* m_cursorElement; - CSSCursorImageValue* m_cursorImageValue; - SVGElement* m_correspondingElement; + HashSet<SVGElement*> m_instances; + SVGElement* m_correspondingElement { nullptr }; bool m_instancesUpdatesBlocked : 1; bool m_useOverrideComputedStyle : 1; bool m_needsOverrideComputedStyleUpdate : 1; RefPtr<MutableStyleProperties> m_animatedSMILStyleProperties; - RefPtr<RenderStyle> m_overrideComputedStyle; + std::unique_ptr<RenderStyle> m_overrideComputedStyle; }; -} - -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGEllipseElement.cpp b/Source/WebCore/svg/SVGEllipseElement.cpp index e8e70f52c..96ec6a50e 100644 --- a/Source/WebCore/svg/SVGEllipseElement.cpp +++ b/Source/WebCore/svg/SVGEllipseElement.cpp @@ -19,17 +19,13 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGEllipseElement.h" -#include "Attribute.h" #include "FloatPoint.h" #include "RenderSVGEllipse.h" #include "RenderSVGPath.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" -#include "SVGLength.h" +#include "SVGLengthValue.h" #include "SVGNames.h" namespace WebCore { @@ -61,95 +57,52 @@ inline SVGEllipseElement::SVGEllipseElement(const QualifiedName& tagName, Docume registerAnimatedPropertiesForSVGEllipseElement(); } -PassRefPtr<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGEllipseElement(tagName, document)); -} - -bool SVGEllipseElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::cxAttr); - supportedAttributes.add(SVGNames::cyAttr); - supportedAttributes.add(SVGNames::rxAttr); - supportedAttributes.add(SVGNames::ryAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGEllipseElement(tagName, document)); } void SVGEllipseElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::cxAttr) - setCxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::cxAttr) + setCxBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::cyAttr) - setCyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setCyBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::rxAttr) - setRxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); + setRxBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::ryAttr) - setRyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setRyBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGGraphicsElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - bool isLengthAttribute = attrName == SVGNames::cxAttr - || attrName == SVGNames::cyAttr - || attrName == SVGNames::rxAttr - || attrName == SVGNames::ryAttr; - - if (isLengthAttribute) - updateRelativeLengthsInformation(); - - RenderSVGShape* renderer = toRenderSVGShape(this->renderer()); - if (!renderer) - return; - - if (isLengthAttribute) { - renderer->setNeedsShapeUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + if (attrName == SVGNames::cxAttr || attrName == SVGNames::cyAttr || attrName == SVGNames::rxAttr || attrName == SVGNames::ryAttr) { + InstanceInvalidationGuard guard(*this); + invalidateSVGPresentationAttributeStyle(); return; } if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + if (auto* renderer = downcast<RenderSVGShape>(this->renderer())) { + InstanceInvalidationGuard guard(*this); + RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } return; } - ASSERT_NOT_REACHED(); -} - -bool SVGEllipseElement::selfHasRelativeLengths() const -{ - return cx().isRelative() - || cy().isRelative() - || rx().isRelative() - || ry().isRelative(); + SVGGraphicsElement::svgAttributeChanged(attrName); } -RenderPtr<RenderElement> SVGEllipseElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGEllipseElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGEllipse>(*this, std::move(style)); + return createRenderer<RenderSVGEllipse>(*this, WTFMove(style)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGEllipseElement.h b/Source/WebCore/svg/SVGEllipseElement.h index e8cb1920b..340698ff1 100644 --- a/Source/WebCore/svg/SVGEllipseElement.h +++ b/Source/WebCore/svg/SVGEllipseElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGEllipseElement_h -#define SVGEllipseElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGExternalResourcesRequired.h" @@ -32,34 +30,27 @@ namespace WebCore { class SVGEllipseElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGEllipseElement> create(const QualifiedName&, Document&); + static Ref<SVGEllipseElement> create(const QualifiedName&, Document&); private: SVGEllipseElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final { return true; } - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGEllipseElement) DECLARE_ANIMATED_LENGTH(Cx, cx) DECLARE_ANIMATED_LENGTH(Cy, cy) DECLARE_ANIMATED_LENGTH(Rx, rx) DECLARE_ANIMATED_LENGTH(Ry, ry) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGEllipseElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGEllipseElement.idl b/Source/WebCore/svg/SVGEllipseElement.idl index 9a7a31847..16a5988ea 100644 --- a/Source/WebCore/svg/SVGEllipseElement.idl +++ b/Source/WebCore/svg/SVGEllipseElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGEllipseElement : SVGGraphicsElement { +interface SVGEllipseElement : SVGGraphicsElement { readonly attribute SVGAnimatedLength cx; readonly attribute SVGAnimatedLength cy; readonly attribute SVGAnimatedLength rx; diff --git a/Source/WebCore/svg/SVGException.cpp b/Source/WebCore/svg/SVGException.cpp index e01b5b52a..7614cbd73 100644 --- a/Source/WebCore/svg/SVGException.cpp +++ b/Source/WebCore/svg/SVGException.cpp @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -27,11 +27,10 @@ */ #include "config.h" - -#if ENABLE(SVG) - #include "SVGException.h" +#include "ExceptionCodeDescription.h" + namespace WebCore { static struct SVGExceptionNameDescription { @@ -55,12 +54,10 @@ bool SVGException::initializeDescription(ExceptionCode ec, ExceptionCodeDescript size_t tableSize = WTF_ARRAY_LENGTH(svgExceptions); size_t tableIndex = ec - SVG_WRONG_TYPE_ERR; - description->name = tableIndex < tableSize ? svgExceptions[tableIndex].name : 0; - description->description = tableIndex < tableSize ? svgExceptions[tableIndex].description : 0; + description->name = tableIndex < tableSize ? svgExceptions[tableIndex].name : nullptr; + description->description = tableIndex < tableSize ? svgExceptions[tableIndex].description : nullptr; return true; } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGException.h b/Source/WebCore/svg/SVGException.h index 51287439d..39e2f4477 100644 --- a/Source/WebCore/svg/SVGException.h +++ b/Source/WebCore/svg/SVGException.h @@ -18,20 +18,17 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGException_h -#define SVGException_h +#pragma once #include "ExceptionBase.h" -#if ENABLE(SVG) - namespace WebCore { -class SVGException : public ExceptionBase { +class SVGException final : public ExceptionBase { public: - static PassRefPtr<SVGException> create(const ExceptionCodeDescription& description) + static Ref<SVGException> create(const ExceptionCodeDescription& description) { - return adoptRef(new SVGException(description)); + return adoptRef(*new SVGException(description)); } static const int SVGExceptionOffset = 300; @@ -53,7 +50,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) - -#endif // SVGException_h diff --git a/Source/WebCore/svg/SVGException.idl b/Source/WebCore/svg/SVGException.idl index c3d8a1417..fa0c118de 100644 --- a/Source/WebCore/svg/SVGException.idl +++ b/Source/WebCore/svg/SVGException.idl @@ -19,19 +19,14 @@ */ [ - Conditional=SVG, DoNotCheckConstants, ImplementationLacksVTable, ] exception SVGException { - readonly attribute unsigned short code; readonly attribute DOMString name; readonly attribute DOMString message; -#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT - // Override in a Mozilla compatible format [NotEnumerable] DOMString toString(); -#endif // SVGExceptionCode const unsigned short SVG_WRONG_TYPE_ERR = 0; diff --git a/Source/WebCore/svg/SVGExternalResourcesRequired.cpp b/Source/WebCore/svg/SVGExternalResourcesRequired.cpp index 52901da5a..b0d38ecaa 100644 --- a/Source/WebCore/svg/SVGExternalResourcesRequired.cpp +++ b/Source/WebCore/svg/SVGExternalResourcesRequired.cpp @@ -19,24 +19,17 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGExternalResourcesRequired.h" -#include "Attr.h" #include "SVGElement.h" #include "SVGNames.h" namespace WebCore { -bool SVGExternalResourcesRequired::parseAttribute(const QualifiedName& name, const AtomicString& value) +void SVGExternalResourcesRequired::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (name == SVGNames::externalResourcesRequiredAttr) { + if (name == SVGNames::externalResourcesRequiredAttr) setExternalResourcesRequiredBaseValue(value == "true"); - return true; - } - - return false; } bool SVGExternalResourcesRequired::isKnownAttribute(const QualifiedName& attrName) @@ -54,7 +47,7 @@ bool SVGExternalResourcesRequired::handleAttributeChange(SVGElement* targetEleme ASSERT(targetElement); if (!isKnownAttribute(attrName)) return false; - if (!targetElement->inDocument()) + if (!targetElement->isConnected()) return true; // Handle dynamic updates of the 'externalResourcesRequired' attribute. Only possible case: changing from 'true' to 'false' @@ -120,5 +113,3 @@ bool SVGExternalResourcesRequired::haveLoadedRequiredResources() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGExternalResourcesRequired.h b/Source/WebCore/svg/SVGExternalResourcesRequired.h index 01285aad5..66355fd67 100644 --- a/Source/WebCore/svg/SVGExternalResourcesRequired.h +++ b/Source/WebCore/svg/SVGExternalResourcesRequired.h @@ -18,16 +18,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGExternalResourcesRequired_h -#define SVGExternalResourcesRequired_h +#pragma once -#if ENABLE(SVG) #include "QualifiedName.h" #include <wtf/HashSet.h> namespace WebCore { -class Attribute; class SVGElement; // Notes on a SVG 1.1 spec discrepancy: @@ -39,9 +36,11 @@ class SVGExternalResourcesRequired { public: virtual ~SVGExternalResourcesRequired() { } - bool parseAttribute(const QualifiedName&, const AtomicString&); - bool isKnownAttribute(const QualifiedName&); - void addSupportedAttributes(HashSet<QualifiedName>&); + void parseAttribute(const QualifiedName&, const AtomicString&); + + static bool isKnownAttribute(const QualifiedName&); + static void addSupportedAttributes(HashSet<QualifiedName>&); + bool handleAttributeChange(SVGElement*, const QualifiedName&); protected: @@ -60,6 +59,3 @@ protected: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGExternalResourcesRequired.idl b/Source/WebCore/svg/SVGExternalResourcesRequired.idl index 7d9d491f4..022088967 100644 --- a/Source/WebCore/svg/SVGExternalResourcesRequired.idl +++ b/Source/WebCore/svg/SVGExternalResourcesRequired.idl @@ -26,9 +26,6 @@ [ NoInterfaceObject, - Conditional=SVG, - ObjCProtocol, ] interface SVGExternalResourcesRequired { readonly attribute SVGAnimatedBoolean externalResourcesRequired; }; - diff --git a/Source/WebCore/svg/SVGFEBlendElement.cpp b/Source/WebCore/svg/SVGFEBlendElement.cpp index 8548caa3a..f29ea3374 100644 --- a/Source/WebCore/svg/SVGFEBlendElement.cpp +++ b/Source/WebCore/svg/SVGFEBlendElement.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -19,13 +20,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEBlendElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" @@ -34,7 +31,7 @@ namespace WebCore { // Animated property definitions DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::inAttr, In1, in1) DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::in2Attr, In2, in2) -DEFINE_ANIMATED_ENUMERATION(SVGFEBlendElement, SVGNames::modeAttr, Mode, mode, BlendModeType) +DEFINE_ANIMATED_ENUMERATION(SVGFEBlendElement, SVGNames::modeAttr, Mode, mode, BlendMode) BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEBlendElement) REGISTER_LOCAL_ANIMATED_PROPERTY(in1) @@ -45,39 +42,23 @@ END_REGISTER_ANIMATED_PROPERTIES inline SVGFEBlendElement::SVGFEBlendElement(const QualifiedName& tagName, Document& document) : SVGFilterPrimitiveStandardAttributes(tagName, document) - , m_mode(FEBLEND_MODE_NORMAL) + , m_mode(BlendModeNormal) { ASSERT(hasTagName(SVGNames::feBlendTag)); registerAnimatedPropertiesForSVGFEBlendElement(); } -PassRefPtr<SVGFEBlendElement> SVGFEBlendElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFEBlendElement(tagName, document)); -} - -bool SVGFEBlendElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFEBlendElement> SVGFEBlendElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::modeAttr); - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::in2Attr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFEBlendElement(tagName, document)); } void SVGFEBlendElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::modeAttr) { - BlendModeType propertyValue = SVGPropertyTraits<BlendModeType>::fromString(value); - if (propertyValue > 0) - setModeBaseValue(propertyValue); + BlendMode mode = BlendModeNormal; + if (parseBlendMode(value, mode)) + setModeBaseValue(mode); return; } @@ -91,7 +72,7 @@ void SVGFEBlendElement::parseAttribute(const QualifiedName& name, const AtomicSt return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -106,42 +87,35 @@ bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const Qua void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::modeAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); FilterEffect* input2 = filterBuilder->getEffectById(in2()); if (!input1 || !input2) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FEBlend::create(filter, mode()); FilterEffectVector& inputEffects = effect->inputEffects(); inputEffects.reserveCapacity(2); inputEffects.append(input1); inputEffects.append(input2); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEBlendElement.h b/Source/WebCore/svg/SVGFEBlendElement.h index 89c284d1b..416055ef3 100644 --- a/Source/WebCore/svg/SVGFEBlendElement.h +++ b/Source/WebCore/svg/SVGFEBlendElement.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -18,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEBlendElement_h -#define SVGFEBlendElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEBlend.h" #include "SVGAnimatedEnumeration.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -29,67 +28,45 @@ namespace WebCore { template<> -struct SVGPropertyTraits<BlendModeType> { - static unsigned highestEnumValue() { return FEBLEND_MODE_LIGHTEN; } +struct SVGPropertyTraits<BlendMode> { + static unsigned highestEnumValue() { return BlendModeLighten; } - static String toString(BlendModeType type) + static String toString(BlendMode type) { switch (type) { - case FEBLEND_MODE_UNKNOWN: + case BlendModeNormal: + return ASCIILiteral("normal"); + case BlendModeMultiply: + return ASCIILiteral("multiply"); + case BlendModeScreen: + return ASCIILiteral("screen"); + case BlendModeDarken: + return ASCIILiteral("darken"); + case BlendModeLighten: + return ASCIILiteral("lighten"); + default: return emptyString(); - case FEBLEND_MODE_NORMAL: - return "normal"; - case FEBLEND_MODE_MULTIPLY: - return "multiply"; - case FEBLEND_MODE_SCREEN: - return "screen"; - case FEBLEND_MODE_DARKEN: - return "darken"; - case FEBLEND_MODE_LIGHTEN: - return "lighten"; } - - ASSERT_NOT_REACHED(); - return emptyString(); - } - - static BlendModeType fromString(const String& value) - { - if (value == "normal") - return FEBLEND_MODE_NORMAL; - if (value == "multiply") - return FEBLEND_MODE_MULTIPLY; - if (value == "screen") - return FEBLEND_MODE_SCREEN; - if (value == "darken") - return FEBLEND_MODE_DARKEN; - if (value == "lighten") - return FEBLEND_MODE_LIGHTEN; - return FEBLEND_MODE_UNKNOWN; } }; class SVGFEBlendElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEBlendElement> create(const QualifiedName&, Document&); + static Ref<SVGFEBlendElement> create(const QualifiedName&, Document&); private: SVGFEBlendElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEBlendElement) DECLARE_ANIMATED_STRING(In1, in1) DECLARE_ANIMATED_STRING(In2, in2) - DECLARE_ANIMATED_ENUMERATION(Mode, mode, BlendModeType) + DECLARE_ANIMATED_ENUMERATION(Mode, mode, BlendMode) END_DECLARE_ANIMATED_PROPERTIES }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEBlendElement.idl b/Source/WebCore/svg/SVGFEBlendElement.idl index 48334e1b4..42e7b7335 100644 --- a/Source/WebCore/svg/SVGFEBlendElement.idl +++ b/Source/WebCore/svg/SVGFEBlendElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG&FILTERS, DoNotCheckConstants ] interface SVGFEBlendElement : SVGElement { // Blend Mode Types diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp index be93ae0c6..841f4faaa 100644 --- a/Source/WebCore/svg/SVGFEColorMatrixElement.cpp +++ b/Source/WebCore/svg/SVGFEColorMatrixElement.cpp @@ -19,13 +19,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEColorMatrixElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" @@ -51,31 +47,15 @@ inline SVGFEColorMatrixElement::SVGFEColorMatrixElement(const QualifiedName& tag registerAnimatedPropertiesForSVGFEColorMatrixElement(); } -PassRefPtr<SVGFEColorMatrixElement> SVGFEColorMatrixElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFEColorMatrixElement(tagName, document)); -} - -bool SVGFEColorMatrixElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFEColorMatrixElement> SVGFEColorMatrixElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::typeAttr); - supportedAttributes.add(SVGNames::valuesAttr); - supportedAttributes.add(SVGNames::inAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFEColorMatrixElement(tagName, document)); } void SVGFEColorMatrixElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::typeAttr) { - ColorMatrixType propertyValue = SVGPropertyTraits<ColorMatrixType>::fromString(value); + auto propertyValue = SVGPropertyTraits<ColorMatrixType>::fromString(value); if (propertyValue > 0) setTypeBaseValue(propertyValue); return; @@ -87,14 +67,14 @@ void SVGFEColorMatrixElement::parseAttribute(const QualifiedName& name, const At } if (name == SVGNames::valuesAttr) { - SVGNumberList newList; + SVGNumberListValues newList; newList.parse(value); detachAnimatedValuesListWrappers(newList.size()); setValuesBaseValue(newList); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -111,32 +91,27 @@ bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, con void SVGFEColorMatrixElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::typeAttr || attrName == SVGNames::valuesAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } if (attrName == SVGNames::inAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEColorMatrixElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEColorMatrixElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; Vector<float> filterValues; ColorMatrixType filterType = type(); @@ -164,14 +139,12 @@ PassRefPtr<FilterEffect> SVGFEColorMatrixElement::build(SVGFilterBuilder* filter if ((filterType == FECOLORMATRIX_TYPE_MATRIX && size != 20) || (filterType == FECOLORMATRIX_TYPE_HUEROTATE && size != 1) || (filterType == FECOLORMATRIX_TYPE_SATURATE && size != 1)) - return 0; + return nullptr; } RefPtr<FilterEffect> effect = FEColorMatrix::create(filter, filterType, filterValues); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.h b/Source/WebCore/svg/SVGFEColorMatrixElement.h index 72167fc1d..1c2254dae 100644 --- a/Source/WebCore/svg/SVGFEColorMatrixElement.h +++ b/Source/WebCore/svg/SVGFEColorMatrixElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEColorMatrixElement_h -#define SVGFEColorMatrixElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEColorMatrix.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedNumberList.h" @@ -39,13 +37,13 @@ struct SVGPropertyTraits<ColorMatrixType> { case FECOLORMATRIX_TYPE_UNKNOWN: return emptyString(); case FECOLORMATRIX_TYPE_MATRIX: - return "matrix"; + return ASCIILiteral("matrix"); case FECOLORMATRIX_TYPE_SATURATE: - return "saturate"; + return ASCIILiteral("saturate"); case FECOLORMATRIX_TYPE_HUEROTATE: - return "hueRotate"; + return ASCIILiteral("hueRotate"); case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: - return "luminanceToAlpha"; + return ASCIILiteral("luminanceToAlpha"); } ASSERT_NOT_REACHED(); @@ -68,16 +66,15 @@ struct SVGPropertyTraits<ColorMatrixType> { class SVGFEColorMatrixElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEColorMatrixElement> create(const QualifiedName&, Document&); + static Ref<SVGFEColorMatrixElement> create(const QualifiedName&, Document&); private: SVGFEColorMatrixElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEColorMatrixElement) DECLARE_ANIMATED_STRING(In1, in1) @@ -87,6 +84,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEColorMatrixElement.idl b/Source/WebCore/svg/SVGFEColorMatrixElement.idl index fe2de5066..6dcbd5c3e 100644 --- a/Source/WebCore/svg/SVGFEColorMatrixElement.idl +++ b/Source/WebCore/svg/SVGFEColorMatrixElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG&FILTERS, DoNotCheckConstants ] interface SVGFEColorMatrixElement : SVGElement { // Color Matrix Types diff --git a/Source/WebCore/svg/SVGFEComponentTransferElement.cpp b/Source/WebCore/svg/SVGFEComponentTransferElement.cpp index 3e493fe63..5c1d2503c 100644 --- a/Source/WebCore/svg/SVGFEComponentTransferElement.cpp +++ b/Source/WebCore/svg/SVGFEComponentTransferElement.cpp @@ -19,11 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEComponentTransferElement.h" -#include "Attr.h" #include "ElementIterator.h" #include "FilterEffect.h" #include "SVGFEFuncAElement.h" @@ -50,35 +47,22 @@ inline SVGFEComponentTransferElement::SVGFEComponentTransferElement(const Qualif registerAnimatedPropertiesForSVGFEComponentTransferElement(); } -PassRefPtr<SVGFEComponentTransferElement> SVGFEComponentTransferElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFEComponentTransferElement(tagName, document)); -} - -bool SVGFEComponentTransferElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFEComponentTransferElement> SVGFEComponentTransferElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - supportedAttributes.add(SVGNames::inAttr); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFEComponentTransferElement(tagName, document)); } void SVGFEComponentTransferElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::inAttr) { setIn1BaseValue(value); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } -PassRefPtr<FilterEffect> SVGFEComponentTransferElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEComponentTransferElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); @@ -91,21 +75,19 @@ PassRefPtr<FilterEffect> SVGFEComponentTransferElement::build(SVGFilterBuilder* ComponentTransferFunction alpha; for (auto& child : childrenOfType<SVGElement>(*this)) { - if (isSVGFEFuncRElement(child)) - red = toSVGFEFuncRElement(child).transferFunction(); - else if (isSVGFEFuncGElement(child)) - green = toSVGFEFuncGElement(child).transferFunction(); - else if (isSVGFEFuncBElement(child)) - blue = toSVGFEFuncBElement(child).transferFunction(); - else if (isSVGFEFuncAElement(child)) - alpha = toSVGFEFuncAElement(child).transferFunction(); + if (is<SVGFEFuncRElement>(child)) + red = downcast<SVGFEFuncRElement>(child).transferFunction(); + else if (is<SVGFEFuncGElement>(child)) + green = downcast<SVGFEFuncGElement>(child).transferFunction(); + else if (is<SVGFEFuncBElement>(child)) + blue = downcast<SVGFEFuncBElement>(child).transferFunction(); + else if (is<SVGFEFuncAElement>(child)) + alpha = downcast<SVGFEFuncAElement>(child).transferFunction(); } RefPtr<FilterEffect> effect = FEComponentTransfer::create(filter, red, green, blue, alpha); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } - -#endif diff --git a/Source/WebCore/svg/SVGFEComponentTransferElement.h b/Source/WebCore/svg/SVGFEComponentTransferElement.h index 0a27ac7dc..a38222311 100644 --- a/Source/WebCore/svg/SVGFEComponentTransferElement.h +++ b/Source/WebCore/svg/SVGFEComponentTransferElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEComponentTransferElement_h -#define SVGFEComponentTransferElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEComponentTransfer.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -29,15 +27,14 @@ namespace WebCore { class SVGFEComponentTransferElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEComponentTransferElement> create(const QualifiedName&, Document&); + static Ref<SVGFEComponentTransferElement> create(const QualifiedName&, Document&); private: SVGFEComponentTransferElement(const QualifiedName&, Document&); // FIXME: svgAttributeChanged missing. - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEComponentTransferElement) DECLARE_ANIMATED_STRING(In1, in1) @@ -45,6 +42,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEComponentTransferElement.idl b/Source/WebCore/svg/SVGFEComponentTransferElement.idl index 84fe9388e..2821dc4f7 100644 --- a/Source/WebCore/svg/SVGFEComponentTransferElement.idl +++ b/Source/WebCore/svg/SVGFEComponentTransferElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEComponentTransferElement : SVGElement { +interface SVGFEComponentTransferElement : SVGElement { readonly attribute SVGAnimatedString in1; }; diff --git a/Source/WebCore/svg/SVGFECompositeElement.cpp b/Source/WebCore/svg/SVGFECompositeElement.cpp index 60e79266a..cd3d5c61b 100644 --- a/Source/WebCore/svg/SVGFECompositeElement.cpp +++ b/Source/WebCore/svg/SVGFECompositeElement.cpp @@ -19,13 +19,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFECompositeElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" @@ -59,33 +55,13 @@ inline SVGFECompositeElement::SVGFECompositeElement(const QualifiedName& tagName registerAnimatedPropertiesForSVGFECompositeElement(); } -PassRefPtr<SVGFECompositeElement> SVGFECompositeElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFECompositeElement(tagName, document)); -} - -bool SVGFECompositeElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFECompositeElement> SVGFECompositeElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::in2Attr); - supportedAttributes.add(SVGNames::operatorAttr); - supportedAttributes.add(SVGNames::k1Attr); - supportedAttributes.add(SVGNames::k2Attr); - supportedAttributes.add(SVGNames::k3Attr); - supportedAttributes.add(SVGNames::k4Attr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFECompositeElement(tagName, document)); } void SVGFECompositeElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::operatorAttr) { CompositeOperationType propertyValue = SVGPropertyTraits<CompositeOperationType>::fromString(value); if (propertyValue > 0) @@ -123,7 +99,7 @@ void SVGFECompositeElement::parseAttribute(const QualifiedName& name, const Atom return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -147,46 +123,35 @@ bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::operatorAttr - || attrName == SVGNames::k1Attr - || attrName == SVGNames::k2Attr - || attrName == SVGNames::k3Attr - || attrName == SVGNames::k4Attr) { + if (attrName == SVGNames::operatorAttr || attrName == SVGNames::k1Attr || attrName == SVGNames::k2Attr || attrName == SVGNames::k3Attr || attrName == SVGNames::k4Attr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFECompositeElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFECompositeElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); FilterEffect* input2 = filterBuilder->getEffectById(in2()); if (!input1 || !input2) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FEComposite::create(filter, svgOperator(), k1(), k2(), k3(), k4()); FilterEffectVector& inputEffects = effect->inputEffects(); inputEffects.reserveCapacity(2); inputEffects.append(input1); inputEffects.append(input2); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFECompositeElement.h b/Source/WebCore/svg/SVGFECompositeElement.h index f43dbd44e..ed08f0f33 100644 --- a/Source/WebCore/svg/SVGFECompositeElement.h +++ b/Source/WebCore/svg/SVGFECompositeElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFECompositeElement_h -#define SVGFECompositeElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEComposite.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedNumber.h" @@ -30,8 +28,11 @@ namespace WebCore { template<> +inline unsigned SVGIDLEnumLimits<CompositeOperationType>::highestExposedEnumValue() { return FECOMPOSITE_OPERATOR_ARITHMETIC; } + +template<> struct SVGPropertyTraits<CompositeOperationType> { - static unsigned highestEnumValue() { return FECOMPOSITE_OPERATOR_ARITHMETIC; } + static unsigned highestEnumValue() { return FECOMPOSITE_OPERATOR_LIGHTER; } static String toString(CompositeOperationType type) { @@ -39,17 +40,19 @@ struct SVGPropertyTraits<CompositeOperationType> { case FECOMPOSITE_OPERATOR_UNKNOWN: return emptyString(); case FECOMPOSITE_OPERATOR_OVER: - return "over"; + return ASCIILiteral("over"); case FECOMPOSITE_OPERATOR_IN: - return "in"; + return ASCIILiteral("in"); case FECOMPOSITE_OPERATOR_OUT: - return "out"; + return ASCIILiteral("out"); case FECOMPOSITE_OPERATOR_ATOP: - return "atop"; + return ASCIILiteral("atop"); case FECOMPOSITE_OPERATOR_XOR: - return "xor"; + return ASCIILiteral("xor"); case FECOMPOSITE_OPERATOR_ARITHMETIC: - return "arithmetic"; + return ASCIILiteral("arithmetic"); + case FECOMPOSITE_OPERATOR_LIGHTER: + return ASCIILiteral("lighter"); } ASSERT_NOT_REACHED(); @@ -70,22 +73,23 @@ struct SVGPropertyTraits<CompositeOperationType> { return FECOMPOSITE_OPERATOR_XOR; if (value == "arithmetic") return FECOMPOSITE_OPERATOR_ARITHMETIC; + if (value == "lighter") + return FECOMPOSITE_OPERATOR_LIGHTER; return FECOMPOSITE_OPERATOR_UNKNOWN; } }; class SVGFECompositeElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFECompositeElement> create(const QualifiedName&, Document&); + static Ref<SVGFECompositeElement> create(const QualifiedName&, Document&); private: SVGFECompositeElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFECompositeElement) DECLARE_ANIMATED_STRING(In1, in1) @@ -99,6 +103,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFECompositeElement.idl b/Source/WebCore/svg/SVGFECompositeElement.idl index 802269805..53a9492e2 100644 --- a/Source/WebCore/svg/SVGFECompositeElement.idl +++ b/Source/WebCore/svg/SVGFECompositeElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG&FILTERS, DoNotCheckConstants ] interface SVGFECompositeElement : SVGElement { // Composite Operators diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp index 241ef2afb..9cf28ab75 100644 --- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp +++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp @@ -18,18 +18,15 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEConvolveMatrixElement.h" -#include "Attr.h" #include "FilterEffect.h" #include "FloatPoint.h" #include "IntPoint.h" #include "IntSize.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" +#include "SVGNumberListValues.h" #include "SVGParserUtilities.h" namespace WebCore { @@ -72,60 +69,37 @@ inline SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement(const QualifiedNam registerAnimatedPropertiesForSVGFEConvolveMatrixElement(); } -PassRefPtr<SVGFEConvolveMatrixElement> SVGFEConvolveMatrixElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEConvolveMatrixElement> SVGFEConvolveMatrixElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEConvolveMatrixElement(tagName, document)); + return adoptRef(*new SVGFEConvolveMatrixElement(tagName, document)); } const AtomicString& SVGFEConvolveMatrixElement::kernelUnitLengthXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFEConvolveMatrixElement::kernelUnitLengthYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFEConvolveMatrixElement::orderXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrderX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGOrderX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFEConvolveMatrixElement::orderYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrderY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGOrderY", AtomicString::ConstructFromLiteral); return s_identifier; } -bool SVGFEConvolveMatrixElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::orderAttr); - supportedAttributes.add(SVGNames::kernelMatrixAttr); - supportedAttributes.add(SVGNames::edgeModeAttr); - supportedAttributes.add(SVGNames::divisorAttr); - supportedAttributes.add(SVGNames::biasAttr); - supportedAttributes.add(SVGNames::targetXAttr); - supportedAttributes.add(SVGNames::targetYAttr); - supportedAttributes.add(SVGNames::kernelUnitLengthAttr); - supportedAttributes.add(SVGNames::preserveAlphaAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::inAttr) { setIn1BaseValue(value); return; @@ -137,9 +111,7 @@ void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const setOrderXBaseValue(x); setOrderYBaseValue(y); } else - document().accessSVGExtensions()->reportWarning( - "feConvolveMatrix: problem parsing order=\"" + value - + "\". Filtered element will not be displayed."); + document().accessSVGExtensions().reportWarning("feConvolveMatrix: problem parsing order=\"" + value + "\". Filtered element will not be displayed."); return; } @@ -148,14 +120,12 @@ void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const if (propertyValue > 0) setEdgeModeBaseValue(propertyValue); else - document().accessSVGExtensions()->reportWarning( - "feConvolveMatrix: problem parsing edgeMode=\"" + value - + "\". Filtered element will not be displayed."); + document().accessSVGExtensions().reportWarning("feConvolveMatrix: problem parsing edgeMode=\"" + value + "\". Filtered element will not be displayed."); return; } if (name == SVGNames::kernelMatrixAttr) { - SVGNumberList newList; + SVGNumberListValues newList; newList.parse(value); detachAnimatedKernelMatrixListWrappers(newList.size()); setKernelMatrixBaseValue(newList); @@ -167,9 +137,7 @@ void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const if (divisor) setDivisorBaseValue(divisor); else - document().accessSVGExtensions()->reportWarning( - "feConvolveMatrix: problem parsing divisor=\"" + value - + "\". Filtered element will not be displayed."); + document().accessSVGExtensions().reportWarning("feConvolveMatrix: problem parsing divisor=\"" + value + "\". Filtered element will not be displayed."); return; } @@ -194,9 +162,7 @@ void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const setKernelUnitLengthXBaseValue(x); setKernelUnitLengthYBaseValue(y); } else - document().accessSVGExtensions()->reportWarning( - "feConvolveMatrix: problem parsing kernelUnitLength=\"" + value - + "\". Filtered element will not be displayed."); + document().accessSVGExtensions().reportWarning("feConvolveMatrix: problem parsing kernelUnitLength=\"" + value + "\". Filtered element will not be displayed."); return; } @@ -206,13 +172,11 @@ void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const else if (value == "false") setPreserveAlphaBaseValue(false); else - document().accessSVGExtensions()->reportWarning( - "feConvolveMatrix: problem parsing preserveAlphaAttr=\"" + value - + "\". Filtered element will not be displayed."); + document().accessSVGExtensions().reportWarning("feConvolveMatrix: problem parsing preserveAlphaAttr=\"" + value + "\". Filtered element will not be displayed."); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFEConvolveMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -253,40 +217,27 @@ void SVGFEConvolveMatrixElement::setKernelUnitLength(float x, float y) void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::edgeModeAttr - || attrName == SVGNames::divisorAttr - || attrName == SVGNames::biasAttr - || attrName == SVGNames::targetXAttr - || attrName == SVGNames::targetYAttr - || attrName == SVGNames::kernelUnitLengthAttr - || attrName == SVGNames::preserveAlphaAttr) { + if (attrName == SVGNames::edgeModeAttr || attrName == SVGNames::divisorAttr || attrName == SVGNames::biasAttr || attrName == SVGNames::targetXAttr || attrName == SVGNames::targetYAttr || attrName == SVGNames::kernelUnitLengthAttr || attrName == SVGNames::preserveAlphaAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } - if (attrName == SVGNames::inAttr - || attrName == SVGNames::orderAttr - || attrName == SVGNames::kernelMatrixAttr) { + if (attrName == SVGNames::inAttr || attrName == SVGNames::orderAttr || attrName == SVGNames::kernelMatrixAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { - FilterEffect* input1 = filterBuilder->getEffectById(in1()); + auto* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; int orderXValue = orderX(); int orderYValue = orderY(); @@ -296,22 +247,22 @@ PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* fil } // Spec says order must be > 0. Bail if it is not. if (orderXValue < 1 || orderYValue < 1) - return 0; - SVGNumberList& kernelMatrix = this->kernelMatrix(); + return nullptr; + auto& kernelMatrix = this->kernelMatrix(); int kernelMatrixSize = kernelMatrix.size(); // The spec says this is a requirement, and should bail out if fails if (orderXValue * orderYValue != kernelMatrixSize) - return 0; + return nullptr; int targetXValue = targetX(); int targetYValue = targetY(); if (hasAttribute(SVGNames::targetXAttr) && (targetXValue < 0 || targetXValue >= orderXValue)) - return 0; + return nullptr; // The spec says the default value is: targetX = floor ( orderX / 2 )) if (!hasAttribute(SVGNames::targetXAttr)) targetXValue = static_cast<int>(floorf(orderXValue / 2)); if (hasAttribute(SVGNames::targetYAttr) && (targetYValue < 0 || targetYValue >= orderYValue)) - return 0; + return nullptr; // The spec says the default value is: targetY = floor ( orderY / 2 )) if (!hasAttribute(SVGNames::targetYAttr)) targetYValue = static_cast<int>(floorf(orderYValue / 2)); @@ -324,11 +275,11 @@ PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* fil kernelUnitLengthYValue = 1; } if (kernelUnitLengthXValue <= 0 || kernelUnitLengthYValue <= 0) - return 0; + return nullptr; float divisorValue = divisor(); if (hasAttribute(SVGNames::divisorAttr) && !divisorValue) - return 0; + return nullptr; if (!hasAttribute(SVGNames::divisorAttr)) { for (int i = 0; i < kernelMatrixSize; ++i) divisorValue += kernelMatrix.at(i); @@ -336,14 +287,9 @@ PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* fil divisorValue = 1; } - RefPtr<FilterEffect> effect = FEConvolveMatrix::create(filter, - IntSize(orderXValue, orderYValue), divisorValue, - bias(), IntPoint(targetXValue, targetYValue), edgeMode(), - FloatPoint(kernelUnitLengthXValue, kernelUnitLengthYValue), preserveAlpha(), kernelMatrix); + auto effect = FEConvolveMatrix::create(filter, IntSize(orderXValue, orderYValue), divisorValue, bias(), IntPoint(targetXValue, targetYValue), edgeMode(), FloatPoint(kernelUnitLengthXValue, kernelUnitLengthYValue), preserveAlpha(), kernelMatrix); effect->inputEffects().append(input1); - return effect.release(); + return WTFMove(effect); } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h index 9024536d7..8198456bb 100644 --- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.h +++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEConvolveMatrixElement_h -#define SVGFEConvolveMatrixElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEConvolveMatrix.h" #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" @@ -41,11 +39,11 @@ struct SVGPropertyTraits<EdgeModeType> { case EDGEMODE_UNKNOWN: return emptyString(); case EDGEMODE_DUPLICATE: - return "duplicate"; + return ASCIILiteral("duplicate"); case EDGEMODE_WRAP: - return "wrap"; + return ASCIILiteral("wrap"); case EDGEMODE_NONE: - return "none"; + return ASCIILiteral("none"); } ASSERT_NOT_REACHED(); @@ -66,7 +64,7 @@ struct SVGPropertyTraits<EdgeModeType> { class SVGFEConvolveMatrixElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEConvolveMatrixElement> create(const QualifiedName&, Document&); + static Ref<SVGFEConvolveMatrixElement> create(const QualifiedName&, Document&); void setOrder(float orderX, float orderY); void setKernelUnitLength(float kernelUnitLengthX, float kernelUnitLengthY); @@ -74,11 +72,10 @@ public: private: SVGFEConvolveMatrixElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; static const AtomicString& orderXIdentifier(); static const AtomicString& orderYIdentifier(); @@ -102,6 +99,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEConvolveMatrixElement.idl b/Source/WebCore/svg/SVGFEConvolveMatrixElement.idl index 275582a2f..4b09c28ac 100644 --- a/Source/WebCore/svg/SVGFEConvolveMatrixElement.idl +++ b/Source/WebCore/svg/SVGFEConvolveMatrixElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG&FILTERS, DoNotCheckConstants ] interface SVGFEConvolveMatrixElement : SVGElement { // Edge Mode Values diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp index d8e2d1688..75f24c4e2 100644 --- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp +++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp @@ -18,16 +18,11 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEDiffuseLightingElement.h" -#include "Attr.h" #include "FEDiffuseLighting.h" #include "FilterEffect.h" #include "RenderStyle.h" -#include "SVGColor.h" -#include "SVGElementInstance.h" #include "SVGFELightElement.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" @@ -60,43 +55,25 @@ inline SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(const QualifiedN registerAnimatedPropertiesForSVGFEDiffuseLightingElement(); } -PassRefPtr<SVGFEDiffuseLightingElement> SVGFEDiffuseLightingElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEDiffuseLightingElement> SVGFEDiffuseLightingElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEDiffuseLightingElement(tagName, document)); + return adoptRef(*new SVGFEDiffuseLightingElement(tagName, document)); } const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral); return s_identifier; } -bool SVGFEDiffuseLightingElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::diffuseConstantAttr); - supportedAttributes.add(SVGNames::surfaceScaleAttr); - supportedAttributes.add(SVGNames::kernelUnitLengthAttr); - supportedAttributes.add(SVGNames::lighting_colorAttr); // Even though it's a SVG-CSS property, we override its handling here. - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFEDiffuseLightingElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name) || name == SVGNames::lighting_colorAttr) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::inAttr) { setIn1BaseValue(value); return; @@ -121,7 +98,7 @@ void SVGFEDiffuseLightingElement::parseAttribute(const QualifiedName& name, cons return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -170,27 +147,19 @@ bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::surfaceScaleAttr - || attrName == SVGNames::diffuseConstantAttr - || attrName == SVGNames::kernelUnitLengthAttr - || attrName == SVGNames::lighting_colorAttr) { + if (attrName == SVGNames::surfaceScaleAttr || attrName == SVGNames::diffuseConstantAttr || attrName == SVGNames::kernelUnitLengthAttr || attrName == SVGNames::lighting_colorAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } if (attrName == SVGNames::inAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName) @@ -202,29 +171,27 @@ void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightE primitiveAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEDiffuseLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEDiffuseLightingElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; - RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this); + auto lightSource = SVGFELightElement::findLightSource(this); if (!lightSource) - return 0; + return nullptr; RenderObject* renderer = this->renderer(); if (!renderer) - return 0; - - Color color = renderer->style().svgStyle().lightingColor(); + return nullptr; + + const Color& color = renderer->style().svgStyle().lightingColor(); RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(), - kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release()); + kernelUnitLengthX(), kernelUnitLengthY(), WTFMove(lightSource)); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h index 29cfd4f13..3b3733b05 100644 --- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.h +++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.h @@ -19,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEDiffuseLightingElement_h -#define SVGFEDiffuseLightingElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFELightElement.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -33,17 +31,16 @@ class SVGColor; class SVGFEDiffuseLightingElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEDiffuseLightingElement> create(const QualifiedName&, Document&); + static Ref<SVGFEDiffuseLightingElement> create(const QualifiedName&, Document&); void lightElementAttributeChanged(const SVGFELightElement*, const QualifiedName&); private: SVGFEDiffuseLightingElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; static const AtomicString& kernelUnitLengthXIdentifier(); static const AtomicString& kernelUnitLengthYIdentifier(); @@ -58,6 +55,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEDiffuseLightingElement.idl b/Source/WebCore/svg/SVGFEDiffuseLightingElement.idl index f5d2ecc06..19862884a 100644 --- a/Source/WebCore/svg/SVGFEDiffuseLightingElement.idl +++ b/Source/WebCore/svg/SVGFEDiffuseLightingElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEDiffuseLightingElement : SVGElement { +interface SVGFEDiffuseLightingElement : SVGElement { readonly attribute SVGAnimatedString in1; readonly attribute SVGAnimatedNumber surfaceScale; readonly attribute SVGAnimatedNumber diffuseConstant; diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp index 95eb4cd88..e989b9ce3 100644 --- a/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp +++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.cpp @@ -18,13 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEDisplacementMapElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" @@ -55,40 +51,22 @@ inline SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(const QualifiedN registerAnimatedPropertiesForSVGFEDisplacementMapElement(); } -PassRefPtr<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFEDisplacementMapElement(tagName, document)); -} - -bool SVGFEDisplacementMapElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::in2Attr); - supportedAttributes.add(SVGNames::xChannelSelectorAttr); - supportedAttributes.add(SVGNames::yChannelSelectorAttr); - supportedAttributes.add(SVGNames::scaleAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFEDisplacementMapElement(tagName, document)); } void SVGFEDisplacementMapElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::xChannelSelectorAttr) { - ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value); + auto propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value); if (propertyValue > 0) setXChannelSelectorBaseValue(propertyValue); return; } if (name == SVGNames::yChannelSelectorAttr) { - ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value); + auto propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value); if (propertyValue > 0) setYChannelSelectorBaseValue(propertyValue); return; @@ -109,7 +87,7 @@ void SVGFEDisplacementMapElement::parseAttribute(const QualifiedName& name, cons return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -128,42 +106,35 @@ bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEDisplacementMapElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEDisplacementMapElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); FilterEffect* input2 = filterBuilder->getEffectById(in2()); if (!input1 || !input2) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, xChannelSelector(), yChannelSelector(), scale()); FilterEffectVector& inputEffects = effect->inputEffects(); inputEffects.reserveCapacity(2); inputEffects.append(input1); inputEffects.append(input2); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.h b/Source/WebCore/svg/SVGFEDisplacementMapElement.h index 0699511fd..e29cdc611 100644 --- a/Source/WebCore/svg/SVGFEDisplacementMapElement.h +++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEDisplacementMapElement_h -#define SVGFEDisplacementMapElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEDisplacementMap.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedNumber.h" @@ -38,13 +36,13 @@ struct SVGPropertyTraits<ChannelSelectorType> { case CHANNEL_UNKNOWN: return emptyString(); case CHANNEL_R: - return "R"; + return ASCIILiteral("R"); case CHANNEL_G: - return "G"; + return ASCIILiteral("G"); case CHANNEL_B: - return "B"; + return ASCIILiteral("B"); case CHANNEL_A: - return "A"; + return ASCIILiteral("A"); } ASSERT_NOT_REACHED(); @@ -67,18 +65,17 @@ struct SVGPropertyTraits<ChannelSelectorType> { class SVGFEDisplacementMapElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEDisplacementMapElement> create(const QualifiedName&, Document&); + static Ref<SVGFEDisplacementMapElement> create(const QualifiedName&, Document&); static ChannelSelectorType stringToChannel(const String&); private: SVGFEDisplacementMapElement(const QualifiedName& tagName, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEDisplacementMapElement) DECLARE_ANIMATED_STRING(In1, in1) @@ -90,6 +87,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGFEDisplacementMapElement_h diff --git a/Source/WebCore/svg/SVGFEDisplacementMapElement.idl b/Source/WebCore/svg/SVGFEDisplacementMapElement.idl index e9efab8a0..a406eb7b0 100644 --- a/Source/WebCore/svg/SVGFEDisplacementMapElement.idl +++ b/Source/WebCore/svg/SVGFEDisplacementMapElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG&FILTERS, DoNotCheckConstants ] interface SVGFEDisplacementMapElement : SVGElement { // Channel Selectors diff --git a/Source/WebCore/svg/SVGFEDistantLightElement.cpp b/Source/WebCore/svg/SVGFEDistantLightElement.cpp index 4a823bc07..5cea1492d 100644 --- a/Source/WebCore/svg/SVGFEDistantLightElement.cpp +++ b/Source/WebCore/svg/SVGFEDistantLightElement.cpp @@ -18,12 +18,10 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEDistantLightElement.h" -#include "SVGNames.h" #include "DistantLightSource.h" +#include "SVGNames.h" namespace WebCore { @@ -33,16 +31,14 @@ inline SVGFEDistantLightElement::SVGFEDistantLightElement(const QualifiedName& t ASSERT(hasTagName(SVGNames::feDistantLightTag)); } -PassRefPtr<SVGFEDistantLightElement> SVGFEDistantLightElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEDistantLightElement> SVGFEDistantLightElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEDistantLightElement(tagName, document)); + return adoptRef(*new SVGFEDistantLightElement(tagName, document)); } -PassRefPtr<LightSource> SVGFEDistantLightElement::lightSource() const +Ref<LightSource> SVGFEDistantLightElement::lightSource() const { return DistantLightSource::create(azimuth(), elevation()); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEDistantLightElement.h b/Source/WebCore/svg/SVGFEDistantLightElement.h index f0635f57b..2ac08c372 100644 --- a/Source/WebCore/svg/SVGFEDistantLightElement.h +++ b/Source/WebCore/svg/SVGFEDistantLightElement.h @@ -17,27 +17,20 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEDistantLightElement_h -#define SVGFEDistantLightElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFELightElement.h" namespace WebCore { class SVGFEDistantLightElement final : public SVGFELightElement { public: - static PassRefPtr<SVGFEDistantLightElement> create(const QualifiedName&, Document&); + static Ref<SVGFEDistantLightElement> create(const QualifiedName&, Document&); private: SVGFEDistantLightElement(const QualifiedName&, Document&); - virtual PassRefPtr<LightSource> lightSource() const override; + Ref<LightSource> lightSource() const override; }; -NODE_TYPE_CASTS(SVGFEDistantLightElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEDistantLightElement.idl b/Source/WebCore/svg/SVGFEDistantLightElement.idl index e62b8f5a6..dd24f21aa 100644 --- a/Source/WebCore/svg/SVGFEDistantLightElement.idl +++ b/Source/WebCore/svg/SVGFEDistantLightElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEDistantLightElement : SVGElement { +interface SVGFEDistantLightElement : SVGElement { readonly attribute SVGAnimatedNumber azimuth; readonly attribute SVGAnimatedNumber elevation; }; diff --git a/Source/WebCore/svg/SVGFEDropShadowElement.cpp b/Source/WebCore/svg/SVGFEDropShadowElement.cpp index 3da5c25d3..31935e170 100644 --- a/Source/WebCore/svg/SVGFEDropShadowElement.cpp +++ b/Source/WebCore/svg/SVGFEDropShadowElement.cpp @@ -18,13 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEDropShadowElement.h" -#include "Attribute.h" #include "RenderStyle.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" #include "SVGParserUtilities.h" @@ -59,20 +55,20 @@ inline SVGFEDropShadowElement::SVGFEDropShadowElement(const QualifiedName& tagNa registerAnimatedPropertiesForSVGFEDropShadowElement(); } -PassRefPtr<SVGFEDropShadowElement> SVGFEDropShadowElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEDropShadowElement> SVGFEDropShadowElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEDropShadowElement(tagName, document)); + return adoptRef(*new SVGFEDropShadowElement(tagName, document)); } const AtomicString& SVGFEDropShadowElement::stdDeviationXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGStdDeviationX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFEDropShadowElement::stdDeviationYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGStdDeviationY", AtomicString::ConstructFromLiteral); return s_identifier; } @@ -83,25 +79,8 @@ void SVGFEDropShadowElement::setStdDeviation(float x, float y) invalidate(); } -bool SVGFEDropShadowElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::dxAttr); - supportedAttributes.add(SVGNames::dyAttr); - supportedAttributes.add(SVGNames::stdDeviationAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFEDropShadowElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::stdDeviationAttr) { float x, y; if (parseNumberOptionalNumber(value, x, y)) { @@ -126,52 +105,41 @@ void SVGFEDropShadowElement::parseAttribute(const QualifiedName& name, const Ato return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } void SVGFEDropShadowElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::inAttr - || attrName == SVGNames::stdDeviationAttr - || attrName == SVGNames::dxAttr - || attrName == SVGNames::dyAttr) { + if (attrName == SVGNames::inAttr || attrName == SVGNames::stdDeviationAttr || attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEDropShadowElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEDropShadowElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { RenderObject* renderer = this->renderer(); if (!renderer) - return 0; + return nullptr; if (stdDeviationX() < 0 || stdDeviationY() < 0) - return 0; + return nullptr; const SVGRenderStyle& svgStyle = renderer->style().svgStyle(); - Color color = svgStyle.floodColor(); + const Color& color = svgStyle.floodColor(); float opacity = svgStyle.floodOpacity(); FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FEDropShadow::create(filter, stdDeviationX(), stdDeviationY(), dx(), dy(), color, opacity); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEDropShadowElement.h b/Source/WebCore/svg/SVGFEDropShadowElement.h index e440c7aae..da9cebfd0 100644 --- a/Source/WebCore/svg/SVGFEDropShadowElement.h +++ b/Source/WebCore/svg/SVGFEDropShadowElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEDropShadowElement_h -#define SVGFEDropShadowElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEDropShadow.h" #include "SVGAnimatedNumber.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -29,17 +27,16 @@ namespace WebCore { class SVGFEDropShadowElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEDropShadowElement> create(const QualifiedName&, Document&); + static Ref<SVGFEDropShadowElement> create(const QualifiedName&, Document&); void setStdDeviation(float stdDeviationX, float stdDeviationY); private: SVGFEDropShadowElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; static const AtomicString& stdDeviationXIdentifier(); static const AtomicString& stdDeviationYIdentifier(); @@ -54,6 +51,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEDropShadowElement.idl b/Source/WebCore/svg/SVGFEDropShadowElement.idl index 19e8b0a01..04bcdfbad 100644 --- a/Source/WebCore/svg/SVGFEDropShadowElement.idl +++ b/Source/WebCore/svg/SVGFEDropShadowElement.idl @@ -17,17 +17,15 @@ * Boston, MA 02110-1301, USA. */ -[ - Conditional=SVG&FILTERS, -] interface SVGFEDropShadowElement : SVGElement { +interface SVGFEDropShadowElement : SVGElement { readonly attribute SVGAnimatedString in1; readonly attribute SVGAnimatedNumber dx; readonly attribute SVGAnimatedNumber dy; readonly attribute SVGAnimatedNumber stdDeviationX; readonly attribute SVGAnimatedNumber stdDeviationY; - void setStdDeviation([Default=Undefined] optional float stdDeviationX, - [Default=Undefined] optional float stdDeviationY); + void setStdDeviation(optional unrestricted float stdDeviationX = NaN, + optional unrestricted float stdDeviationY = NaN); }; SVGFEDropShadowElement implements SVGFilterPrimitiveStandardAttributes; diff --git a/Source/WebCore/svg/SVGFEFloodElement.cpp b/Source/WebCore/svg/SVGFEFloodElement.cpp index 22e216a20..561694924 100644 --- a/Source/WebCore/svg/SVGFEFloodElement.cpp +++ b/Source/WebCore/svg/SVGFEFloodElement.cpp @@ -19,11 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEFloodElement.h" -#include "Attribute.h" #include "RenderStyle.h" #include "SVGNames.h" #include "SVGRenderStyle.h" @@ -36,12 +33,11 @@ inline SVGFEFloodElement::SVGFEFloodElement(const QualifiedName& tagName, Docume ASSERT(hasTagName(SVGNames::feFloodTag)); } -PassRefPtr<SVGFEFloodElement> SVGFEFloodElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEFloodElement> SVGFEFloodElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEFloodElement(tagName, document)); + return adoptRef(*new SVGFEFloodElement(tagName, document)); } - bool SVGFEFloodElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) { RenderObject* renderer = this->renderer(); @@ -58,20 +54,18 @@ bool SVGFEFloodElement::setFilterEffectAttribute(FilterEffect* effect, const Qua return false; } -PassRefPtr<FilterEffect> SVGFEFloodElement::build(SVGFilterBuilder*, Filter* filter) +RefPtr<FilterEffect> SVGFEFloodElement::build(SVGFilterBuilder*, Filter& filter) { RenderObject* renderer = this->renderer(); if (!renderer) - return 0; + return nullptr; const SVGRenderStyle& svgStyle = renderer->style().svgStyle(); - Color color = svgStyle.floodColor(); + const Color& color = svgStyle.floodColor(); float opacity = svgStyle.floodOpacity(); return FEFlood::create(filter, color, opacity); } } - -#endif // ENABLE(SVG) && ENABLE(FILTERS) diff --git a/Source/WebCore/svg/SVGFEFloodElement.h b/Source/WebCore/svg/SVGFEFloodElement.h index 0b33058cc..1c218ac6f 100644 --- a/Source/WebCore/svg/SVGFEFloodElement.h +++ b/Source/WebCore/svg/SVGFEFloodElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEFloodElement_h -#define SVGFEFloodElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEFlood.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -29,16 +27,13 @@ namespace WebCore { class SVGFEFloodElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEFloodElement> create(const QualifiedName&, Document&); + static Ref<SVGFEFloodElement> create(const QualifiedName&, Document&); private: SVGFEFloodElement(const QualifiedName&, Document&); - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) -#endif diff --git a/Source/WebCore/svg/SVGFEFloodElement.idl b/Source/WebCore/svg/SVGFEFloodElement.idl index bd5abc86e..9c8da6032 100644 --- a/Source/WebCore/svg/SVGFEFloodElement.idl +++ b/Source/WebCore/svg/SVGFEFloodElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEFloodElement : SVGElement { +interface SVGFEFloodElement : SVGElement { }; SVGFEFloodElement implements SVGFilterPrimitiveStandardAttributes; diff --git a/Source/WebCore/svg/SVGFEFuncAElement.cpp b/Source/WebCore/svg/SVGFEFuncAElement.cpp index 257555538..a30b315bc 100644 --- a/Source/WebCore/svg/SVGFEFuncAElement.cpp +++ b/Source/WebCore/svg/SVGFEFuncAElement.cpp @@ -19,9 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEFuncAElement.h" + #include "SVGNames.h" namespace WebCore { @@ -32,13 +31,11 @@ inline SVGFEFuncAElement::SVGFEFuncAElement(const QualifiedName& tagName, Docume ASSERT(hasTagName(SVGNames::feFuncATag)); } -PassRefPtr<SVGFEFuncAElement> SVGFEFuncAElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEFuncAElement> SVGFEFuncAElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEFuncAElement(tagName, document)); + return adoptRef(*new SVGFEFuncAElement(tagName, document)); } } -#endif // ENABLE(SVG) - // vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFEFuncAElement.h b/Source/WebCore/svg/SVGFEFuncAElement.h index b2ec58183..585623db5 100644 --- a/Source/WebCore/svg/SVGFEFuncAElement.h +++ b/Source/WebCore/svg/SVGFEFuncAElement.h @@ -18,25 +18,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEFuncAElement_h -#define SVGFEFuncAElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGComponentTransferFunctionElement.h" namespace WebCore { class SVGFEFuncAElement final : public SVGComponentTransferFunctionElement { public: - static PassRefPtr<SVGFEFuncAElement> create(const QualifiedName&, Document&); + static Ref<SVGFEFuncAElement> create(const QualifiedName&, Document&); private: SVGFEFuncAElement(const QualifiedName&, Document&); }; -NODE_TYPE_CASTS(SVGFEFuncAElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEFuncAElement.idl b/Source/WebCore/svg/SVGFEFuncAElement.idl index 4d78ecdc2..faab472a4 100644 --- a/Source/WebCore/svg/SVGFEFuncAElement.idl +++ b/Source/WebCore/svg/SVGFEFuncAElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEFuncAElement : SVGComponentTransferFunctionElement { +interface SVGFEFuncAElement : SVGComponentTransferFunctionElement { }; diff --git a/Source/WebCore/svg/SVGFEFuncBElement.cpp b/Source/WebCore/svg/SVGFEFuncBElement.cpp index 7d980b64a..e95e7a558 100644 --- a/Source/WebCore/svg/SVGFEFuncBElement.cpp +++ b/Source/WebCore/svg/SVGFEFuncBElement.cpp @@ -19,9 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEFuncBElement.h" + #include "SVGNames.h" namespace WebCore { @@ -32,13 +31,9 @@ inline SVGFEFuncBElement::SVGFEFuncBElement(const QualifiedName& tagName, Docume ASSERT(hasTagName(SVGNames::feFuncBTag)); } -PassRefPtr<SVGFEFuncBElement> SVGFEFuncBElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEFuncBElement> SVGFEFuncBElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEFuncBElement(tagName, document)); + return adoptRef(*new SVGFEFuncBElement(tagName, document)); } } - -#endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFEFuncBElement.h b/Source/WebCore/svg/SVGFEFuncBElement.h index 6964dbd4c..e93090fe0 100644 --- a/Source/WebCore/svg/SVGFEFuncBElement.h +++ b/Source/WebCore/svg/SVGFEFuncBElement.h @@ -18,25 +18,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEFuncBElement_h -#define SVGFEFuncBElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGComponentTransferFunctionElement.h" namespace WebCore { class SVGFEFuncBElement final : public SVGComponentTransferFunctionElement { public: - static PassRefPtr<SVGFEFuncBElement> create(const QualifiedName&, Document&); + static Ref<SVGFEFuncBElement> create(const QualifiedName&, Document&); private: SVGFEFuncBElement(const QualifiedName&, Document&); }; -NODE_TYPE_CASTS(SVGFEFuncBElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEFuncBElement.idl b/Source/WebCore/svg/SVGFEFuncBElement.idl index a14376019..69945cb6b 100644 --- a/Source/WebCore/svg/SVGFEFuncBElement.idl +++ b/Source/WebCore/svg/SVGFEFuncBElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEFuncBElement : SVGComponentTransferFunctionElement { +interface SVGFEFuncBElement : SVGComponentTransferFunctionElement { }; diff --git a/Source/WebCore/svg/SVGFEFuncGElement.cpp b/Source/WebCore/svg/SVGFEFuncGElement.cpp index c169214f1..208f0fffb 100644 --- a/Source/WebCore/svg/SVGFEFuncGElement.cpp +++ b/Source/WebCore/svg/SVGFEFuncGElement.cpp @@ -19,9 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEFuncGElement.h" + #include "SVGNames.h" namespace WebCore { @@ -32,13 +31,9 @@ inline SVGFEFuncGElement::SVGFEFuncGElement(const QualifiedName& tagName, Docume ASSERT(hasTagName(SVGNames::feFuncGTag)); } -PassRefPtr<SVGFEFuncGElement> SVGFEFuncGElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEFuncGElement> SVGFEFuncGElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEFuncGElement(tagName, document)); + return adoptRef(*new SVGFEFuncGElement(tagName, document)); } } - -#endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFEFuncGElement.h b/Source/WebCore/svg/SVGFEFuncGElement.h index b67abb4f5..0fb3ae05a 100644 --- a/Source/WebCore/svg/SVGFEFuncGElement.h +++ b/Source/WebCore/svg/SVGFEFuncGElement.h @@ -18,25 +18,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEFuncGElement_h -#define SVGFEFuncGElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGComponentTransferFunctionElement.h" namespace WebCore { class SVGFEFuncGElement final : public SVGComponentTransferFunctionElement { public: - static PassRefPtr<SVGFEFuncGElement> create(const QualifiedName&, Document&); + static Ref<SVGFEFuncGElement> create(const QualifiedName&, Document&); private: SVGFEFuncGElement(const QualifiedName&, Document&); }; -NODE_TYPE_CASTS(SVGFEFuncGElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEFuncGElement.idl b/Source/WebCore/svg/SVGFEFuncGElement.idl index 53c6e68ac..022e8d11f 100644 --- a/Source/WebCore/svg/SVGFEFuncGElement.idl +++ b/Source/WebCore/svg/SVGFEFuncGElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEFuncGElement : SVGComponentTransferFunctionElement { +interface SVGFEFuncGElement : SVGComponentTransferFunctionElement { }; diff --git a/Source/WebCore/svg/SVGFEFuncRElement.cpp b/Source/WebCore/svg/SVGFEFuncRElement.cpp index 04714fee4..38cbe338d 100644 --- a/Source/WebCore/svg/SVGFEFuncRElement.cpp +++ b/Source/WebCore/svg/SVGFEFuncRElement.cpp @@ -19,9 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEFuncRElement.h" + #include "SVGNames.h" namespace WebCore { @@ -32,13 +31,9 @@ inline SVGFEFuncRElement::SVGFEFuncRElement(const QualifiedName& tagName, Docume ASSERT(hasTagName(SVGNames::feFuncRTag)); } -PassRefPtr<SVGFEFuncRElement> SVGFEFuncRElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEFuncRElement> SVGFEFuncRElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEFuncRElement(tagName, document)); + return adoptRef(*new SVGFEFuncRElement(tagName, document)); } } - -#endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFEFuncRElement.h b/Source/WebCore/svg/SVGFEFuncRElement.h index b2d44ae90..abe7a488d 100644 --- a/Source/WebCore/svg/SVGFEFuncRElement.h +++ b/Source/WebCore/svg/SVGFEFuncRElement.h @@ -18,25 +18,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEFuncRElement_h -#define SVGFEFuncRElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGComponentTransferFunctionElement.h" namespace WebCore { class SVGFEFuncRElement final : public SVGComponentTransferFunctionElement { public: - static PassRefPtr<SVGFEFuncRElement> create(const QualifiedName&, Document&); + static Ref<SVGFEFuncRElement> create(const QualifiedName&, Document&); private: SVGFEFuncRElement(const QualifiedName&, Document&); }; -NODE_TYPE_CASTS(SVGFEFuncRElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEFuncRElement.idl b/Source/WebCore/svg/SVGFEFuncRElement.idl index 0f73b9a06..2391da1f4 100644 --- a/Source/WebCore/svg/SVGFEFuncRElement.idl +++ b/Source/WebCore/svg/SVGFEFuncRElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEFuncRElement : SVGComponentTransferFunctionElement { +interface SVGFEFuncRElement : SVGComponentTransferFunctionElement { }; diff --git a/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp b/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp index b58210726..7b21de836 100644 --- a/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp +++ b/Source/WebCore/svg/SVGFEGaussianBlurElement.cpp @@ -19,13 +19,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEGaussianBlurElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" #include "SVGParserUtilities.h" @@ -54,20 +50,20 @@ inline SVGFEGaussianBlurElement::SVGFEGaussianBlurElement(const QualifiedName& t registerAnimatedPropertiesForSVGFEGaussianBlurElement(); } -PassRefPtr<SVGFEGaussianBlurElement> SVGFEGaussianBlurElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEGaussianBlurElement> SVGFEGaussianBlurElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEGaussianBlurElement(tagName, document)); + return adoptRef(*new SVGFEGaussianBlurElement(tagName, document)); } const AtomicString& SVGFEGaussianBlurElement::stdDeviationXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGStdDeviationX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFEGaussianBlurElement::stdDeviationYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGStdDeviationY", AtomicString::ConstructFromLiteral); return s_identifier; } @@ -78,24 +74,8 @@ void SVGFEGaussianBlurElement::setStdDeviation(float x, float y) invalidate(); } -bool SVGFEGaussianBlurElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::stdDeviationAttr); - supportedAttributes.add(SVGNames::edgeModeAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFEGaussianBlurElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::stdDeviationAttr) { float x, y; if (parseNumberOptionalNumber(value, x, y)) { @@ -111,53 +91,41 @@ void SVGFEGaussianBlurElement::parseAttribute(const QualifiedName& name, const A } if (name == SVGNames::edgeModeAttr) { - EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value); + auto propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value); if (propertyValue > 0) setEdgeModeBaseValue(propertyValue); else - document().accessSVGExtensions()->reportWarning( - "feGaussianBlur: problem parsing edgeMode=\"" + value - + "\". Filtered element will not be displayed."); + document().accessSVGExtensions().reportWarning("feGaussianBlur: problem parsing edgeMode=\"" + value + "\". Filtered element will not be displayed."); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } void SVGFEGaussianBlurElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::inAttr - || attrName == SVGNames::stdDeviationAttr - || attrName == SVGNames::edgeModeAttr) { + if (attrName == SVGNames::inAttr || attrName == SVGNames::stdDeviationAttr || attrName == SVGNames::edgeModeAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEGaussianBlurElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEGaussianBlurElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; if (stdDeviationX() < 0 || stdDeviationY() < 0) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FEGaussianBlur::create(filter, stdDeviationX(), stdDeviationY(), edgeMode()); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEGaussianBlurElement.h b/Source/WebCore/svg/SVGFEGaussianBlurElement.h index 44261d485..d5b97cdfa 100644 --- a/Source/WebCore/svg/SVGFEGaussianBlurElement.h +++ b/Source/WebCore/svg/SVGFEGaussianBlurElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEGaussianBlurElement_h -#define SVGFEGaussianBlurElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEGaussianBlur.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedNumber.h" @@ -32,17 +30,16 @@ namespace WebCore { class SVGFEGaussianBlurElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEGaussianBlurElement> create(const QualifiedName&, Document&); + static Ref<SVGFEGaussianBlurElement> create(const QualifiedName&, Document&); void setStdDeviation(float stdDeviationX, float stdDeviationY); private: SVGFEGaussianBlurElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; static const AtomicString& stdDeviationXIdentifier(); static const AtomicString& stdDeviationYIdentifier(); @@ -56,6 +53,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEGaussianBlurElement.idl b/Source/WebCore/svg/SVGFEGaussianBlurElement.idl index 413f83bae..b32aee1cd 100644 --- a/Source/WebCore/svg/SVGFEGaussianBlurElement.idl +++ b/Source/WebCore/svg/SVGFEGaussianBlurElement.idl @@ -24,8 +24,7 @@ */ [ - Conditional=SVG&FILTERS, - DoNotCheckConstants, + DoNotCheckConstants ] interface SVGFEGaussianBlurElement : SVGElement { // Edge Mode Values const unsigned short SVG_EDGEMODE_UNKNOWN = 0; @@ -38,8 +37,8 @@ readonly attribute SVGAnimatedNumber stdDeviationY; readonly attribute SVGAnimatedEnumeration edgeMode; - void setStdDeviation([Default=Undefined] optional float stdDeviationX, - [Default=Undefined] optional float stdDeviationY); + void setStdDeviation(optional unrestricted float stdDeviationX = NaN, + optional unrestricted float stdDeviationY = NaN); }; SVGFEGaussianBlurElement implements SVGFilterPrimitiveStandardAttributes; diff --git a/Source/WebCore/svg/SVGFEImageElement.cpp b/Source/WebCore/svg/SVGFEImageElement.cpp index 2078fe5a7..19ef63b29 100644 --- a/Source/WebCore/svg/SVGFEImageElement.cpp +++ b/Source/WebCore/svg/SVGFEImageElement.cpp @@ -20,22 +20,17 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEImageElement.h" -#include "Attr.h" #include "CachedImage.h" #include "CachedResourceLoader.h" #include "CachedResourceRequest.h" -#include "ColorSpace.h" #include "Document.h" #include "Image.h" #include "RenderObject.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGNames.h" -#include "SVGPreserveAspectRatio.h" +#include "SVGPreserveAspectRatioValue.h" #include "XLinkNames.h" namespace WebCore { @@ -59,9 +54,9 @@ inline SVGFEImageElement::SVGFEImageElement(const QualifiedName& tagName, Docume registerAnimatedPropertiesForSVGFEImageElement(); } -PassRefPtr<SVGFEImageElement> SVGFEImageElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEImageElement> SVGFEImageElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEImageElement(tagName, document)); + return adoptRef(*new SVGFEImageElement(tagName, document)); } SVGFEImageElement::~SVGFEImageElement() @@ -69,30 +64,41 @@ SVGFEImageElement::~SVGFEImageElement() clearResourceReferences(); } +bool SVGFEImageElement::hasSingleSecurityOrigin() const +{ + if (!m_cachedImage) + return true; + auto* image = m_cachedImage->image(); + return !image || image->hasSingleSecurityOrigin(); +} + void SVGFEImageElement::clearResourceReferences() { if (m_cachedImage) { - m_cachedImage->removeClient(this); - m_cachedImage = 0; + m_cachedImage->removeClient(*this); + m_cachedImage = nullptr; } - document().accessSVGExtensions()->removeAllTargetReferencesForElement(this); + document().accessSVGExtensions().removeAllTargetReferencesForElement(this); } void SVGFEImageElement::requestImageResource() { - CachedResourceRequest request(ResourceRequest(document().completeURL(href()))); - request.setInitiator(this); - m_cachedImage = document().cachedResourceLoader()->requestImage(request); + ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions(); + options.contentSecurityPolicyImposition = isInUserAgentShadowTree() ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck; + + CachedResourceRequest request(ResourceRequest(document().completeURL(href())), options); + request.setInitiator(*this); + m_cachedImage = document().cachedResourceLoader().requestImage(WTFMove(request)); if (m_cachedImage) - m_cachedImage->addClient(this); + m_cachedImage->addClient(*this); } void SVGFEImageElement::buildPendingResource() { clearResourceReferences(); - if (!inDocument()) + if (!isConnected()) return; String id; @@ -101,102 +107,75 @@ void SVGFEImageElement::buildPendingResource() if (id.isEmpty()) requestImageResource(); else { - document().accessSVGExtensions()->addPendingResource(id, this); + document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); } } else if (target->isSVGElement()) { // Register us with the target in the dependencies map. Any change of hrefElement // that leads to relayout/repainting now informs us, so we can react to it. - document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target)); + document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target)); } invalidate(); } -bool SVGFEImageElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGURIReference::addSupportedAttributes(supportedAttributes); - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::preserveAspectRatioAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFEImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::preserveAspectRatioAttr) { - SVGPreserveAspectRatio preserveAspectRatio; + SVGPreserveAspectRatioValue preserveAspectRatio; preserveAspectRatio.parse(value); setPreserveAspectRatioBaseValue(preserveAspectRatio); return; } - if (SVGURIReference::parseAttribute(name, value)) - return; - if (SVGLangSpace::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::preserveAspectRatioAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } if (SVGURIReference::isKnownAttribute(attrName)) { + InstanceInvalidationGuard guard(*this); buildPendingResource(); return; } - if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) - return; - - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } Node::InsertionNotificationRequest SVGFEImageElement::insertedInto(ContainerNode& rootParent) { SVGFilterPrimitiveStandardAttributes::insertedInto(rootParent); + return InsertionShouldCallFinishedInsertingSubtree; +} + +void SVGFEImageElement::finishedInsertingSubtree() +{ buildPendingResource(); - return InsertionDone; } void SVGFEImageElement::removedFrom(ContainerNode& rootParent) { SVGFilterPrimitiveStandardAttributes::removedFrom(rootParent); - if (rootParent.inDocument()) + if (rootParent.isConnected()) clearResourceReferences(); } -void SVGFEImageElement::notifyFinished(CachedResource*) +void SVGFEImageElement::notifyFinished(CachedResource&) { - if (!inDocument()) + if (!isConnected()) return; Element* parent = parentElement(); - ASSERT(parent); - if (!parent->hasTagName(SVGNames::filterTag)) + if (!parent || !parent->hasTagName(SVGNames::filterTag)) return; RenderElement* parentRenderer = parent->renderer(); @@ -206,7 +185,7 @@ void SVGFEImageElement::notifyFinished(CachedResource*) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*parentRenderer); } -PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter* filter) +RefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter& filter) { if (m_cachedImage) return FEImage::createWithImage(filter, m_cachedImage->imageForRenderer(renderer()), preserveAspectRatio()); @@ -221,5 +200,3 @@ void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) cons } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEImageElement.h b/Source/WebCore/svg/SVGFEImageElement.h index ab8c4c7fd..b3cf2c940 100644 --- a/Source/WebCore/svg/SVGFEImageElement.h +++ b/Source/WebCore/svg/SVGFEImageElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEImageElement_h -#define SVGFEImageElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "CachedImageClient.h" #include "CachedResourceHandle.h" #include "ImageBuffer.h" @@ -39,38 +37,38 @@ class SVGFEImageElement final : public SVGFilterPrimitiveStandardAttributes, public SVGExternalResourcesRequired, public CachedImageClient { public: - static PassRefPtr<SVGFEImageElement> create(const QualifiedName&, Document&); + static Ref<SVGFEImageElement> create(const QualifiedName&, Document&); virtual ~SVGFEImageElement(); + bool hasSingleSecurityOrigin() const; + private: SVGFEImageElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void notifyFinished(CachedResource*) override; + void finishedInsertingSubtree() override; + + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + void notifyFinished(CachedResource&) final; - virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void addSubresourceAttributeURLs(ListHashSet<URL>&) const override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; void clearResourceReferences(); void requestImageResource(); - virtual void buildPendingResource() override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + void buildPendingResource() override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEImageElement) DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES CachedResourceHandle<CachedImage> m_cachedImage; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEImageElement.idl b/Source/WebCore/svg/SVGFEImageElement.idl index 0ac605586..422f432fb 100644 --- a/Source/WebCore/svg/SVGFEImageElement.idl +++ b/Source/WebCore/svg/SVGFEImageElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEImageElement : SVGElement { +interface SVGFEImageElement : SVGElement { readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; }; diff --git a/Source/WebCore/svg/SVGFELightElement.cpp b/Source/WebCore/svg/SVGFELightElement.cpp index dc56f36ae..9a85b408b 100644 --- a/Source/WebCore/svg/SVGFELightElement.cpp +++ b/Source/WebCore/svg/SVGFELightElement.cpp @@ -20,17 +20,16 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFELightElement.h" -#include "Attribute.h" #include "ElementIterator.h" #include "RenderObject.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGFEDiffuseLightingElement.h" +#include "SVGFEDistantLightElement.h" +#include "SVGFEPointLightElement.h" #include "SVGFESpecularLightingElement.h" +#include "SVGFESpotLightElement.h" #include "SVGFilterElement.h" #include "SVGFilterPrimitiveStandardAttributes.h" #include "SVGNames.h" @@ -72,13 +71,13 @@ SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document& doc SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement* svgElement) { for (auto& child : childrenOfType<SVGElement>(*svgElement)) { - if (isSVGFEDistantLightElement(child) || isSVGFEPointLightElement(child) || isSVGFESpotLightElement(child)) + if (is<SVGFEDistantLightElement>(child) || is<SVGFEPointLightElement>(child) || is<SVGFESpotLightElement>(child)) return static_cast<SVGFELightElement*>(const_cast<SVGElement*>(&child)); } return nullptr; } -PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement) +RefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement) { SVGFELightElement* lightNode = findLightElement(svgElement); if (!lightNode) @@ -86,31 +85,8 @@ PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svg return lightNode->lightSource(); } -bool SVGFELightElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::azimuthAttr); - supportedAttributes.add(SVGNames::elevationAttr); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::zAttr); - supportedAttributes.add(SVGNames::pointsAtXAttr); - supportedAttributes.add(SVGNames::pointsAtYAttr); - supportedAttributes.add(SVGNames::pointsAtZAttr); - supportedAttributes.add(SVGNames::specularExponentAttr); - supportedAttributes.add(SVGNames::limitingConeAngleAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFELightElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::azimuthAttr) { setAzimuthBaseValue(value.toFloat()); return; @@ -161,48 +137,36 @@ void SVGFELightElement::parseAttribute(const QualifiedName& name, const AtomicSt return; } - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); } void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGElement::svgAttributeChanged(attrName); - return; - } + if (attrName == SVGNames::azimuthAttr || attrName == SVGNames::elevationAttr + || attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::zAttr + || attrName == SVGNames::pointsAtXAttr || attrName == SVGNames::pointsAtYAttr || attrName == SVGNames::pointsAtZAttr + || attrName == SVGNames::specularExponentAttr || attrName == SVGNames::limitingConeAngleAttr) { - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::azimuthAttr - || attrName == SVGNames::elevationAttr - || attrName == SVGNames::xAttr - || attrName == SVGNames::yAttr - || attrName == SVGNames::zAttr - || attrName == SVGNames::pointsAtXAttr - || attrName == SVGNames::pointsAtYAttr - || attrName == SVGNames::pointsAtZAttr - || attrName == SVGNames::specularExponentAttr - || attrName == SVGNames::limitingConeAngleAttr) { - ContainerNode* parent = parentNode(); + auto* parent = parentElement(); if (!parent) return; - RenderObject* renderer = parent->renderer(); + auto* renderer = parent->renderer(); if (!renderer || !renderer->isSVGResourceFilterPrimitive()) return; - if (parent->hasTagName(SVGNames::feDiffuseLightingTag)) { - SVGFEDiffuseLightingElement* diffuseLighting = static_cast<SVGFEDiffuseLightingElement*>(parent); - diffuseLighting->lightElementAttributeChanged(this, attrName); - return; - } else if (parent->hasTagName(SVGNames::feSpecularLightingTag)) { - SVGFESpecularLightingElement* specularLighting = static_cast<SVGFESpecularLightingElement*>(parent); - specularLighting->lightElementAttributeChanged(this, attrName); - return; + if (is<SVGFEDiffuseLightingElement>(*parent)) { + InstanceInvalidationGuard guard(*this); + downcast<SVGFEDiffuseLightingElement>(*parent).lightElementAttributeChanged(this, attrName); + } else if (is<SVGFESpecularLightingElement>(*parent)) { + InstanceInvalidationGuard guard(*this); + downcast<SVGFESpecularLightingElement>(*parent).lightElementAttributeChanged(this, attrName); } + + return; } - ASSERT_NOT_REACHED(); + SVGElement::svgAttributeChanged(attrName); } void SVGFELightElement::childrenChanged(const ChildChange& change) @@ -220,5 +184,3 @@ void SVGFELightElement::childrenChanged(const ChildChange& change) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFELightElement.h b/Source/WebCore/svg/SVGFELightElement.h index 13865a3bc..02471ba9c 100644 --- a/Source/WebCore/svg/SVGFELightElement.h +++ b/Source/WebCore/svg/SVGFELightElement.h @@ -19,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFELightElement_h -#define SVGFELightElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "LightSource.h" #include "SVGAnimatedNumber.h" #include "SVGElement.h" @@ -31,20 +29,19 @@ namespace WebCore { class SVGFELightElement : public SVGElement { public: - virtual PassRefPtr<LightSource> lightSource() const = 0; + virtual Ref<LightSource> lightSource() const = 0; static SVGFELightElement* findLightElement(const SVGElement*); - static PassRefPtr<LightSource> findLightSource(const SVGElement*); + static RefPtr<LightSource> findLightSource(const SVGElement*); protected: SVGFELightElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) override { return false; } private: - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void childrenChanged(const ChildChange&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + void childrenChanged(const ChildChange&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFELightElement) DECLARE_ANIMATED_NUMBER(Azimuth, azimuth) @@ -61,6 +58,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) -#endif diff --git a/Source/WebCore/svg/SVGFEMergeElement.cpp b/Source/WebCore/svg/SVGFEMergeElement.cpp index cdf9c25bc..bc0167097 100644 --- a/Source/WebCore/svg/SVGFEMergeElement.cpp +++ b/Source/WebCore/svg/SVGFEMergeElement.cpp @@ -19,8 +19,6 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEMergeElement.h" #include "ElementIterator.h" @@ -37,12 +35,12 @@ inline SVGFEMergeElement::SVGFEMergeElement(const QualifiedName& tagName, Docume ASSERT(hasTagName(SVGNames::feMergeTag)); } -PassRefPtr<SVGFEMergeElement> SVGFEMergeElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEMergeElement> SVGFEMergeElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEMergeElement(tagName, document)); + return adoptRef(*new SVGFEMergeElement(tagName, document)); } -PassRefPtr<FilterEffect> SVGFEMergeElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEMergeElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { RefPtr<FilterEffect> effect = FEMerge::create(filter); FilterEffectVector& mergeInputs = effect->inputEffects(); @@ -57,9 +55,7 @@ PassRefPtr<FilterEffect> SVGFEMergeElement::build(SVGFilterBuilder* filterBuilde if (mergeInputs.isEmpty()) return nullptr; - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEMergeElement.h b/Source/WebCore/svg/SVGFEMergeElement.h index dd58b552e..7d18d09cc 100644 --- a/Source/WebCore/svg/SVGFEMergeElement.h +++ b/Source/WebCore/svg/SVGFEMergeElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEMergeElement_h -#define SVGFEMergeElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEMerge.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -29,15 +27,12 @@ namespace WebCore { class SVGFEMergeElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEMergeElement> create(const QualifiedName&, Document&); + static Ref<SVGFEMergeElement> create(const QualifiedName&, Document&); private: SVGFEMergeElement(const QualifiedName&, Document&); - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEMergeElement.idl b/Source/WebCore/svg/SVGFEMergeElement.idl index 6a99009c0..d3d8b2d2f 100644 --- a/Source/WebCore/svg/SVGFEMergeElement.idl +++ b/Source/WebCore/svg/SVGFEMergeElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEMergeElement : SVGElement { +interface SVGFEMergeElement : SVGElement { }; SVGFEMergeElement implements SVGFilterPrimitiveStandardAttributes; diff --git a/Source/WebCore/svg/SVGFEMergeNodeElement.cpp b/Source/WebCore/svg/SVGFEMergeNodeElement.cpp index 0290c3783..48511f26e 100644 --- a/Source/WebCore/svg/SVGFEMergeNodeElement.cpp +++ b/Source/WebCore/svg/SVGFEMergeNodeElement.cpp @@ -19,14 +19,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEMergeNodeElement.h" -#include "Attribute.h" -#include "RenderObject.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGFilterElement.h" #include "SVGFilterPrimitiveStandardAttributes.h" #include "SVGNames.h" @@ -47,51 +42,30 @@ inline SVGFEMergeNodeElement::SVGFEMergeNodeElement(const QualifiedName& tagName registerAnimatedPropertiesForSVGFEMergeNodeElement(); } -PassRefPtr<SVGFEMergeNodeElement> SVGFEMergeNodeElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFEMergeNodeElement(tagName, document)); -} - -bool SVGFEMergeNodeElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFEMergeNodeElement> SVGFEMergeNodeElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - supportedAttributes.add(SVGNames::inAttr); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFEMergeNodeElement(tagName, document)); } void SVGFEMergeNodeElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::inAttr) { setIn1BaseValue(value); return; } - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); } void SVGFEMergeNodeElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::inAttr) { + InstanceInvalidationGuard guard(*this); invalidateFilterPrimitiveParent(this); return; } - ASSERT_NOT_REACHED(); + SVGElement::svgAttributeChanged(attrName); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEMergeNodeElement.h b/Source/WebCore/svg/SVGFEMergeNodeElement.h index bef567dc5..3b718db6b 100644 --- a/Source/WebCore/svg/SVGFEMergeNodeElement.h +++ b/Source/WebCore/svg/SVGFEMergeNodeElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEMergeNodeElement_h -#define SVGFEMergeNodeElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGAnimatedString.h" #include "SVGElement.h" @@ -29,25 +27,18 @@ namespace WebCore { class SVGFEMergeNodeElement final : public SVGElement { public: - static PassRefPtr<SVGFEMergeNodeElement> create(const QualifiedName&, Document&); + static Ref<SVGFEMergeNodeElement> create(const QualifiedName&, Document&); private: SVGFEMergeNodeElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; + bool rendererIsNeeded(const RenderStyle&) final { return false; } BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEMergeNodeElement) DECLARE_ANIMATED_STRING(In1, in1) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGFEMergeNodeElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEMergeNodeElement.idl b/Source/WebCore/svg/SVGFEMergeNodeElement.idl index f7093c45c..8595c5142 100644 --- a/Source/WebCore/svg/SVGFEMergeNodeElement.idl +++ b/Source/WebCore/svg/SVGFEMergeNodeElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEMergeNodeElement : SVGElement { +interface SVGFEMergeNodeElement : SVGElement { readonly attribute SVGAnimatedString in1; }; diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.cpp b/Source/WebCore/svg/SVGFEMorphologyElement.cpp index 784a50d1a..3370e1855 100644 --- a/Source/WebCore/svg/SVGFEMorphologyElement.cpp +++ b/Source/WebCore/svg/SVGFEMorphologyElement.cpp @@ -18,13 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEMorphologyElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" #include "SVGParserUtilities.h" @@ -53,20 +49,20 @@ inline SVGFEMorphologyElement::SVGFEMorphologyElement(const QualifiedName& tagNa registerAnimatedPropertiesForSVGFEMorphologyElement(); } -PassRefPtr<SVGFEMorphologyElement> SVGFEMorphologyElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEMorphologyElement> SVGFEMorphologyElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEMorphologyElement(tagName, document)); + return adoptRef(*new SVGFEMorphologyElement(tagName, document)); } const AtomicString& SVGFEMorphologyElement::radiusXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGRadiusX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFEMorphologyElement::radiusYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGRadiusY", AtomicString::ConstructFromLiteral); return s_identifier; } @@ -77,24 +73,8 @@ void SVGFEMorphologyElement::setRadius(float x, float y) invalidate(); } -bool SVGFEMorphologyElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::operatorAttr); - supportedAttributes.add(SVGNames::radiusAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFEMorphologyElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::operatorAttr) { MorphologyOperatorType propertyValue = SVGPropertyTraits<MorphologyOperatorType>::fromString(value); if (propertyValue > 0) @@ -116,7 +96,7 @@ void SVGFEMorphologyElement::parseAttribute(const QualifiedName& name, const Ato return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -137,43 +117,36 @@ bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, cons void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } if (attrName == SVGNames::inAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEMorphologyElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEMorphologyElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); float xRadius = radiusX(); float yRadius = radiusY(); if (!input1) - return 0; + return nullptr; if (xRadius < 0 || yRadius < 0) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FEMorphology::create(filter, svgOperator(), xRadius, yRadius); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.h b/Source/WebCore/svg/SVGFEMorphologyElement.h index 1d5d752f0..814d6d5a5 100644 --- a/Source/WebCore/svg/SVGFEMorphologyElement.h +++ b/Source/WebCore/svg/SVGFEMorphologyElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEMorphologyElement_h -#define SVGFEMorphologyElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEMorphology.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedNumber.h" @@ -38,9 +36,9 @@ struct SVGPropertyTraits<MorphologyOperatorType> { case FEMORPHOLOGY_OPERATOR_UNKNOWN: return emptyString(); case FEMORPHOLOGY_OPERATOR_ERODE: - return "erode"; + return ASCIILiteral("erode"); case FEMORPHOLOGY_OPERATOR_DILATE: - return "dilate"; + return ASCIILiteral("dilate"); } ASSERT_NOT_REACHED(); @@ -59,18 +57,17 @@ struct SVGPropertyTraits<MorphologyOperatorType> { class SVGFEMorphologyElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEMorphologyElement> create(const QualifiedName&, Document&); + static Ref<SVGFEMorphologyElement> create(const QualifiedName&, Document&); void setRadius(float radiusX, float radiusY); private: SVGFEMorphologyElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; static const AtomicString& radiusXIdentifier(); static const AtomicString& radiusYIdentifier(); @@ -84,6 +81,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEMorphologyElement.idl b/Source/WebCore/svg/SVGFEMorphologyElement.idl index b58c596fd..b6d86f40b 100644 --- a/Source/WebCore/svg/SVGFEMorphologyElement.idl +++ b/Source/WebCore/svg/SVGFEMorphologyElement.idl @@ -24,8 +24,7 @@ */ [ - Conditional=SVG&FILTERS, - DoNotCheckConstants, + DoNotCheckConstants ] interface SVGFEMorphologyElement : SVGElement { // Morphology Operators const unsigned short SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0; @@ -37,8 +36,8 @@ readonly attribute SVGAnimatedNumber radiusX; readonly attribute SVGAnimatedNumber radiusY; - void setRadius([Default=Undefined] optional float radiusX, - [Default=Undefined] optional float radiusY); + void setRadius(optional unrestricted float radiusX = NaN, + optional unrestricted float radiusY = NaN); }; SVGFEMorphologyElement implements SVGFilterPrimitiveStandardAttributes; diff --git a/Source/WebCore/svg/SVGFEOffsetElement.cpp b/Source/WebCore/svg/SVGFEOffsetElement.cpp index 9911d9f35..43138ff9a 100644 --- a/Source/WebCore/svg/SVGFEOffsetElement.cpp +++ b/Source/WebCore/svg/SVGFEOffsetElement.cpp @@ -19,13 +19,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEOffsetElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" @@ -50,29 +46,13 @@ inline SVGFEOffsetElement::SVGFEOffsetElement(const QualifiedName& tagName, Docu registerAnimatedPropertiesForSVGFEOffsetElement(); } -PassRefPtr<SVGFEOffsetElement> SVGFEOffsetElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFEOffsetElement(tagName, document)); -} - -bool SVGFEOffsetElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFEOffsetElement> SVGFEOffsetElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::dxAttr); - supportedAttributes.add(SVGNames::dyAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFEOffsetElement(tagName, document)); } void SVGFEOffsetElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::dxAttr) { setDxBaseValue(value.toFloat()); return; @@ -88,38 +68,30 @@ void SVGFEOffsetElement::parseAttribute(const QualifiedName& name, const AtomicS return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } void SVGFEOffsetElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::inAttr || attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFEOffsetElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFEOffsetElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FEOffset::create(filter, dx(), dy()); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFEOffsetElement.h b/Source/WebCore/svg/SVGFEOffsetElement.h index 4e0226a25..c7e00af6e 100644 --- a/Source/WebCore/svg/SVGFEOffsetElement.h +++ b/Source/WebCore/svg/SVGFEOffsetElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEOffsetElement_h -#define SVGFEOffsetElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FEOffset.h" #include "SVGAnimatedNumber.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -30,15 +28,14 @@ namespace WebCore { class SVGFEOffsetElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFEOffsetElement> create(const QualifiedName&, Document&); + static Ref<SVGFEOffsetElement> create(const QualifiedName&, Document&); private: SVGFEOffsetElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEOffsetElement) DECLARE_ANIMATED_STRING(In1, in1) @@ -48,6 +45,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEOffsetElement.idl b/Source/WebCore/svg/SVGFEOffsetElement.idl index eb95e7465..730ec4a0f 100644 --- a/Source/WebCore/svg/SVGFEOffsetElement.idl +++ b/Source/WebCore/svg/SVGFEOffsetElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEOffsetElement : SVGElement { +interface SVGFEOffsetElement : SVGElement { readonly attribute SVGAnimatedString in1; readonly attribute SVGAnimatedNumber dx; readonly attribute SVGAnimatedNumber dy; diff --git a/Source/WebCore/svg/SVGFEPointLightElement.cpp b/Source/WebCore/svg/SVGFEPointLightElement.cpp index e215e055a..831f2c83b 100644 --- a/Source/WebCore/svg/SVGFEPointLightElement.cpp +++ b/Source/WebCore/svg/SVGFEPointLightElement.cpp @@ -18,8 +18,6 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEPointLightElement.h" #include "SVGNames.h" @@ -33,18 +31,14 @@ inline SVGFEPointLightElement::SVGFEPointLightElement(const QualifiedName& tagNa ASSERT(hasTagName(SVGNames::fePointLightTag)); } -PassRefPtr<SVGFEPointLightElement> SVGFEPointLightElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFEPointLightElement> SVGFEPointLightElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFEPointLightElement(tagName, document)); + return adoptRef(*new SVGFEPointLightElement(tagName, document)); } -PassRefPtr<LightSource> SVGFEPointLightElement::lightSource() const +Ref<LightSource> SVGFEPointLightElement::lightSource() const { return PointLightSource::create(FloatPoint3D(x(), y(), z())); } } - -#endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFEPointLightElement.h b/Source/WebCore/svg/SVGFEPointLightElement.h index 30d18fff5..eaa4580cd 100644 --- a/Source/WebCore/svg/SVGFEPointLightElement.h +++ b/Source/WebCore/svg/SVGFEPointLightElement.h @@ -17,27 +17,20 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEPointLightElement_h -#define SVGFEPointLightElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFELightElement.h" namespace WebCore { class SVGFEPointLightElement final : public SVGFELightElement { public: - static PassRefPtr<SVGFEPointLightElement> create(const QualifiedName&, Document&); + static Ref<SVGFEPointLightElement> create(const QualifiedName&, Document&); private: SVGFEPointLightElement(const QualifiedName&, Document&); - virtual PassRefPtr<LightSource> lightSource() const override; + Ref<LightSource> lightSource() const override; }; -NODE_TYPE_CASTS(SVGFEPointLightElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFEPointLightElement.idl b/Source/WebCore/svg/SVGFEPointLightElement.idl index 102d5b2bd..2ba36ed93 100644 --- a/Source/WebCore/svg/SVGFEPointLightElement.idl +++ b/Source/WebCore/svg/SVGFEPointLightElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFEPointLightElement : SVGElement { +interface SVGFEPointLightElement : SVGElement { readonly attribute SVGAnimatedNumber x; readonly attribute SVGAnimatedNumber y; readonly attribute SVGAnimatedNumber z; diff --git a/Source/WebCore/svg/SVGFESpecularLightingElement.cpp b/Source/WebCore/svg/SVGFESpecularLightingElement.cpp index 779747175..5565b91d1 100644 --- a/Source/WebCore/svg/SVGFESpecularLightingElement.cpp +++ b/Source/WebCore/svg/SVGFESpecularLightingElement.cpp @@ -20,15 +20,10 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFESpecularLightingElement.h" -#include "Attribute.h" #include "FilterEffect.h" #include "RenderStyle.h" -#include "SVGColor.h" -#include "SVGElementInstance.h" #include "SVGFELightElement.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" @@ -64,43 +59,25 @@ inline SVGFESpecularLightingElement::SVGFESpecularLightingElement(const Qualifie registerAnimatedPropertiesForSVGFESpecularLightingElement(); } -PassRefPtr<SVGFESpecularLightingElement> SVGFESpecularLightingElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFESpecularLightingElement> SVGFESpecularLightingElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFESpecularLightingElement(tagName, document)); + return adoptRef(*new SVGFESpecularLightingElement(tagName, document)); } const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral); return s_identifier; } -bool SVGFESpecularLightingElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::inAttr); - supportedAttributes.add(SVGNames::specularConstantAttr); - supportedAttributes.add(SVGNames::specularExponentAttr); - supportedAttributes.add(SVGNames::surfaceScaleAttr); - supportedAttributes.add(SVGNames::kernelUnitLengthAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFESpecularLightingElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::inAttr) { setIn1BaseValue(value); return; @@ -130,7 +107,7 @@ void SVGFESpecularLightingElement::parseAttribute(const QualifiedName& name, con return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -181,27 +158,19 @@ bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect void SVGFESpecularLightingElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::surfaceScaleAttr - || attrName == SVGNames::specularConstantAttr - || attrName == SVGNames::specularExponentAttr - || attrName == SVGNames::kernelUnitLengthAttr) { + if (attrName == SVGNames::surfaceScaleAttr || attrName == SVGNames::specularConstantAttr || attrName == SVGNames::specularExponentAttr || attrName == SVGNames::kernelUnitLengthAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } if (attrName == SVGNames::inAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName) @@ -213,29 +182,27 @@ void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELight primitiveAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFESpecularLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFESpecularLightingElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; - RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this); + auto lightSource = SVGFELightElement::findLightSource(this); if (!lightSource) - return 0; + return nullptr; RenderObject* renderer = this->renderer(); if (!renderer) - return 0; + return nullptr; - Color color = renderer->style().svgStyle().lightingColor(); + const Color& color = renderer->style().svgStyle().lightingColor(); RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(), - specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release()); + specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), WTFMove(lightSource)); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFESpecularLightingElement.h b/Source/WebCore/svg/SVGFESpecularLightingElement.h index ea5316b53..146e300f1 100644 --- a/Source/WebCore/svg/SVGFESpecularLightingElement.h +++ b/Source/WebCore/svg/SVGFESpecularLightingElement.h @@ -19,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFESpecularLightingElement_h -#define SVGFESpecularLightingElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FESpecularLighting.h" #include "SVGAnimatedNumber.h" #include "SVGFELightElement.h" @@ -32,17 +30,16 @@ namespace WebCore { class SVGFESpecularLightingElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFESpecularLightingElement> create(const QualifiedName&, Document&); + static Ref<SVGFESpecularLightingElement> create(const QualifiedName&, Document&); void lightElementAttributeChanged(const SVGFELightElement*, const QualifiedName&); private: SVGFESpecularLightingElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; static const AtomicString& kernelUnitLengthXIdentifier(); static const AtomicString& kernelUnitLengthYIdentifier(); @@ -58,6 +55,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFESpecularLightingElement.idl b/Source/WebCore/svg/SVGFESpecularLightingElement.idl index 0e4e9ee52..409a15582 100644 --- a/Source/WebCore/svg/SVGFESpecularLightingElement.idl +++ b/Source/WebCore/svg/SVGFESpecularLightingElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFESpecularLightingElement : SVGElement { +interface SVGFESpecularLightingElement : SVGElement { readonly attribute SVGAnimatedString in1; readonly attribute SVGAnimatedNumber surfaceScale; readonly attribute SVGAnimatedNumber specularConstant; diff --git a/Source/WebCore/svg/SVGFESpotLightElement.cpp b/Source/WebCore/svg/SVGFESpotLightElement.cpp index 4d5093bd7..55952d1a5 100644 --- a/Source/WebCore/svg/SVGFESpotLightElement.cpp +++ b/Source/WebCore/svg/SVGFESpotLightElement.cpp @@ -18,11 +18,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFESpotLightElement.h" -#include "SVGNames.h" +#include "SVGNames.h" #include "SpotLightSource.h" namespace WebCore { @@ -33,12 +31,12 @@ inline SVGFESpotLightElement::SVGFESpotLightElement(const QualifiedName& tagName ASSERT(hasTagName(SVGNames::feSpotLightTag)); } -PassRefPtr<SVGFESpotLightElement> SVGFESpotLightElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFESpotLightElement> SVGFESpotLightElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFESpotLightElement(tagName, document)); + return adoptRef(*new SVGFESpotLightElement(tagName, document)); } -PassRefPtr<LightSource> SVGFESpotLightElement::lightSource() const +Ref<LightSource> SVGFESpotLightElement::lightSource() const { FloatPoint3D pos(x(), y(), z()); FloatPoint3D direction(pointsAtX(), pointsAtY(), pointsAtZ()); @@ -47,7 +45,3 @@ PassRefPtr<LightSource> SVGFESpotLightElement::lightSource() const } } - -#endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFESpotLightElement.h b/Source/WebCore/svg/SVGFESpotLightElement.h index 0d5d6c645..b56d09199 100644 --- a/Source/WebCore/svg/SVGFESpotLightElement.h +++ b/Source/WebCore/svg/SVGFESpotLightElement.h @@ -17,27 +17,20 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFESpotLightElement_h -#define SVGFESpotLightElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFELightElement.h" namespace WebCore { class SVGFESpotLightElement final : public SVGFELightElement { public: - static PassRefPtr<SVGFESpotLightElement> create(const QualifiedName&, Document&); + static Ref<SVGFESpotLightElement> create(const QualifiedName&, Document&); private: SVGFESpotLightElement(const QualifiedName&, Document&); - virtual PassRefPtr<LightSource> lightSource() const override; + Ref<LightSource> lightSource() const override; }; -NODE_TYPE_CASTS(SVGFESpotLightElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFESpotLightElement.idl b/Source/WebCore/svg/SVGFESpotLightElement.idl index 20d8f9171..af52685a3 100644 --- a/Source/WebCore/svg/SVGFESpotLightElement.idl +++ b/Source/WebCore/svg/SVGFESpotLightElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFESpotLightElement : SVGElement { +interface SVGFESpotLightElement : SVGElement { readonly attribute SVGAnimatedNumber x; readonly attribute SVGAnimatedNumber y; readonly attribute SVGAnimatedNumber z; diff --git a/Source/WebCore/svg/SVGFETileElement.cpp b/Source/WebCore/svg/SVGFETileElement.cpp index 1c1b0d379..969bf4870 100644 --- a/Source/WebCore/svg/SVGFETileElement.cpp +++ b/Source/WebCore/svg/SVGFETileElement.cpp @@ -19,13 +19,9 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFETileElement.h" -#include "Attribute.h" #include "FilterEffect.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGNames.h" #include "SVGRenderStyle.h" @@ -47,63 +43,42 @@ inline SVGFETileElement::SVGFETileElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGFETileElement(); } -PassRefPtr<SVGFETileElement> SVGFETileElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGFETileElement(tagName, document)); -} - -bool SVGFETileElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGFETileElement> SVGFETileElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - supportedAttributes.add(SVGNames::inAttr); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGFETileElement(tagName, document)); } void SVGFETileElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::inAttr) { setIn1BaseValue(value); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } void SVGFETileElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::inAttr) { + InstanceInvalidationGuard guard(*this); invalidate(); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFETileElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) +RefPtr<FilterEffect> SVGFETileElement::build(SVGFilterBuilder* filterBuilder, Filter& filter) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) - return 0; + return nullptr; RefPtr<FilterEffect> effect = FETile::create(filter); effect->inputEffects().append(input1); - return effect.release(); + return effect; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFETileElement.h b/Source/WebCore/svg/SVGFETileElement.h index ddd288845..5651b3c8c 100644 --- a/Source/WebCore/svg/SVGFETileElement.h +++ b/Source/WebCore/svg/SVGFETileElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFETileElement_h -#define SVGFETileElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FETile.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -29,15 +27,14 @@ namespace WebCore { class SVGFETileElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFETileElement> create(const QualifiedName&, Document&); + static Ref<SVGFETileElement> create(const QualifiedName&, Document&); private: SVGFETileElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFETileElement) DECLARE_ANIMATED_STRING(In1, in1) @@ -45,6 +42,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFETileElement.idl b/Source/WebCore/svg/SVGFETileElement.idl index 5cae1a148..91474a1c0 100644 --- a/Source/WebCore/svg/SVGFETileElement.idl +++ b/Source/WebCore/svg/SVGFETileElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS -] interface SVGFETileElement : SVGElement { +interface SVGFETileElement : SVGElement { readonly attribute SVGAnimatedString in1; }; diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.cpp b/Source/WebCore/svg/SVGFETurbulenceElement.cpp index a357e4e5c..b808bd920 100644 --- a/Source/WebCore/svg/SVGFETurbulenceElement.cpp +++ b/Source/WebCore/svg/SVGFETurbulenceElement.cpp @@ -19,12 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFETurbulenceElement.h" -#include "Attribute.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGParserUtilities.h" @@ -58,43 +54,25 @@ inline SVGFETurbulenceElement::SVGFETurbulenceElement(const QualifiedName& tagNa registerAnimatedPropertiesForSVGFETurbulenceElement(); } -PassRefPtr<SVGFETurbulenceElement> SVGFETurbulenceElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFETurbulenceElement> SVGFETurbulenceElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFETurbulenceElement(tagName, document)); + return adoptRef(*new SVGFETurbulenceElement(tagName, document)); } const AtomicString& SVGFETurbulenceElement::baseFrequencyXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGBaseFrequencyX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFETurbulenceElement::baseFrequencyYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGBaseFrequencyY", AtomicString::ConstructFromLiteral); return s_identifier; } -bool SVGFETurbulenceElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::baseFrequencyAttr); - supportedAttributes.add(SVGNames::numOctavesAttr); - supportedAttributes.add(SVGNames::seedAttr); - supportedAttributes.add(SVGNames::stitchTilesAttr); - supportedAttributes.add(SVGNames::typeAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGFETurbulenceElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); - return; - } - if (name == SVGNames::typeAttr) { TurbulenceType propertyValue = SVGPropertyTraits<TurbulenceType>::fromString(value); if (propertyValue > 0) @@ -128,7 +106,7 @@ void SVGFETurbulenceElement::parseAttribute(const QualifiedName& name, const Ato return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); } bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) @@ -151,32 +129,20 @@ bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, cons void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::baseFrequencyAttr - || attrName == SVGNames::numOctavesAttr - || attrName == SVGNames::seedAttr - || attrName == SVGNames::stitchTilesAttr - || attrName == SVGNames::typeAttr) { + if (attrName == SVGNames::baseFrequencyAttr || attrName == SVGNames::numOctavesAttr || attrName == SVGNames::seedAttr || attrName == SVGNames::stitchTilesAttr || attrName == SVGNames::typeAttr) { + InstanceInvalidationGuard guard(*this); primitiveAttributeChanged(attrName); return; } - ASSERT_NOT_REACHED(); + SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); } -PassRefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*, Filter* filter) +RefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*, Filter& filter) { if (baseFrequencyX() < 0 || baseFrequencyY() < 0) - return 0; + return nullptr; return FETurbulence::create(filter, type(), baseFrequencyX(), baseFrequencyY(), numOctaves(), seed(), stitchTiles() == SVG_STITCHTYPE_STITCH); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.h b/Source/WebCore/svg/SVGFETurbulenceElement.h index b13f72712..4a9cbef01 100644 --- a/Source/WebCore/svg/SVGFETurbulenceElement.h +++ b/Source/WebCore/svg/SVGFETurbulenceElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFETurbulenceElement_h -#define SVGFETurbulenceElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FETurbulence.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedInteger.h" @@ -46,9 +44,9 @@ struct SVGPropertyTraits<SVGStitchOptions> { case SVG_STITCHTYPE_UNKNOWN: return emptyString(); case SVG_STITCHTYPE_STITCH: - return "stitch"; + return ASCIILiteral("stitch"); case SVG_STITCHTYPE_NOSTITCH: - return "noStitch"; + return ASCIILiteral("noStitch"); } ASSERT_NOT_REACHED(); @@ -75,9 +73,9 @@ struct SVGPropertyTraits<TurbulenceType> { case FETURBULENCE_TYPE_UNKNOWN: return emptyString(); case FETURBULENCE_TYPE_FRACTALNOISE: - return "fractalNoise"; + return ASCIILiteral("fractalNoise"); case FETURBULENCE_TYPE_TURBULENCE: - return "turbulence"; + return ASCIILiteral("turbulence"); } ASSERT_NOT_REACHED(); @@ -96,16 +94,15 @@ struct SVGPropertyTraits<TurbulenceType> { class SVGFETurbulenceElement final : public SVGFilterPrimitiveStandardAttributes { public: - static PassRefPtr<SVGFETurbulenceElement> create(const QualifiedName&, Document&); + static Ref<SVGFETurbulenceElement> create(const QualifiedName&, Document&); private: SVGFETurbulenceElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) override; + void svgAttributeChanged(const QualifiedName&) override; + RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) override; static const AtomicString& baseFrequencyXIdentifier(); static const AtomicString& baseFrequencyYIdentifier(); @@ -121,6 +118,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGFETurbulenceElement.idl b/Source/WebCore/svg/SVGFETurbulenceElement.idl index 0804fb596..6f4f2e80a 100644 --- a/Source/WebCore/svg/SVGFETurbulenceElement.idl +++ b/Source/WebCore/svg/SVGFETurbulenceElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG&FILTERS, DoNotCheckConstants ] interface SVGFETurbulenceElement : SVGElement { // Turbulence Types diff --git a/Source/WebCore/svg/SVGFilterElement.cpp b/Source/WebCore/svg/SVGFilterElement.cpp index 5da956455..80663b8d3 100644 --- a/Source/WebCore/svg/SVGFilterElement.cpp +++ b/Source/WebCore/svg/SVGFilterElement.cpp @@ -4,6 +4,7 @@ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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,18 +23,15 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFilterElement.h" -#include "Attr.h" #include "RenderSVGResourceFilter.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" #include "SVGFilterPrimitiveStandardAttributes.h" #include "SVGNames.h" #include "SVGParserUtilities.h" #include "XLinkNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -77,20 +75,20 @@ inline SVGFilterElement::SVGFilterElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGFilterElement(); } -PassRefPtr<SVGFilterElement> SVGFilterElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFilterElement> SVGFilterElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFilterElement(tagName, document)); + return adoptRef(*new SVGFilterElement(tagName, document)); } const AtomicString& SVGFilterElement::filterResXIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGFilterResX", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGFilterResX", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGFilterElement::filterResYIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGFilterResY", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGFilterResY", AtomicString::ConstructFromLiteral); return s_identifier; } @@ -105,29 +103,27 @@ void SVGFilterElement::setFilterRes(unsigned filterResX, unsigned filterResY) bool SVGFilterElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGURIReference::addSupportedAttributes(supportedAttributes); SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::filterUnitsAttr); - supportedAttributes.add(SVGNames::primitiveUnitsAttr); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); - supportedAttributes.add(SVGNames::filterResAttr); + supportedAttributes.get().add(SVGNames::filterUnitsAttr); + supportedAttributes.get().add(SVGNames::primitiveUnitsAttr); + supportedAttributes.get().add(SVGNames::xAttr); + supportedAttributes.get().add(SVGNames::yAttr); + supportedAttributes.get().add(SVGNames::widthAttr); + supportedAttributes.get().add(SVGNames::heightAttr); + supportedAttributes.get().add(SVGNames::filterResAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGElement::parseAttribute(name, value); - else if (name == SVGNames::filterUnitsAttr) { + if (name == SVGNames::filterUnitsAttr) { SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); if (propertyValue > 0) setFilterUnitsBaseValue(propertyValue); @@ -136,26 +132,26 @@ void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicStr if (propertyValue > 0) setPrimitiveUnitsBaseValue(propertyValue); } else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::filterResAttr) { float x, y; if (parseNumberOptionalNumber(value, x, y)) { setFilterResXBaseValue(x); setFilterResYBaseValue(y); } - } else if (SVGURIReference::parseAttribute(name, value) - || SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + } reportAttributeParsingError(parseError, name, value); + + SVGElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName) @@ -165,16 +161,15 @@ void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::xAttr - || attrName == SVGNames::yAttr - || attrName == SVGNames::widthAttr - || attrName == SVGNames::heightAttr) - updateRelativeLengthsInformation(); + InstanceInvalidationGuard guard(*this); - if (RenderObject* object = renderer()) - object->setNeedsLayout(); + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { + invalidateSVGPresentationAttributeStyle(); + return; + } + + if (auto* renderer = this->renderer()) + renderer->setNeedsLayout(); } void SVGFilterElement::childrenChanged(const ChildChange& change) @@ -188,9 +183,9 @@ void SVGFilterElement::childrenChanged(const ChildChange& change) object->setNeedsLayout(); } -RenderPtr<RenderElement> SVGFilterElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGFilterElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceFilter>(*this, std::move(style)); + return createRenderer<RenderSVGResourceFilter>(*this, WTFMove(style)); } bool SVGFilterElement::childShouldCreateRenderer(const Node& child) const @@ -198,48 +193,38 @@ bool SVGFilterElement::childShouldCreateRenderer(const Node& child) const if (!child.isSVGElement()) return false; - const SVGElement& svgElement = toSVGElement(child); - - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, allowedChildElementTags, ()); - if (allowedChildElementTags.isEmpty()) { - allowedChildElementTags.add(SVGNames::feBlendTag); - allowedChildElementTags.add(SVGNames::feColorMatrixTag); - allowedChildElementTags.add(SVGNames::feComponentTransferTag); - allowedChildElementTags.add(SVGNames::feCompositeTag); - allowedChildElementTags.add(SVGNames::feConvolveMatrixTag); - allowedChildElementTags.add(SVGNames::feDiffuseLightingTag); - allowedChildElementTags.add(SVGNames::feDisplacementMapTag); - allowedChildElementTags.add(SVGNames::feDistantLightTag); - allowedChildElementTags.add(SVGNames::feDropShadowTag); - allowedChildElementTags.add(SVGNames::feFloodTag); - allowedChildElementTags.add(SVGNames::feFuncATag); - allowedChildElementTags.add(SVGNames::feFuncBTag); - allowedChildElementTags.add(SVGNames::feFuncGTag); - allowedChildElementTags.add(SVGNames::feFuncRTag); - allowedChildElementTags.add(SVGNames::feGaussianBlurTag); - allowedChildElementTags.add(SVGNames::feImageTag); - allowedChildElementTags.add(SVGNames::feMergeTag); - allowedChildElementTags.add(SVGNames::feMergeNodeTag); - allowedChildElementTags.add(SVGNames::feMorphologyTag); - allowedChildElementTags.add(SVGNames::feOffsetTag); - allowedChildElementTags.add(SVGNames::fePointLightTag); - allowedChildElementTags.add(SVGNames::feSpecularLightingTag); - allowedChildElementTags.add(SVGNames::feSpotLightTag); - allowedChildElementTags.add(SVGNames::feTileTag); - allowedChildElementTags.add(SVGNames::feTurbulenceTag); + const SVGElement& svgElement = downcast<SVGElement>(child); + + static NeverDestroyed<HashSet<QualifiedName>> allowedChildElementTags; + if (allowedChildElementTags.get().isEmpty()) { + allowedChildElementTags.get().add(SVGNames::feBlendTag); + allowedChildElementTags.get().add(SVGNames::feColorMatrixTag); + allowedChildElementTags.get().add(SVGNames::feComponentTransferTag); + allowedChildElementTags.get().add(SVGNames::feCompositeTag); + allowedChildElementTags.get().add(SVGNames::feConvolveMatrixTag); + allowedChildElementTags.get().add(SVGNames::feDiffuseLightingTag); + allowedChildElementTags.get().add(SVGNames::feDisplacementMapTag); + allowedChildElementTags.get().add(SVGNames::feDistantLightTag); + allowedChildElementTags.get().add(SVGNames::feDropShadowTag); + allowedChildElementTags.get().add(SVGNames::feFloodTag); + allowedChildElementTags.get().add(SVGNames::feFuncATag); + allowedChildElementTags.get().add(SVGNames::feFuncBTag); + allowedChildElementTags.get().add(SVGNames::feFuncGTag); + allowedChildElementTags.get().add(SVGNames::feFuncRTag); + allowedChildElementTags.get().add(SVGNames::feGaussianBlurTag); + allowedChildElementTags.get().add(SVGNames::feImageTag); + allowedChildElementTags.get().add(SVGNames::feMergeTag); + allowedChildElementTags.get().add(SVGNames::feMergeNodeTag); + allowedChildElementTags.get().add(SVGNames::feMorphologyTag); + allowedChildElementTags.get().add(SVGNames::feOffsetTag); + allowedChildElementTags.get().add(SVGNames::fePointLightTag); + allowedChildElementTags.get().add(SVGNames::feSpecularLightingTag); + allowedChildElementTags.get().add(SVGNames::feSpotLightTag); + allowedChildElementTags.get().add(SVGNames::feTileTag); + allowedChildElementTags.get().add(SVGNames::feTurbulenceTag); } - return allowedChildElementTags.contains<SVGAttributeHashTranslator>(svgElement.tagQName()); -} - -bool SVGFilterElement::selfHasRelativeLengths() const -{ - return x().isRelative() - || y().isRelative() - || width().isRelative() - || height().isRelative(); + return allowedChildElementTags.get().contains<SVGAttributeHashTranslator>(svgElement.tagQName()); } } - -#endif diff --git a/Source/WebCore/svg/SVGFilterElement.h b/Source/WebCore/svg/SVGFilterElement.h index aeaa45996..3470ab54f 100644 --- a/Source/WebCore/svg/SVGFilterElement.h +++ b/Source/WebCore/svg/SVGFilterElement.h @@ -20,17 +20,14 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFilterElement_h -#define SVGFilterElement_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedInteger.h" #include "SVGAnimatedLength.h" #include "SVGElement.h" #include "SVGExternalResourcesRequired.h" -#include "SVGNames.h" #include "SVGURIReference.h" #include "SVGUnitTypes.h" @@ -40,24 +37,24 @@ class SVGFilterElement final : public SVGElement, public SVGURIReference, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGFilterElement> create(const QualifiedName&, Document&); + static Ref<SVGFilterElement> create(const QualifiedName&, Document&); void setFilterRes(unsigned filterResX, unsigned filterResY); private: SVGFilterElement(const QualifiedName&, Document&); - virtual bool needsPendingResourceHandling() const override { return false; } + bool needsPendingResourceHandling() const final { return false; } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void childrenChanged(const ChildChange&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; + void childrenChanged(const ChildChange&) final; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool childShouldCreateRenderer(const Node&) const override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; + bool childShouldCreateRenderer(const Node&) const final; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final { return true; } static const AtomicString& filterResXIdentifier(); static const AtomicString& filterResYIdentifier(); @@ -71,14 +68,9 @@ private: DECLARE_ANIMATED_LENGTH(Height, height) DECLARE_ANIMATED_INTEGER(FilterResX, filterResX) DECLARE_ANIMATED_INTEGER(FilterResY, filterResY) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGFilterElement) - -} - -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGFilterElement.idl b/Source/WebCore/svg/SVGFilterElement.idl index 06292c98f..4b788db1b 100644 --- a/Source/WebCore/svg/SVGFilterElement.idl +++ b/Source/WebCore/svg/SVGFilterElement.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG&FILTERS, -] interface SVGFilterElement : SVGElement { +interface SVGFilterElement : SVGElement { readonly attribute SVGAnimatedEnumeration filterUnits; readonly attribute SVGAnimatedEnumeration primitiveUnits; readonly attribute SVGAnimatedLength x; @@ -36,8 +34,8 @@ readonly attribute SVGAnimatedInteger filterResX; readonly attribute SVGAnimatedInteger filterResY; - void setFilterRes([Default=Undefined] optional unsigned long filterResX, - [Default=Undefined] optional unsigned long filterResY); + void setFilterRes(optional unsigned long filterResX = 0, + optional unsigned long filterResY = 0); }; SVGFilterElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp index 09aabf068..d69ddf317 100644 --- a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp +++ b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp @@ -20,19 +20,16 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFilterPrimitiveStandardAttributes.h" -#include "Attribute.h" #include "FilterEffect.h" #include "RenderSVGResourceFilterPrimitive.h" #include "SVGElement.h" -#include "SVGElementInstance.h" #include "SVGFilterBuilder.h" -#include "SVGLength.h" +#include "SVGLengthValue.h" #include "SVGNames.h" #include "SVGUnitTypes.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -66,37 +63,35 @@ SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const bool SVGFilterPrimitiveStandardAttributes::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); - supportedAttributes.add(SVGNames::resultAttr); + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { + supportedAttributes.get().add(SVGNames::xAttr); + supportedAttributes.get().add(SVGNames::yAttr); + supportedAttributes.get().add(SVGNames::widthAttr); + supportedAttributes.get().add(SVGNames::heightAttr); + supportedAttributes.get().add(SVGNames::resultAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGFilterPrimitiveStandardAttributes::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGElement::parseAttribute(name, value); - else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::resultAttr) setResultBaseValue(value); - else - ASSERT_NOT_REACHED(); reportAttributeParsingError(parseError, name, value); + + SVGElement::parseAttribute(name, value); } bool SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect*, const QualifiedName&) @@ -113,7 +108,7 @@ void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedNa return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); invalidate(); } @@ -142,9 +137,9 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(FilterEffect* f filterEffect->setHasHeight(true); } -RenderPtr<RenderElement> SVGFilterPrimitiveStandardAttributes::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGFilterPrimitiveStandardAttributes::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceFilterPrimitive>(*this, std::move(style)); + return createRenderer<RenderSVGResourceFilterPrimitive>(*this, WTFMove(style)); } bool SVGFilterPrimitiveStandardAttributes::rendererIsNeeded(const RenderStyle& style) @@ -173,5 +168,3 @@ void invalidateFilterPrimitiveParent(SVGElement* element) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h index e36c56dcf..7745b83b6 100644 --- a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h +++ b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h @@ -18,17 +18,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFilterPrimitiveStandardAttributes_h -#define SVGFilterPrimitiveStandardAttributes_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "RenderSVGResourceFilter.h" #include "RenderSVGResourceFilterPrimitive.h" #include "SVGAnimatedLength.h" #include "SVGAnimatedString.h" #include "SVGElement.h" - -#include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> namespace WebCore { @@ -41,36 +37,28 @@ class SVGFilterPrimitiveStandardAttributes : public SVGElement { public: void setStandardAttributes(FilterEffect*) const; - virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter* filter) = 0; + virtual RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) = 0; // Returns true, if the new value is different from the old one. virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&); protected: SVGFilterPrimitiveStandardAttributes(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void childrenChanged(const ChildChange&) override; - - inline void invalidate() - { - if (RenderElement* primitiveRenderer = renderer()) - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*primitiveRenderer); - } + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + void childrenChanged(const ChildChange&) override; - inline void primitiveAttributeChanged(const QualifiedName& attribute) - { - if (RenderElement* primitiveRenderer = renderer()) - static_cast<RenderSVGResourceFilterPrimitive*>(primitiveRenderer)->primitiveAttributeChanged(attribute); - } + void invalidate(); + void primitiveAttributeChanged(const QualifiedName& attributeName); private: - virtual bool isFilterEffect() const override { return true; } + bool isFilterEffect() const override { return true; } - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool rendererIsNeeded(const RenderStyle&) override; - virtual bool childShouldCreateRenderer(const Node&) const override { return false; } + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool rendererIsNeeded(const RenderStyle&) override; + bool childShouldCreateRenderer(const Node&) const override { return false; } + + static bool isSupportedAttribute(const QualifiedName&); BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes) DECLARE_ANIMATED_LENGTH(X, x) @@ -83,15 +71,21 @@ private: void invalidateFilterPrimitiveParent(SVGElement*); -void isSVGFilterPrimitiveStandardAttributes(const SVGFilterPrimitiveStandardAttributes&); // Catch unnecessary runtime check of type known at compile time. -inline bool isSVGFilterPrimitiveStandardAttributes(const SVGElement& element) { return element.isFilterEffect(); } -inline bool isSVGFilterPrimitiveStandardAttributes(const Node& node) { return node.isSVGElement() && toSVGElement(node).isFilterEffect(); } -template <> inline bool isElementOfType<const SVGFilterPrimitiveStandardAttributes>(const Element& element) { return isSVGFilterPrimitiveStandardAttributes(element); } - -NODE_TYPE_CASTS(SVGFilterPrimitiveStandardAttributes) +inline void SVGFilterPrimitiveStandardAttributes::invalidate() +{ + if (auto* primitiveRenderer = renderer()) + RenderSVGResource::markForLayoutAndParentResourceInvalidation(*primitiveRenderer); +} +inline void SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged(const QualifiedName& attribute) +{ + if (auto* primitiveRenderer = renderer()) + static_cast<RenderSVGResourceFilterPrimitive*>(primitiveRenderer)->primitiveAttributeChanged(attribute); +} } // namespace WebCore -#endif // ENABLE(SVG) -#endif +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGFilterPrimitiveStandardAttributes) + static bool isType(const WebCore::SVGElement& element) { return element.isFilterEffect(); } + static bool isType(const WebCore::Node& node) { return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.idl b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.idl index 84609571e..69bad4a3e 100644 --- a/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.idl +++ b/Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.idl @@ -26,8 +26,6 @@ [ NoInterfaceObject, - Conditional=SVG, - ObjCProtocol ] interface SVGFilterPrimitiveStandardAttributes { readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; @@ -35,4 +33,3 @@ readonly attribute SVGAnimatedLength height; readonly attribute SVGAnimatedString result; }; - diff --git a/Source/WebCore/svg/SVGFitToViewBox.cpp b/Source/WebCore/svg/SVGFitToViewBox.cpp index 13b04c81c..770f1f419 100644 --- a/Source/WebCore/svg/SVGFitToViewBox.cpp +++ b/Source/WebCore/svg/SVGFitToViewBox.cpp @@ -19,27 +19,24 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGFitToViewBox.h" #include "AffineTransform.h" -#include "Attribute.h" #include "Document.h" #include "FloatRect.h" #include "SVGDocumentExtensions.h" #include "SVGNames.h" #include "SVGParserUtilities.h" -#include "SVGPreserveAspectRatio.h" -#include <wtf/text/StringImpl.h> +#include "SVGPreserveAspectRatioValue.h" +#include <wtf/text/StringView.h> namespace WebCore { bool SVGFitToViewBox::parseViewBox(Document* doc, const String& s, FloatRect& viewBox) { - const UChar* c = s.deprecatedCharacters(); - const UChar* end = c + s.length(); - return parseViewBox(doc, c, end, viewBox, true); + auto upconvertedCharacters = StringView(s).upconvertedCharacters(); + const UChar* characters = upconvertedCharacters; + return parseViewBox(doc, characters, characters + s.length(), viewBox, true); } bool SVGFitToViewBox::parseViewBox(Document* doc, const UChar*& c, const UChar* end, FloatRect& viewBox, bool validate) @@ -58,21 +55,21 @@ bool SVGFitToViewBox::parseViewBox(Document* doc, const UChar*& c, const UChar* return true; } if (!valid) { - doc->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + str + "\""); + doc->accessSVGExtensions().reportWarning("Problem parsing viewBox=\"" + str + "\""); return false; } if (width < 0.0) { // check that width is positive - doc->accessSVGExtensions()->reportError("A negative value for ViewBox width is not allowed"); + doc->accessSVGExtensions().reportError("A negative value for ViewBox width is not allowed"); return false; } if (height < 0.0) { // check that height is positive - doc->accessSVGExtensions()->reportError("A negative value for ViewBox height is not allowed"); + doc->accessSVGExtensions().reportError("A negative value for ViewBox height is not allowed"); return false; } skipOptionalSVGSpaces(c, end); if (c < end) { // nothing should come after the last, fourth number - doc->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + str + "\""); + doc->accessSVGExtensions().reportWarning("Problem parsing viewBox=\"" + str + "\""); return false; } @@ -80,9 +77,9 @@ bool SVGFitToViewBox::parseViewBox(Document* doc, const UChar*& c, const UChar* return true; } -AffineTransform SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatio& preserveAspectRatio, float viewWidth, float viewHeight) +AffineTransform SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatioValue& preserveAspectRatio, float viewWidth, float viewHeight) { - if (!viewBoxRect.width() || !viewBoxRect.height()) + if (!viewBoxRect.width() || !viewBoxRect.height() || !viewWidth || !viewHeight) return AffineTransform(); return preserveAspectRatio.getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), viewWidth, viewHeight); @@ -100,5 +97,3 @@ void SVGFitToViewBox::addSupportedAttributes(HashSet<QualifiedName>& supportedAt } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGFitToViewBox.h b/Source/WebCore/svg/SVGFitToViewBox.h index 02e2a937a..10cd608f5 100644 --- a/Source/WebCore/svg/SVGFitToViewBox.h +++ b/Source/WebCore/svg/SVGFitToViewBox.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFitToViewBox_h -#define SVGFitToViewBox_h +#pragma once -#if ENABLE(SVG) #include "FloatRect.h" #include "QualifiedName.h" #include "SVGNames.h" @@ -35,7 +33,7 @@ class Document; class SVGFitToViewBox { public: - static AffineTransform viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatio&, float viewWidth, float viewHeight); + static AffineTransform viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatioValue&, float viewWidth, float viewHeight); static bool isKnownAttribute(const QualifiedName&); static void addSupportedAttributes(HashSet<QualifiedName>&); @@ -52,7 +50,7 @@ public: } if (name == SVGNames::preserveAspectRatioAttr) { - SVGPreserveAspectRatio preserveAspectRatio; + SVGPreserveAspectRatioValue preserveAspectRatio; preserveAspectRatio.parse(value); target->setPreserveAspectRatioBaseValue(preserveAspectRatio); return true; @@ -68,6 +66,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGFitToViewBox_h diff --git a/Source/WebCore/svg/SVGFitToViewBox.idl b/Source/WebCore/svg/SVGFitToViewBox.idl index 1e6107278..94964cdc2 100644 --- a/Source/WebCore/svg/SVGFitToViewBox.idl +++ b/Source/WebCore/svg/SVGFitToViewBox.idl @@ -26,10 +26,7 @@ [ NoInterfaceObject, - Conditional=SVG, - ObjCProtocol, ] interface SVGFitToViewBox { - readonly attribute SVGAnimatedRect viewBox; + readonly attribute SVGAnimatedRect viewBox; readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; }; - diff --git a/Source/WebCore/svg/SVGFontData.cpp b/Source/WebCore/svg/SVGFontData.cpp deleted file mode 100644 index 25793a5ef..000000000 --- a/Source/WebCore/svg/SVGFontData.cpp +++ /dev/null @@ -1,308 +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. - */ - -#include "config.h" - -#if ENABLE(SVG_FONTS) -#include "SVGFontData.h" - -#include "RenderElement.h" -#include "SVGAltGlyphElement.h" -#include "SVGFontElement.h" -#include "SVGFontFaceElement.h" -#include "SVGGlyph.h" -#include "SVGGlyphElement.h" -#include "SVGNames.h" -#include "SVGTextRunRenderingContext.h" -#include "TextRun.h" -#include "WidthIterator.h" -#include "XMLNames.h" -#include <wtf/text/StringBuilder.h> -#include <wtf/unicode/CharacterNames.h> -#include <wtf/unicode/Unicode.h> - -using namespace WTF; -using namespace Unicode; - -namespace WebCore { - -SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement) - : m_svgFontFaceElement(fontFaceElement) - , m_horizontalOriginX(fontFaceElement->horizontalOriginX()) - , m_horizontalOriginY(fontFaceElement->horizontalOriginY()) - , m_horizontalAdvanceX(fontFaceElement->horizontalAdvanceX()) - , m_verticalOriginX(fontFaceElement->verticalOriginX()) - , m_verticalOriginY(fontFaceElement->verticalOriginY()) - , m_verticalAdvanceY(fontFaceElement->verticalAdvanceY()) -{ - ASSERT_ARG(fontFaceElement, fontFaceElement); -} - -void SVGFontData::initializeFontData(SimpleFontData* fontData, float fontSize) -{ - ASSERT(fontData); - - SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement(); - ASSERT(svgFontFaceElement); - - SVGFontElement* svgFontElement = svgFontFaceElement->associatedFontElement(); - ASSERT(svgFontElement); - GlyphData missingGlyphData; - missingGlyphData.fontData = fontData; - missingGlyphData.glyph = svgFontElement->missingGlyph(); - fontData->setMissingGlyphData(missingGlyphData); - - fontData->setZeroWidthSpaceGlyph(0); - fontData->determinePitch(); - - unsigned unitsPerEm = svgFontFaceElement->unitsPerEm(); - float scale = scaleEmToUnits(fontSize, unitsPerEm); - float xHeight = svgFontFaceElement->xHeight() * scale; - float ascent = svgFontFaceElement->ascent() * scale; - float descent = svgFontFaceElement->descent() * scale; - float lineGap = 0.1f * fontSize; - - GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(fontData, 0)->page(); - - if (!xHeight && glyphPageZero) { - // Fallback if x_heightAttr is not specified for the font element. - Glyph letterXGlyph = glyphPageZero->glyphDataForCharacter('x').glyph; - xHeight = letterXGlyph ? fontData->widthForGlyph(letterXGlyph) : 2 * ascent / 3; - } - - FontMetrics& fontMetrics = fontData->fontMetrics(); - fontMetrics.setUnitsPerEm(unitsPerEm); - fontMetrics.setAscent(ascent); - fontMetrics.setDescent(descent); - fontMetrics.setLineGap(lineGap); - fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap)); - fontMetrics.setXHeight(xHeight); - - if (!glyphPageZero) { - fontData->setSpaceGlyph(0); - fontData->setSpaceWidth(0); - fontData->setAvgCharWidth(0); - fontData->setMaxCharWidth(ascent); - return; - } - - // Calculate space width. - Glyph spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph; - fontData->setSpaceGlyph(spaceGlyph); - fontData->setSpaceWidth(fontData->widthForGlyph(spaceGlyph)); - - // Estimate average character width. - Glyph numeralZeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph; - fontData->setAvgCharWidth(numeralZeroGlyph ? fontData->widthForGlyph(numeralZeroGlyph) : fontData->spaceWidth()); - - // Estimate maximum character width. - Glyph letterWGlyph = glyphPageZero->glyphDataForCharacter('W').glyph; - fontData->setMaxCharWidth(letterWGlyph ? fontData->widthForGlyph(letterWGlyph) : ascent); -} - -float SVGFontData::widthForSVGGlyph(Glyph glyph, float fontSize) const -{ - SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement(); - ASSERT(svgFontFaceElement); - - SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement(); - ASSERT(associatedFontElement); - - SVGGlyph svgGlyph = associatedFontElement->svgGlyphForGlyph(glyph); - SVGGlyphElement::inheritUnspecifiedAttributes(svgGlyph, this); - return svgGlyph.horizontalAdvanceX * scaleEmToUnits(fontSize, svgFontFaceElement->unitsPerEm()); -} - -bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& glyphData, bool mirror, int currentCharacter, unsigned& advanceLength) const -{ - const TextRun& run = iterator.run(); - Vector<SVGGlyph::ArabicForm>& arabicForms = iterator.arabicForms(); - ASSERT(int(run.charactersLength()) >= currentCharacter); - - // Associate text with arabic forms, if needed. - String remainingTextInRun; - - if (run.is8Bit()) { - remainingTextInRun = String(run.data8(currentCharacter), run.charactersLength() - currentCharacter); - remainingTextInRun = Font::normalizeSpaces(remainingTextInRun.characters8(), remainingTextInRun.length()); - } else { - remainingTextInRun = String(run.data16(currentCharacter), run.charactersLength() - currentCharacter); - remainingTextInRun = Font::normalizeSpaces(remainingTextInRun.characters16(), remainingTextInRun.length()); - } - - if (mirror) - remainingTextInRun = createStringWithMirroredCharacters(remainingTextInRun.deprecatedCharacters(), remainingTextInRun.length()); - if (!currentCharacter && arabicForms.isEmpty()) - arabicForms = charactersWithArabicForm(remainingTextInRun, mirror); - - SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement(); - ASSERT(svgFontFaceElement); - - SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement(); - ASSERT(associatedFontElement); - - RenderObject* renderObject = 0; - if (TextRun::RenderingContext* renderingContext = run.renderingContext()) - renderObject = &static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer(); - - String language; - bool isVerticalText = false; - Vector<String> altGlyphNames; - - if (renderObject) { - RenderElement* parentRenderer = renderObject->isRenderElement() ? toRenderElement(renderObject) : renderObject->parent(); - ASSERT(parentRenderer); - - isVerticalText = parentRenderer->style().svgStyle().isVerticalWritingMode(); - if (Element* parentRendererElement = parentRenderer->element()) { - language = parentRendererElement->getAttribute(XMLNames::langAttr); - - if (isSVGAltGlyphElement(parentRendererElement)) { - SVGAltGlyphElement* altGlyph = toSVGAltGlyphElement(parentRendererElement); - if (!altGlyph->hasValidGlyphElements(altGlyphNames)) - altGlyphNames.clear(); - } - } - } - - Vector<SVGGlyph> glyphs; - size_t altGlyphNamesSize = altGlyphNames.size(); - if (altGlyphNamesSize) { - for (size_t index = 0; index < altGlyphNamesSize; ++index) - associatedFontElement->collectGlyphsForGlyphName(altGlyphNames[index], glyphs); - - // Assign the unicodeStringLength now that its known. - size_t glyphsSize = glyphs.size(); - for (size_t i = 0; i < glyphsSize; ++i) - glyphs[i].unicodeStringLength = run.length(); - - // Do not check alt glyphs for compatibility. Just return the first one. - // Later code will fail if we do not do this and the glyph is incompatible. - if (glyphsSize) { - SVGGlyph& svgGlyph = glyphs[0]; - iterator.setLastGlyphName(svgGlyph.glyphName); - glyphData.glyph = svgGlyph.tableEntry; - advanceLength = svgGlyph.unicodeStringLength; - return true; - } - } else - associatedFontElement->collectGlyphsForString(remainingTextInRun, glyphs); - - size_t glyphsSize = glyphs.size(); - for (size_t i = 0; i < glyphsSize; ++i) { - SVGGlyph& svgGlyph = glyphs[i]; - if (svgGlyph.isPartOfLigature) - continue; - if (!isCompatibleGlyph(svgGlyph, isVerticalText, language, arabicForms, currentCharacter, currentCharacter + svgGlyph.unicodeStringLength)) - continue; - iterator.setLastGlyphName(svgGlyph.glyphName); - glyphData.glyph = svgGlyph.tableEntry; - advanceLength = svgGlyph.unicodeStringLength; - return true; - } - - iterator.setLastGlyphName(String()); - return false; -} - -bool SVGFontData::fillSVGGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) const -{ - ASSERT(fontData->isCustomFont()); - ASSERT(fontData->isSVGFont()); - - SVGFontFaceElement* fontFaceElement = this->svgFontFaceElement(); - ASSERT(fontFaceElement); - - SVGFontElement* fontElement = fontFaceElement->associatedFontElement(); - ASSERT(fontElement); - - if (bufferLength == length) - return fillBMPGlyphs(fontElement, pageToFill, offset, length, buffer, fontData); - - ASSERT(bufferLength == 2 * length); - return fillNonBMPGlyphs(fontElement, pageToFill, offset, length, buffer, fontData); -} - -bool SVGFontData::fillBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, const SimpleFontData* fontData) const -{ - bool haveGlyphs = false; - Vector<SVGGlyph> glyphs; - for (unsigned i = 0; i < length; ++i) { - String lookupString(buffer + i, 1); - fontElement->collectGlyphsForString(lookupString, glyphs); - if (glyphs.isEmpty()) { - pageToFill->setGlyphDataForIndex(offset + i, 0, 0); - continue; - } - - // Associate entry in glyph page with first valid SVGGlyph. - // If there are multiple valid ones, just take the first one. WidthIterator will take - // care of matching to the correct glyph, if multiple ones are available, as that's - // only possible within the context of a string (eg. arabic form matching). - haveGlyphs = true; - pageToFill->setGlyphDataForIndex(offset + i, glyphs.first().tableEntry, fontData); - glyphs.clear(); - } - - return haveGlyphs; -} - -bool SVGFontData::fillNonBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, const SimpleFontData* fontData) const -{ - bool haveGlyphs = false; - Vector<SVGGlyph> glyphs; - for (unsigned i = 0; i < length; ++i) { - // Each character here consists of a surrogate pair - String lookupString(buffer + i * 2, 2); - fontElement->collectGlyphsForString(lookupString, glyphs); - if (glyphs.isEmpty()) { - pageToFill->setGlyphDataForIndex(offset + i, 0, 0); - continue; - } - - // Associate entry in glyph page with first valid SVGGlyph. - // If there are multiple valid ones, just take the first one. WidthIterator will take - // care of matching to the correct glyph, if multiple ones are available, as that's - // only possible within the context of a string (eg. arabic form matching). - haveGlyphs = true; - pageToFill->setGlyphDataForIndex(offset + i, glyphs.first().tableEntry, fontData); - glyphs.clear(); - } - - return haveGlyphs; -} - -String SVGFontData::createStringWithMirroredCharacters(const UChar* characters, unsigned length) const -{ - StringBuilder mirroredCharacters; - mirroredCharacters.reserveCapacity(length); - - unsigned i = 0; - while (i < length) { - UChar32 character; - U16_NEXT(characters, i, length, character); - mirroredCharacters.append(u_charMirror(character)); - } - - return mirroredCharacters.toString(); -} - -} // namespace WebCore - -#endif diff --git a/Source/WebCore/svg/SVGFontData.h b/Source/WebCore/svg/SVGFontData.h deleted file mode 100644 index 3fb967cf0..000000000 --- a/Source/WebCore/svg/SVGFontData.h +++ /dev/null @@ -1,77 +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 SVGFontData_h -#define SVGFontData_h - -#if ENABLE(SVG_FONTS) -#include "SimpleFontData.h" - -namespace WebCore { - -class SVGFontElement; -class SVGFontFaceElement; - -class SVGFontData : public SimpleFontData::AdditionalFontData { -public: - explicit SVGFontData(SVGFontFaceElement*); - virtual ~SVGFontData() { } - - virtual void initializeFontData(SimpleFontData*, float fontSize) override; - virtual float widthForSVGGlyph(Glyph, float fontSize) const override; - virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData*) const override; - virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, int currentCharacter, unsigned& advanceLength) const override; - - SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement; } - - float horizontalOriginX() const { return m_horizontalOriginX; } - float horizontalOriginY() const { return m_horizontalOriginY; } - float horizontalAdvanceX() const { return m_horizontalAdvanceX; } - - float verticalOriginX() const { return m_verticalOriginX; } - float verticalOriginY() const { return m_verticalOriginY; } - float verticalAdvanceY() const { return m_verticalAdvanceY; } - -private: - bool fillBMPGlyphs(SVGFontElement*, GlyphPage* , unsigned offset, unsigned length, UChar* buffer, const SimpleFontData*) const; - bool fillNonBMPGlyphs(SVGFontElement*, GlyphPage* , unsigned offset, unsigned length, UChar* buffer, const SimpleFontData*) const; - - String createStringWithMirroredCharacters(const UChar* characters, unsigned length) const; - - // Ths SVGFontFaceElement is kept alive -- - // 1) in the external font case: by the CSSFontFaceSource, which holds a reference to the external SVG document - // containing the element; - // 2) in the in-document font case: by virtue of being in the document tree and making sure that when it is removed - // from the document, it removes the @font-face rule it owns from the document's mapped element sheet and forces - // a style update. - SVGFontFaceElement* m_svgFontFaceElement; - - float m_horizontalOriginX; - float m_horizontalOriginY; - float m_horizontalAdvanceX; - - float m_verticalOriginX; - float m_verticalOriginY; - float m_verticalAdvanceY; -}; - -} // namespace WebCore - -#endif -#endif // SVGFontData_h diff --git a/Source/WebCore/svg/SVGFontElement.cpp b/Source/WebCore/svg/SVGFontElement.cpp index c0355239f..6427281be 100644 --- a/Source/WebCore/svg/SVGFontElement.cpp +++ b/Source/WebCore/svg/SVGFontElement.cpp @@ -26,8 +26,7 @@ #include "Document.h" #include "ElementIterator.h" -#include "Font.h" -#include "GlyphPageTreeNode.h" +#include "FontCascade.h" #include "SVGGlyphElement.h" #include "SVGHKernElement.h" #include "SVGMissingGlyphElement.h" @@ -47,278 +46,14 @@ END_REGISTER_ANIMATED_PROPERTIES inline SVGFontElement::SVGFontElement(const QualifiedName& tagName, Document& document) : SVGElement(tagName, document) - , m_missingGlyph(0) - , m_isGlyphCacheValid(false) { ASSERT(hasTagName(SVGNames::fontTag)); registerAnimatedPropertiesForSVGFontElement(); } -PassRefPtr<SVGFontElement> SVGFontElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFontElement> SVGFontElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFontElement(tagName, document)); -} - -void SVGFontElement::invalidateGlyphCache() -{ - if (m_isGlyphCacheValid) { - m_glyphMap.clear(); - m_horizontalKerningMap.clear(); - m_verticalKerningMap.clear(); - } - m_isGlyphCacheValid = false; -} - -const SVGMissingGlyphElement* SVGFontElement::firstMissingGlyphElement() const -{ - return childrenOfType<SVGMissingGlyphElement>(*this).first(); -} - -void SVGFontElement::registerLigaturesInGlyphCache(Vector<String>& ligatures) -{ - ASSERT(!ligatures.isEmpty()); - - // Register each character of a ligature in the map, if not present. - // Eg. If only a "fi" ligature is present, but not "f" and "i", the - // GlyphPage will not contain any entries for "f" and "i", so the - // SVGFont is not used to render the text "fi1234". Register an - // empty SVGGlyph with the character, so the SVG Font will be used - // to render the text. If someone tries to render "f2" the SVG Font - // will not be able to find a glyph for "f", but handles the fallback - // character substitution properly through glyphDataForCharacter(). - Vector<SVGGlyph> glyphs; - size_t ligaturesSize = ligatures.size(); - for (size_t i = 0; i < ligaturesSize; ++i) { - const String& unicode = ligatures[i]; - - unsigned unicodeLength = unicode.length(); - ASSERT(unicodeLength > 1); - - const UChar* characters = unicode.deprecatedCharacters(); - for (unsigned i = 0; i < unicodeLength; ++i) { - String lookupString(characters + i, 1); - m_glyphMap.collectGlyphsForString(lookupString, glyphs); - if (!glyphs.isEmpty()) { - glyphs.clear(); - continue; - } - - // This glyph is never meant to be used for rendering, only as identifier as a part of a ligature. - SVGGlyph newGlyphPart; - newGlyphPart.isPartOfLigature = true; - m_glyphMap.addGlyph(String(), lookupString, newGlyphPart); - } - } -} - -void SVGFontElement::ensureGlyphCache() -{ - if (m_isGlyphCacheValid) - return; - - const SVGMissingGlyphElement* firstMissingGlyphElement = nullptr; - Vector<String> ligatures; - for (auto& child : childrenOfType<SVGElement>(*this)) { - if (isSVGGlyphElement(child)) { - SVGGlyphElement& glyph = toSVGGlyphElement(child); - AtomicString unicode = glyph.fastGetAttribute(SVGNames::unicodeAttr); - AtomicString glyphId = glyph.getIdAttribute(); - if (glyphId.isEmpty() && unicode.isEmpty()) - continue; - - m_glyphMap.addGlyph(glyphId, unicode, glyph.buildGlyphIdentifier()); - - // Register ligatures, if needed, don't mix up with surrogate pairs though! - if (unicode.length() > 1 && !U16_IS_SURROGATE(unicode[0])) - ligatures.append(unicode.string()); - } else if (isSVGHKernElement(child)) { - SVGHKernElement& hkern = toSVGHKernElement(child); - hkern.buildHorizontalKerningPair(m_horizontalKerningMap); - } else if (isSVGVKernElement(child)) { - SVGVKernElement& vkern = toSVGVKernElement(child); - vkern.buildVerticalKerningPair(m_verticalKerningMap); - } else if (isSVGMissingGlyphElement(child) && !firstMissingGlyphElement) - firstMissingGlyphElement = &toSVGMissingGlyphElement(child); - } - - // Register each character of each ligature, if needed. - if (!ligatures.isEmpty()) - registerLigaturesInGlyphCache(ligatures); - - // Register missing-glyph element, if present. - if (firstMissingGlyphElement) { - SVGGlyph svgGlyph = SVGGlyphElement::buildGenericGlyphIdentifier(firstMissingGlyphElement); - m_glyphMap.appendToGlyphTable(svgGlyph); - m_missingGlyph = svgGlyph.tableEntry; - ASSERT(m_missingGlyph > 0); - } - - m_isGlyphCacheValid = true; -} - -void SVGKerningMap::clear() -{ - unicodeMap.clear(); - glyphMap.clear(); - kerningUnicodeRangeMap.clear(); -} - -void SVGKerningMap::insert(const SVGKerningPair& kerningPair) -{ - SVGKerning svgKerning; - svgKerning.kerning = kerningPair.kerning; - svgKerning.unicodeRange2 = kerningPair.unicodeRange2; - svgKerning.unicodeName2 = kerningPair.unicodeName2; - svgKerning.glyphName2 = kerningPair.glyphName2; - - HashSet<String>::const_iterator uIt = kerningPair.unicodeName1.begin(); - const HashSet<String>::const_iterator uEnd = kerningPair.unicodeName1.end(); - for (; uIt != uEnd; ++uIt) { - if (unicodeMap.contains(*uIt)) - unicodeMap.get(*uIt)->append(svgKerning); - else { - auto newVector = std::make_unique<SVGKerningVector>(); - newVector->append(svgKerning); - unicodeMap.add(*uIt, std::move(newVector)); - } - } - - HashSet<String>::const_iterator gIt = kerningPair.glyphName1.begin(); - const HashSet<String>::const_iterator gEnd = kerningPair.glyphName1.end(); - for (; gIt != gEnd; ++gIt) { - if (glyphMap.contains(*gIt)) - glyphMap.get(*gIt)->append(svgKerning); - else { - auto newVector = std::make_unique<SVGKerningVector>(); - newVector->append(svgKerning); - glyphMap.add(*gIt, std::move(newVector)); - } - } - - if (!kerningPair.unicodeRange1.isEmpty()) - kerningUnicodeRangeMap.append(kerningPair); -} - -static inline bool stringMatchesUnicodeRange(const String& unicodeString, const UnicodeRanges& ranges) -{ - if (unicodeString.isEmpty()) - return false; - - if (!ranges.isEmpty()) { - UChar firstChar = unicodeString[0]; - const UnicodeRanges::const_iterator end = ranges.end(); - for (UnicodeRanges::const_iterator it = ranges.begin(); it != end; ++it) { - if (firstChar >= it->first && firstChar <= it->second) - return true; - } - } - - return false; -} - -static inline bool stringMatchesGlyphName(const String& glyphName, const HashSet<String>& glyphValues) -{ - if (glyphName.isEmpty()) - return false; - - return glyphValues.contains(glyphName); -} - -static inline bool stringMatchesUnicodeName(const String& unicodeName, const HashSet<String>& unicodeValues) -{ - if (unicodeName.isEmpty()) - return false; - - return unicodeValues.contains(unicodeName); -} - -static inline bool matches(const String& u2, const String& g2, const SVGKerning& svgKerning) -{ - return stringMatchesGlyphName(g2, svgKerning.glyphName2) - || stringMatchesUnicodeName(u2, svgKerning.unicodeName2) - || stringMatchesUnicodeRange(u2, svgKerning.unicodeRange2); -} - -static inline bool matches(const String& u1, const String& u2, const String& g2, const SVGKerningPair& svgKerningPair) -{ - return stringMatchesUnicodeRange(u1, svgKerningPair.unicodeRange1) && matches(u2, g2, svgKerningPair); -} - -static inline float kerningForPairOfStringsAndGlyphs(const SVGKerningMap& kerningMap, const String& u1, const String& g1, const String& u2, const String& g2) -{ - if (!g1.isEmpty() && kerningMap.glyphMap.contains(g1)) { - SVGKerningVector* kerningVector = kerningMap.glyphMap.get(g1); - SVGKerningVector::const_iterator it = kerningVector->end() - 1; - const SVGKerningVector::const_iterator begin = kerningVector->begin() - 1; - for (; it != begin; --it) { - if (matches(u2, g2, *it)) - return it->kerning; - } - } - - if (!u1.isEmpty()) { - if (kerningMap.unicodeMap.contains(u1)) { - SVGKerningVector* kerningVector = kerningMap.unicodeMap.get(u1); - SVGKerningVector::const_iterator it = kerningVector->end() - 1; - const SVGKerningVector::const_iterator begin = kerningVector->begin() - 1; - for (; it != begin; --it) { - if (matches(u2, g2, *it)) - return it->kerning; - } - } - - if (!kerningMap.kerningUnicodeRangeMap.isEmpty()) { - Vector<SVGKerningPair>::const_iterator it = kerningMap.kerningUnicodeRangeMap.end() - 1; - const Vector<SVGKerningPair>::const_iterator begin = kerningMap.kerningUnicodeRangeMap.begin() - 1; - for (; it != begin; --it) { - if (matches(u1, u2, g2, *it)) - return it->kerning; - } - } - } - - return 0; -} - -float SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const -{ - if (m_horizontalKerningMap.isEmpty()) - return 0; - - return kerningForPairOfStringsAndGlyphs(m_horizontalKerningMap, u1, g1, u2, g2); -} - -float SVGFontElement::verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const -{ - if (m_verticalKerningMap.isEmpty()) - return 0; - - return kerningForPairOfStringsAndGlyphs(m_verticalKerningMap, u1, g1, u2, g2); -} - -void SVGFontElement::collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs) -{ - ensureGlyphCache(); - m_glyphMap.collectGlyphsForString(string, glyphs); -} - -void SVGFontElement::collectGlyphsForGlyphName(const String& glyphName, Vector<SVGGlyph>& glyphs) -{ - ensureGlyphCache(); - // FIXME: We only support glyphName -> single glyph mapping so far. - glyphs.append(m_glyphMap.glyphIdentifierForGlyphName(glyphName)); -} - -SVGGlyph SVGFontElement::svgGlyphForGlyph(Glyph glyph) -{ - ensureGlyphCache(); - return m_glyphMap.svgGlyphForGlyph(glyph); -} - -Glyph SVGFontElement::missingGlyph() -{ - ensureGlyphCache(); - return m_missingGlyph; + return adoptRef(*new SVGFontElement(tagName, document)); } } diff --git a/Source/WebCore/svg/SVGFontElement.h b/Source/WebCore/svg/SVGFontElement.h index 89f3b3306..52246bc9a 100644 --- a/Source/WebCore/svg/SVGFontElement.h +++ b/Source/WebCore/svg/SVGFontElement.h @@ -19,91 +19,44 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFontElement_h -#define SVGFontElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGAnimatedBoolean.h" #include "SVGElement.h" #include "SVGExternalResourcesRequired.h" -#include "SVGGlyphMap.h" #include "SVGParserUtilities.h" namespace WebCore { -// Describe an SVG <hkern>/<vkern> element already matched on the first symbol. -struct SVGKerning { - float kerning; - UnicodeRanges unicodeRange2; - HashSet<String> unicodeName2; - HashSet<String> glyphName2; - - SVGKerning() - : kerning(0) - { } -}; - // Describe an SVG <hkern>/<vkern> element -struct SVGKerningPair : public SVGKerning { +struct SVGKerningPair { UnicodeRanges unicodeRange1; HashSet<String> unicodeName1; HashSet<String> glyphName1; -}; - -typedef Vector<SVGKerning> SVGKerningVector; -struct SVGKerningMap { - HashMap<String, std::unique_ptr<SVGKerningVector>> unicodeMap; - HashMap<String, std::unique_ptr<SVGKerningVector>> glyphMap; - Vector<SVGKerningPair> kerningUnicodeRangeMap; - - bool isEmpty() const { return unicodeMap.isEmpty() && glyphMap.isEmpty() && kerningUnicodeRangeMap.isEmpty(); } - void clear(); - void insert(const SVGKerningPair&); + UnicodeRanges unicodeRange2; + HashSet<String> unicodeName2; + HashSet<String> glyphName2; + float kerning { 0 }; }; -class SVGMissingGlyphElement; - class SVGFontElement final : public SVGElement , public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGFontElement> create(const QualifiedName&, Document&); - - void invalidateGlyphCache(); - void collectGlyphsForString(const String&, Vector<SVGGlyph>&); - void collectGlyphsForGlyphName(const String&, Vector<SVGGlyph>&); - - float horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const; - float verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const; - - // Used by SimpleFontData/WidthIterator. - SVGGlyph svgGlyphForGlyph(Glyph); - Glyph missingGlyph(); - - const SVGMissingGlyphElement* firstMissingGlyphElement() const; + static Ref<SVGFontElement> create(const QualifiedName&, Document&); private: SVGFontElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } - - void ensureGlyphCache(); - void registerLigaturesInGlyphCache(Vector<String>&); + bool rendererIsNeeded(const RenderStyle&) final { return false; } BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFontElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES - - SVGKerningMap m_horizontalKerningMap; - SVGKerningMap m_verticalKerningMap; - SVGGlyphMap m_glyphMap; - Glyph m_missingGlyph; - bool m_isGlyphCacheValid; }; -NODE_TYPE_CASTS(SVGFontElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif diff --git a/Source/WebCore/svg/SVGFontElement.idl b/Source/WebCore/svg/SVGFontElement.idl index feef70665..7c8b9ffef 100644 --- a/Source/WebCore/svg/SVGFontElement.idl +++ b/Source/WebCore/svg/SVGFontElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGFontElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGFontFaceElement.cpp b/Source/WebCore/svg/SVGFontFaceElement.cpp index beac300e7..4a93c7e28 100644 --- a/Source/WebCore/svg/SVGFontFaceElement.cpp +++ b/Source/WebCore/svg/SVGFontFaceElement.cpp @@ -24,7 +24,6 @@ #if ENABLE(SVG_FONTS) #include "SVGFontFaceElement.h" -#include "Attribute.h" #include "CSSFontFaceSrcValue.h" #include "CSSParser.h" #include "CSSPropertyNames.h" @@ -33,7 +32,7 @@ #include "CSSValueList.h" #include "Document.h" #include "ElementIterator.h" -#include "Font.h" +#include "FontCascade.h" #include "SVGDocumentExtensions.h" #include "SVGFontElement.h" #include "SVGFontFaceSrcElement.h" @@ -42,6 +41,7 @@ #include "StyleProperties.h" #include "StyleResolver.h" #include "StyleRule.h" +#include "StyleScope.h" #include <math.h> namespace WebCore { @@ -50,15 +50,15 @@ using namespace SVGNames; inline SVGFontFaceElement::SVGFontFaceElement(const QualifiedName& tagName, Document& document) : SVGElement(tagName, document) - , m_fontFaceRule(StyleRuleFontFace::create(MutableStyleProperties::create(CSSStrictMode))) - , m_fontElement(0) + , m_fontFaceRule(StyleRuleFontFace::create(MutableStyleProperties::create(HTMLStandardMode))) + , m_fontElement(nullptr) { ASSERT(hasTagName(font_faceTag)); } -PassRefPtr<SVGFontFaceElement> SVGFontFaceElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFontFaceElement> SVGFontFaceElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFontFaceElement(tagName, document)); + return adoptRef(*new SVGFontFaceElement(tagName, document)); } void SVGFontFaceElement::parseAttribute(const QualifiedName& name, const AtomicString& value) @@ -75,16 +75,21 @@ void SVGFontFaceElement::parseAttribute(const QualifiedName& name, const AtomicS unsigned SVGFontFaceElement::unitsPerEm() const { - const AtomicString& value = fastGetAttribute(units_per_emAttr); + const AtomicString& value = attributeWithoutSynchronization(units_per_emAttr); if (value.isEmpty()) - return gDefaultUnitsPerEm; + return FontMetrics::defaultUnitsPerEm; return static_cast<unsigned>(ceilf(value.toFloat())); } int SVGFontFaceElement::xHeight() const { - return static_cast<int>(ceilf(fastGetAttribute(x_heightAttr).toFloat())); + return static_cast<int>(ceilf(attributeWithoutSynchronization(x_heightAttr).toFloat())); +} + +int SVGFontFaceElement::capHeight() const +{ + return static_cast<int>(ceilf(attributeWithoutSynchronization(cap_heightAttr).toFloat())); } float SVGFontFaceElement::horizontalOriginX() const @@ -95,7 +100,7 @@ float SVGFontFaceElement::horizontalOriginX() const // Spec: The X-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing horizontally oriented text. (Note that the origin applies to all glyphs in the font.) // If the attribute is not specified, the effect is as if a value of "0" were specified. - return m_fontElement->fastGetAttribute(horiz_origin_xAttr).toFloat(); + return m_fontElement->attributeWithoutSynchronization(horiz_origin_xAttr).toFloat(); } float SVGFontFaceElement::horizontalOriginY() const @@ -106,7 +111,7 @@ float SVGFontFaceElement::horizontalOriginY() const // Spec: The Y-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing horizontally oriented text. (Note that the origin applies to all glyphs in the font.) // If the attribute is not specified, the effect is as if a value of "0" were specified. - return m_fontElement->fastGetAttribute(horiz_origin_yAttr).toFloat(); + return m_fontElement->attributeWithoutSynchronization(horiz_origin_yAttr).toFloat(); } float SVGFontFaceElement::horizontalAdvanceX() const @@ -117,7 +122,7 @@ float SVGFontFaceElement::horizontalAdvanceX() const // Spec: The default horizontal advance after rendering a glyph in horizontal orientation. Glyph // widths are required to be non-negative, even if the glyph is typically rendered right-to-left, // as in Hebrew and Arabic scripts. - return m_fontElement->fastGetAttribute(horiz_adv_xAttr).toFloat(); + return m_fontElement->attributeWithoutSynchronization(horiz_adv_xAttr).toFloat(); } float SVGFontFaceElement::verticalOriginX() const @@ -128,7 +133,7 @@ float SVGFontFaceElement::verticalOriginX() const // Spec: The default X-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing vertically oriented text. If the attribute is not specified, the effect is as if the attribute // were set to half of the effective value of attribute horiz-adv-x. - const AtomicString& value = m_fontElement->fastGetAttribute(vert_origin_xAttr); + const AtomicString& value = m_fontElement->attributeWithoutSynchronization(vert_origin_xAttr); if (value.isEmpty()) return horizontalAdvanceX() / 2.0f; @@ -143,7 +148,7 @@ float SVGFontFaceElement::verticalOriginY() const // Spec: The default Y-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing vertically oriented text. If the attribute is not specified, the effect is as if the attribute // were set to the position specified by the font's ascent attribute. - const AtomicString& value = m_fontElement->fastGetAttribute(vert_origin_yAttr); + const AtomicString& value = m_fontElement->attributeWithoutSynchronization(vert_origin_yAttr); if (value.isEmpty()) return ascent(); @@ -157,7 +162,7 @@ float SVGFontFaceElement::verticalAdvanceY() const // Spec: The default vertical advance after rendering a glyph in vertical orientation. If the attribute is // not specified, the effect is as if a value equivalent of one em were specified (see units-per-em). - const AtomicString& value = m_fontElement->fastGetAttribute(vert_adv_yAttr); + const AtomicString& value = m_fontElement->attributeWithoutSynchronization(vert_adv_yAttr); if (value.isEmpty()) return 1.0f; @@ -170,12 +175,12 @@ int SVGFontFaceElement::ascent() const // unaccented height of the font within the font coordinate system. If the attribute is not specified, // the effect is as if the attribute were set to the difference between the units-per-em value and the // vert-origin-y value for the corresponding font. - const AtomicString& ascentValue = fastGetAttribute(ascentAttr); + const AtomicString& ascentValue = attributeWithoutSynchronization(ascentAttr); if (!ascentValue.isEmpty()) return static_cast<int>(ceilf(ascentValue.toFloat())); if (m_fontElement) { - const AtomicString& vertOriginY = m_fontElement->fastGetAttribute(vert_origin_yAttr); + const AtomicString& vertOriginY = m_fontElement->attributeWithoutSynchronization(vert_origin_yAttr); if (!vertOriginY.isEmpty()) return static_cast<int>(unitsPerEm()) - static_cast<int>(ceilf(vertOriginY.toFloat())); } @@ -189,7 +194,7 @@ int SVGFontFaceElement::descent() const // Spec: Same syntax and semantics as the 'descent' descriptor within an @font-face rule. The maximum // unaccented depth of the font within the font coordinate system. If the attribute is not specified, // the effect is as if the attribute were set to the vert-origin-y value for the corresponding font. - const AtomicString& descentValue = fastGetAttribute(descentAttr); + const AtomicString& descentValue = attributeWithoutSynchronization(descentAttr); if (!descentValue.isEmpty()) { // 14 different W3C SVG 1.1 testcases use a negative descent value, // where a positive was meant to be used Including: @@ -199,7 +204,7 @@ int SVGFontFaceElement::descent() const } if (m_fontElement) { - const AtomicString& vertOriginY = m_fontElement->fastGetAttribute(vert_origin_yAttr); + const AtomicString& vertOriginY = m_fontElement->attributeWithoutSynchronization(vert_origin_yAttr); if (!vertOriginY.isEmpty()) return static_cast<int>(ceilf(vertOriginY.toFloat())); } @@ -216,13 +221,13 @@ String SVGFontFaceElement::fontFamily() const SVGFontElement* SVGFontFaceElement::associatedFontElement() const { ASSERT(parentNode() == m_fontElement); - ASSERT(!parentNode() || isSVGFontElement(parentNode())); + ASSERT(!parentNode() || is<SVGFontElement>(*parentNode())); return m_fontElement; } void SVGFontFaceElement::rebuildFontFace() { - if (!inDocument()) { + if (!isConnected()) { ASSERT(!m_fontElement); return; } @@ -230,16 +235,16 @@ void SVGFontFaceElement::rebuildFontFace() // we currently ignore all but the first src element, alternatively we could concat them auto srcElement = childrenOfType<SVGFontFaceSrcElement>(*this).first(); - bool describesParentFont = isSVGFontElement(parentNode()); + bool describesParentFont = is<SVGFontElement>(*parentNode()); RefPtr<CSSValueList> list; if (describesParentFont) { - m_fontElement = toSVGFontElement(parentNode()); + m_fontElement = downcast<SVGFontElement>(parentNode()); list = CSSValueList::createCommaSeparated(); list->append(CSSFontFaceSrcValue::createLocal(fontFamily())); } else { - m_fontElement = 0; + m_fontElement = nullptr; if (srcElement) list = srcElement->srcValue(); } @@ -253,26 +258,26 @@ void SVGFontFaceElement::rebuildFontFace() if (describesParentFont) { // Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves. RefPtr<CSSValue> src = m_fontFaceRule->properties().getPropertyCSSValue(CSSPropertySrc); - CSSValueList* srcList = toCSSValueList(src.get()); + CSSValueList* srcList = downcast<CSSValueList>(src.get()); unsigned srcLength = srcList ? srcList->length() : 0; - for (unsigned i = 0; i < srcLength; i++) { - if (CSSFontFaceSrcValue* item = toCSSFontFaceSrcValue(srcList->itemWithoutBoundsCheck(i))) + for (unsigned i = 0; i < srcLength; ++i) { + if (CSSFontFaceSrcValue* item = downcast<CSSFontFaceSrcValue>(srcList->itemWithoutBoundsCheck(i))) item->setSVGFontFaceElement(this); } } - document().styleResolverChanged(DeferRecalcStyle); + document().styleScope().didChangeStyleSheetEnvironment(); } Node::InsertionNotificationRequest SVGFontFaceElement::insertedInto(ContainerNode& rootParent) { SVGElement::insertedInto(rootParent); - if (!rootParent.inDocument()) { + if (!rootParent.isConnected()) { ASSERT(!m_fontElement); return InsertionDone; } - document().accessSVGExtensions()->registerSVGFontFaceElement(this); + document().accessSVGExtensions().registerSVGFontFaceElement(this); rebuildFontFace(); return InsertionDone; @@ -282,12 +287,12 @@ void SVGFontFaceElement::removedFrom(ContainerNode& rootParent) { SVGElement::removedFrom(rootParent); - if (rootParent.inDocument()) { - m_fontElement = 0; - document().accessSVGExtensions()->unregisterSVGFontFaceElement(this); + if (rootParent.isConnected()) { + m_fontElement = nullptr; + document().accessSVGExtensions().unregisterSVGFontFaceElement(this); m_fontFaceRule->mutableProperties().clear(); - document().styleResolverChanged(DeferRecalcStyle); + document().styleScope().didChangeStyleSheetEnvironment(); } else ASSERT(!m_fontElement); } diff --git a/Source/WebCore/svg/SVGFontFaceElement.h b/Source/WebCore/svg/SVGFontFaceElement.h index 6a2116a95..5afef2c89 100644 --- a/Source/WebCore/svg/SVGFontFaceElement.h +++ b/Source/WebCore/svg/SVGFontFaceElement.h @@ -19,10 +19,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFontFaceElement_h -#define SVGFontFaceElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGElement.h" namespace WebCore { @@ -32,10 +32,11 @@ class StyleRuleFontFace; class SVGFontFaceElement final : public SVGElement { public: - static PassRefPtr<SVGFontFaceElement> create(const QualifiedName&, Document&); + static Ref<SVGFontFaceElement> create(const QualifiedName&, Document&); unsigned unitsPerEm() const; int xHeight() const; + int capHeight() const; float horizontalOriginX() const; float horizontalOriginY() const; float horizontalAdvanceX() const; @@ -49,28 +50,23 @@ public: SVGFontElement* associatedFontElement() const; void rebuildFontFace(); - StyleRuleFontFace* fontFaceRule() const { return m_fontFaceRule.get(); } + StyleRuleFontFace& fontFaceRule() { return m_fontFaceRule.get(); } private: SVGFontFaceElement(const QualifiedName&, Document&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; - virtual void childrenChanged(const ChildChange&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + void childrenChanged(const ChildChange&) final; + InsertionNotificationRequest insertedInto(ContainerNode&) final; + void removedFrom(ContainerNode&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } - RefPtr<StyleRuleFontFace> m_fontFaceRule; + Ref<StyleRuleFontFace> m_fontFaceRule; SVGFontElement* m_fontElement; }; -NODE_TYPE_CASTS(SVGFontFaceElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFontFaceElement.idl b/Source/WebCore/svg/SVGFontFaceElement.idl index aa2a39515..1286a4e46 100644 --- a/Source/WebCore/svg/SVGFontFaceElement.idl +++ b/Source/WebCore/svg/SVGFontFaceElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGFontFaceElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGFontFaceFormatElement.cpp b/Source/WebCore/svg/SVGFontFaceFormatElement.cpp index ac7801175..591606532 100644 --- a/Source/WebCore/svg/SVGFontFaceFormatElement.cpp +++ b/Source/WebCore/svg/SVGFontFaceFormatElement.cpp @@ -35,9 +35,9 @@ inline SVGFontFaceFormatElement::SVGFontFaceFormatElement(const QualifiedName& t ASSERT(hasTagName(font_face_formatTag)); } -PassRefPtr<SVGFontFaceFormatElement> SVGFontFaceFormatElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFontFaceFormatElement> SVGFontFaceFormatElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFontFaceFormatElement(tagName, document)); + return adoptRef(*new SVGFontFaceFormatElement(tagName, document)); } void SVGFontFaceFormatElement::childrenChanged(const ChildChange& change) @@ -53,7 +53,7 @@ void SVGFontFaceFormatElement::childrenChanged(const ChildChange& change) ancestor = ancestor->parentNode(); if (ancestor && ancestor->hasTagName(font_faceTag)) - toSVGFontFaceElement(ancestor)->rebuildFontFace(); + downcast<SVGFontFaceElement>(*ancestor).rebuildFontFace(); } } diff --git a/Source/WebCore/svg/SVGFontFaceFormatElement.h b/Source/WebCore/svg/SVGFontFaceFormatElement.h index 344299580..803c464b5 100644 --- a/Source/WebCore/svg/SVGFontFaceFormatElement.h +++ b/Source/WebCore/svg/SVGFontFaceFormatElement.h @@ -17,28 +17,25 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFontFaceFormatElement_h -#define SVGFontFaceFormatElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGElement.h" namespace WebCore { class SVGFontFaceFormatElement final : public SVGElement { public: - static PassRefPtr<SVGFontFaceFormatElement> create(const QualifiedName&, Document&); + static Ref<SVGFontFaceFormatElement> create(const QualifiedName&, Document&); private: SVGFontFaceFormatElement(const QualifiedName&, Document&); - virtual void childrenChanged(const ChildChange&) override; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + void childrenChanged(const ChildChange&) final; + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFontFaceFormatElement.idl b/Source/WebCore/svg/SVGFontFaceFormatElement.idl index 837402cf6..e46857912 100644 --- a/Source/WebCore/svg/SVGFontFaceFormatElement.idl +++ b/Source/WebCore/svg/SVGFontFaceFormatElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGFontFaceFormatElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGFontFaceNameElement.cpp b/Source/WebCore/svg/SVGFontFaceNameElement.cpp index 1def9e437..f90d92259 100644 --- a/Source/WebCore/svg/SVGFontFaceNameElement.cpp +++ b/Source/WebCore/svg/SVGFontFaceNameElement.cpp @@ -33,17 +33,17 @@ inline SVGFontFaceNameElement::SVGFontFaceNameElement(const QualifiedName& tagNa ASSERT(hasTagName(SVGNames::font_face_nameTag)); } -PassRefPtr<SVGFontFaceNameElement> SVGFontFaceNameElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFontFaceNameElement> SVGFontFaceNameElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFontFaceNameElement(tagName, document)); + return adoptRef(*new SVGFontFaceNameElement(tagName, document)); } -PassRef<CSSFontFaceSrcValue> SVGFontFaceNameElement::srcValue() const +Ref<CSSFontFaceSrcValue> SVGFontFaceNameElement::srcValue() const { - return CSSFontFaceSrcValue::createLocal(fastGetAttribute(SVGNames::nameAttr)); + return CSSFontFaceSrcValue::createLocal(attributeWithoutSynchronization(SVGNames::nameAttr)); } } -#endif // ENABLE(SVG) +#endif // ENABLE(SVG_FONTS) diff --git a/Source/WebCore/svg/SVGFontFaceNameElement.h b/Source/WebCore/svg/SVGFontFaceNameElement.h index 3f25445fa..5e2b45c0b 100644 --- a/Source/WebCore/svg/SVGFontFaceNameElement.h +++ b/Source/WebCore/svg/SVGFontFaceNameElement.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFontFaceNameElement_h -#define SVGFontFaceNameElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGElement.h" namespace WebCore { @@ -29,21 +29,16 @@ class CSSFontFaceSrcValue; class SVGFontFaceNameElement final : public SVGElement { public: - static PassRefPtr<SVGFontFaceNameElement> create(const QualifiedName&, Document&); + static Ref<SVGFontFaceNameElement> create(const QualifiedName&, Document&); - PassRef<CSSFontFaceSrcValue> srcValue() const; + Ref<CSSFontFaceSrcValue> srcValue() const; private: SVGFontFaceNameElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGFontFaceNameElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFontFaceNameElement.idl b/Source/WebCore/svg/SVGFontFaceNameElement.idl index 7288cd25c..4f41fceed 100644 --- a/Source/WebCore/svg/SVGFontFaceNameElement.idl +++ b/Source/WebCore/svg/SVGFontFaceNameElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGFontFaceNameElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGFontFaceSrcElement.cpp b/Source/WebCore/svg/SVGFontFaceSrcElement.cpp index 4848bc2b7..d6b934142 100644 --- a/Source/WebCore/svg/SVGFontFaceSrcElement.cpp +++ b/Source/WebCore/svg/SVGFontFaceSrcElement.cpp @@ -40,22 +40,22 @@ inline SVGFontFaceSrcElement::SVGFontFaceSrcElement(const QualifiedName& tagName ASSERT(hasTagName(font_face_srcTag)); } -PassRefPtr<SVGFontFaceSrcElement> SVGFontFaceSrcElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFontFaceSrcElement> SVGFontFaceSrcElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFontFaceSrcElement(tagName, document)); + return adoptRef(*new SVGFontFaceSrcElement(tagName, document)); } -PassRefPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const +Ref<CSSValueList> SVGFontFaceSrcElement::srcValue() const { - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); + Ref<CSSValueList> list = CSSValueList::createCommaSeparated(); for (auto& child : childrenOfType<SVGElement>(*this)) { RefPtr<CSSFontFaceSrcValue> srcValue; - if (isSVGFontFaceUriElement(child)) - srcValue = toSVGFontFaceUriElement(child).srcValue(); - else if (isSVGFontFaceNameElement(child)) - srcValue = toSVGFontFaceNameElement(child).srcValue(); + if (is<SVGFontFaceUriElement>(child)) + srcValue = downcast<SVGFontFaceUriElement>(child).srcValue(); + else if (is<SVGFontFaceNameElement>(child)) + srcValue = downcast<SVGFontFaceNameElement>(child).srcValue(); if (srcValue && srcValue->resource().length()) - list->append(srcValue.release()); + list->append(srcValue.releaseNonNull()); } return list; } @@ -63,8 +63,8 @@ PassRefPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const void SVGFontFaceSrcElement::childrenChanged(const ChildChange& change) { SVGElement::childrenChanged(change); - if (parentNode() && parentNode()->hasTagName(font_faceTag)) - toSVGFontFaceElement(parentNode())->rebuildFontFace(); + if (is<SVGFontFaceElement>(parentNode())) + downcast<SVGFontFaceElement>(*parentNode()).rebuildFontFace(); } } diff --git a/Source/WebCore/svg/SVGFontFaceSrcElement.h b/Source/WebCore/svg/SVGFontFaceSrcElement.h index 3b0914c12..2f5112ae4 100644 --- a/Source/WebCore/svg/SVGFontFaceSrcElement.h +++ b/Source/WebCore/svg/SVGFontFaceSrcElement.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFontFaceSrcElement_h -#define SVGFontFaceSrcElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGElement.h" namespace WebCore { @@ -29,22 +29,17 @@ class CSSValueList; class SVGFontFaceSrcElement final : public SVGElement { public: - static PassRefPtr<SVGFontFaceSrcElement> create(const QualifiedName&, Document&); + static Ref<SVGFontFaceSrcElement> create(const QualifiedName&, Document&); - PassRefPtr<CSSValueList> srcValue() const; + Ref<CSSValueList> srcValue() const; private: SVGFontFaceSrcElement(const QualifiedName&, Document&); - virtual void childrenChanged(const ChildChange&) override; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + void childrenChanged(const ChildChange&) final; + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGFontFaceSrcElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGFontFaceSrcElement.idl b/Source/WebCore/svg/SVGFontFaceSrcElement.idl index c86091a04..e85f13a6a 100644 --- a/Source/WebCore/svg/SVGFontFaceSrcElement.idl +++ b/Source/WebCore/svg/SVGFontFaceSrcElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGFontFaceSrcElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGFontFaceUriElement.cpp b/Source/WebCore/svg/SVGFontFaceUriElement.cpp index c45173c41..56d5e63c3 100644 --- a/Source/WebCore/svg/SVGFontFaceUriElement.cpp +++ b/Source/WebCore/svg/SVGFontFaceUriElement.cpp @@ -23,7 +23,6 @@ #if ENABLE(SVG_FONTS) #include "SVGFontFaceUriElement.h" -#include "Attribute.h" #include "CSSFontFaceSrcValue.h" #include "CachedFont.h" #include "CachedResourceLoader.h" @@ -43,21 +42,21 @@ inline SVGFontFaceUriElement::SVGFontFaceUriElement(const QualifiedName& tagName ASSERT(hasTagName(font_face_uriTag)); } -PassRefPtr<SVGFontFaceUriElement> SVGFontFaceUriElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGFontFaceUriElement> SVGFontFaceUriElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGFontFaceUriElement(tagName, document)); + return adoptRef(*new SVGFontFaceUriElement(tagName, document)); } SVGFontFaceUriElement::~SVGFontFaceUriElement() { if (m_cachedFont) - m_cachedFont->removeClient(this); + m_cachedFont->removeClient(*this); } -PassRef<CSSFontFaceSrcValue> SVGFontFaceUriElement::srcValue() const +Ref<CSSFontFaceSrcValue> SVGFontFaceUriElement::srcValue() const { auto src = CSSFontFaceSrcValue::create(getAttribute(XLinkNames::hrefAttr)); - AtomicString value(fastGetAttribute(formatAttr)); + AtomicString value(attributeWithoutSynchronization(formatAttr)); src.get().setFormat(value.isEmpty() ? "svg" : value); // Default format return src; } @@ -79,7 +78,7 @@ void SVGFontFaceUriElement::childrenChanged(const ChildChange& change) ContainerNode* grandparent = parentNode()->parentNode(); if (grandparent && grandparent->hasTagName(font_faceTag)) - toSVGFontFaceElement(grandparent)->rebuildFontFace(); + downcast<SVGFontFaceElement>(*grandparent).rebuildFontFace(); } Node::InsertionNotificationRequest SVGFontFaceUriElement::insertedInto(ContainerNode& rootParent) @@ -88,23 +87,32 @@ Node::InsertionNotificationRequest SVGFontFaceUriElement::insertedInto(Container return SVGElement::insertedInto(rootParent); } +static bool isSVGFontTarget(const SVGFontFaceUriElement& element) +{ + Ref<CSSFontFaceSrcValue> srcValue(element.srcValue()); + return srcValue->isSVGFontTarget(); +} + void SVGFontFaceUriElement::loadFont() { if (m_cachedFont) - m_cachedFont->removeClient(this); + m_cachedFont->removeClient(*this); const AtomicString& href = getAttribute(XLinkNames::hrefAttr); if (!href.isNull()) { - CachedResourceLoader* cachedResourceLoader = document().cachedResourceLoader(); - CachedResourceRequest request(ResourceRequest(document().completeURL(href))); - request.setInitiator(this); - m_cachedFont = cachedResourceLoader->requestFont(request); + ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions(); + options.contentSecurityPolicyImposition = isInUserAgentShadowTree() ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck; + + CachedResourceLoader& cachedResourceLoader = document().cachedResourceLoader(); + CachedResourceRequest request(ResourceRequest(document().completeURL(href)), options); + request.setInitiator(*this); + m_cachedFont = cachedResourceLoader.requestFont(WTFMove(request), isSVGFontTarget(*this)); if (m_cachedFont) { - m_cachedFont->addClient(this); + m_cachedFont->addClient(*this); m_cachedFont->beginLoadIfNeeded(cachedResourceLoader); } } else - m_cachedFont = 0; + m_cachedFont = nullptr; } } diff --git a/Source/WebCore/svg/SVGFontFaceUriElement.h b/Source/WebCore/svg/SVGFontFaceUriElement.h index 189a7895a..58fc1ca94 100644 --- a/Source/WebCore/svg/SVGFontFaceUriElement.h +++ b/Source/WebCore/svg/SVGFontFaceUriElement.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFontFaceUriElement_h -#define SVGFontFaceUriElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "CachedFontClient.h" #include "CachedResourceHandle.h" #include "SVGElement.h" @@ -31,29 +31,25 @@ class CSSFontFaceSrcValue; class SVGFontFaceUriElement final : public SVGElement, public CachedFontClient { public: - static PassRefPtr<SVGFontFaceUriElement> create(const QualifiedName&, Document&); + static Ref<SVGFontFaceUriElement> create(const QualifiedName&, Document&); virtual ~SVGFontFaceUriElement(); - PassRef<CSSFontFaceSrcValue> srcValue() const; + Ref<CSSFontFaceSrcValue> srcValue() const; private: SVGFontFaceUriElement(const QualifiedName&, Document&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void childrenChanged(const ChildChange&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void childrenChanged(const ChildChange&) final; + InsertionNotificationRequest insertedInto(ContainerNode&) final; + bool rendererIsNeeded(const RenderStyle&) final { return false; } void loadFont(); CachedResourceHandle<CachedFont> m_cachedFont; }; -NODE_TYPE_CASTS(SVGFontFaceUriElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) - -#endif // SVGFontFaceUriElement_h diff --git a/Source/WebCore/svg/SVGFontFaceUriElement.idl b/Source/WebCore/svg/SVGFontFaceUriElement.idl index 48037a067..234c2e5cf 100644 --- a/Source/WebCore/svg/SVGFontFaceUriElement.idl +++ b/Source/WebCore/svg/SVGFontFaceUriElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGFontFaceUriElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGForeignObjectElement.cpp b/Source/WebCore/svg/SVGForeignObjectElement.cpp index 37cc8cd39..c2af1f4e5 100644 --- a/Source/WebCore/svg/SVGForeignObjectElement.cpp +++ b/Source/WebCore/svg/SVGForeignObjectElement.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Apple Inc. All rights reserved. * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -19,19 +20,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGForeignObjectElement.h" -#include "Attribute.h" #include "CSSPropertyNames.h" #include "RenderSVGForeignObject.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" -#include "SVGLength.h" +#include "SVGLengthValue.h" #include "SVGNames.h" #include "XLinkNames.h" #include <wtf/Assertions.h> +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -64,45 +62,42 @@ inline SVGForeignObjectElement::SVGForeignObjectElement(const QualifiedName& tag registerAnimatedPropertiesForSVGForeignObjectElement(); } -PassRefPtr<SVGForeignObjectElement> SVGForeignObjectElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGForeignObjectElement> SVGForeignObjectElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGForeignObjectElement(tagName, document)); + return adoptRef(*new SVGForeignObjectElement(tagName, document)); } bool SVGForeignObjectElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); + supportedAttributes.get().add(SVGNames::xAttr); + supportedAttributes.get().add(SVGNames::yAttr); + supportedAttributes.get().add(SVGNames::widthAttr); + supportedAttributes.get().add(SVGNames::heightAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGForeignObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) @@ -112,23 +107,24 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - bool isLengthAttribute = attrName == SVGNames::xAttr - || attrName == SVGNames::yAttr - || attrName == SVGNames::widthAttr - || attrName == SVGNames::heightAttr; + InstanceInvalidationGuard guard(*this); + + if (attrName == SVGNames::widthAttr + || attrName == SVGNames::heightAttr) { + invalidateSVGPresentationAttributeStyle(); + return; + } - if (isLengthAttribute) + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) updateRelativeLengthsInformation(); if (auto renderer = this->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); } -RenderPtr<RenderElement> SVGForeignObjectElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGForeignObjectElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGForeignObject>(*this, std::move(style)); + return createRenderer<RenderSVGForeignObject>(*this, WTFMove(style)); } bool SVGForeignObjectElement::childShouldCreateRenderer(const Node& child) const @@ -159,14 +155,4 @@ bool SVGForeignObjectElement::rendererIsNeeded(const RenderStyle& style) return SVGGraphicsElement::rendererIsNeeded(style); } -bool SVGForeignObjectElement::selfHasRelativeLengths() const -{ - return x().isRelative() - || y().isRelative() - || width().isRelative() - || height().isRelative(); -} - } - -#endif diff --git a/Source/WebCore/svg/SVGForeignObjectElement.h b/Source/WebCore/svg/SVGForeignObjectElement.h index eb7284438..e48128838 100644 --- a/Source/WebCore/svg/SVGForeignObjectElement.h +++ b/Source/WebCore/svg/SVGForeignObjectElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGForeignObjectElement_h -#define SVGForeignObjectElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGExternalResourcesRequired.h" @@ -33,21 +31,21 @@ namespace WebCore { class SVGForeignObjectElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGForeignObjectElement> create(const QualifiedName&, Document&); + static Ref<SVGForeignObjectElement> create(const QualifiedName&, Document&); private: SVGForeignObjectElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + bool isValid() const final { return SVGTests::isValid(); } + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override; - virtual bool childShouldCreateRenderer(const Node&) const override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + bool rendererIsNeeded(const RenderStyle&) final; + bool childShouldCreateRenderer(const Node&) const final; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final { return true; } BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGForeignObjectElement) DECLARE_ANIMATED_LENGTH(X, x) @@ -55,13 +53,8 @@ private: DECLARE_ANIMATED_LENGTH(Width, width) DECLARE_ANIMATED_LENGTH(Height, height) DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGForeignObjectElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGForeignObjectElement.idl b/Source/WebCore/svg/SVGForeignObjectElement.idl index 174c86ffe..8856757c3 100644 --- a/Source/WebCore/svg/SVGForeignObjectElement.idl +++ b/Source/WebCore/svg/SVGForeignObjectElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGForeignObjectElement : SVGGraphicsElement { +interface SVGForeignObjectElement : SVGGraphicsElement { readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; readonly attribute SVGAnimatedLength width; diff --git a/Source/WebCore/svg/SVGGElement.cpp b/Source/WebCore/svg/SVGGElement.cpp index 2d6490475..94cf836fe 100644 --- a/Source/WebCore/svg/SVGGElement.cpp +++ b/Source/WebCore/svg/SVGGElement.cpp @@ -19,15 +19,13 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGGElement.h" #include "RenderSVGHiddenContainer.h" #include "RenderSVGResource.h" #include "RenderSVGTransformableContainer.h" -#include "SVGElementInstance.h" #include "SVGNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -46,34 +44,30 @@ SVGGElement::SVGGElement(const QualifiedName& tagName, Document& document) registerAnimatedPropertiesForSVGGElement(); } -PassRefPtr<SVGGElement> SVGGElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGGElement> SVGGElement::create(const QualifiedName& tagName, Document& document) +{ + return adoptRef(*new SVGGElement(tagName, document)); +} + +Ref<SVGGElement> SVGGElement::create(Document& document) { - return adoptRef(new SVGGElement(tagName, document)); + return create(SVGNames::gTag, document); } bool SVGGElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGGElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGGraphicsElement::parseAttribute(name, value); - return; - } - - if (SVGLangSpace::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) @@ -83,22 +77,22 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (auto renderer = this->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); } -RenderPtr<RenderElement> SVGGElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGGElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - // SVG 1.1 testsuite explicitely uses constructs like <g display="none"><linearGradient> + // SVG 1.1 testsuite explicitly uses constructs like <g display="none"><linearGradient> // We still have to create renderers for the <g> & <linearGradient> element, though the // subtree may be hidden - we only want the resource renderers to exist so they can be // referenced from somewhere else. - if (style.get().display() == NONE) - return createRenderer<RenderSVGHiddenContainer>(*this, std::move(style)); + if (style.display() == NONE) + return createRenderer<RenderSVGHiddenContainer>(*this, WTFMove(style)); - return createRenderer<RenderSVGTransformableContainer>(*this, std::move(style)); + return createRenderer<RenderSVGTransformableContainer>(*this, WTFMove(style)); } bool SVGGElement::rendererIsNeeded(const RenderStyle&) @@ -109,5 +103,3 @@ bool SVGGElement::rendererIsNeeded(const RenderStyle&) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGGElement.h b/Source/WebCore/svg/SVGGElement.h index 50b69b530..47c29cdc0 100644 --- a/Source/WebCore/svg/SVGGElement.h +++ b/Source/WebCore/svg/SVGGElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGGElement_h -#define SVGGElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGExternalResourcesRequired.h" #include "SVGGraphicsElement.h" @@ -31,28 +29,25 @@ namespace WebCore { class SVGGElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGGElement> create(const QualifiedName&, Document&); + static Ref<SVGGElement> create(const QualifiedName&, Document&); + static Ref<SVGGElement> create(Document&); private: SVGGElement(const QualifiedName&, Document&); - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override; + bool rendererIsNeeded(const RenderStyle&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGGElement.idl b/Source/WebCore/svg/SVGGElement.idl index c2d332355..62cc1bbc0 100644 --- a/Source/WebCore/svg/SVGGElement.idl +++ b/Source/WebCore/svg/SVGGElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGGElement : SVGGraphicsElement { +interface SVGGElement : SVGGraphicsElement { }; SVGGElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGGlyphElement.cpp b/Source/WebCore/svg/SVGGlyphElement.cpp index ee656146d..7f66952ca 100644 --- a/Source/WebCore/svg/SVGGlyphElement.cpp +++ b/Source/WebCore/svg/SVGGlyphElement.cpp @@ -24,8 +24,6 @@ #if ENABLE(SVG_FONTS) #include "SVGGlyphElement.h" -#include "Attribute.h" -#include "SVGFontData.h" #include "SVGFontElement.h" #include "SVGFontFaceElement.h" #include "SVGNames.h" @@ -39,128 +37,9 @@ inline SVGGlyphElement::SVGGlyphElement(const QualifiedName& tagName, Document& ASSERT(hasTagName(SVGNames::glyphTag)); } -PassRefPtr<SVGGlyphElement> SVGGlyphElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGGlyphElement> SVGGlyphElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGGlyphElement(tagName, document)); -} - -void SVGGlyphElement::invalidateGlyphCache() -{ - ContainerNode* fontNode = parentNode(); - if (fontNode && isSVGFontElement(fontNode)) - toSVGFontElement(fontNode)->invalidateGlyphCache(); -} - -void SVGGlyphElement::parseAttribute(const QualifiedName& name, const AtomicString& value) -{ - if (name == SVGNames::dAttr) - invalidateGlyphCache(); - else - SVGElement::parseAttribute(name, value); -} - -Node::InsertionNotificationRequest SVGGlyphElement::insertedInto(ContainerNode& rootParent) -{ - invalidateGlyphCache(); - return SVGElement::insertedInto(rootParent); -} - -void SVGGlyphElement::removedFrom(ContainerNode& rootParent) -{ - if (rootParent.inDocument()) - invalidateGlyphCache(); - SVGElement::removedFrom(rootParent); -} - -static inline SVGGlyph::ArabicForm parseArabicForm(const AtomicString& value) -{ - if (value == "medial") - return SVGGlyph::Medial; - if (value == "terminal") - return SVGGlyph::Terminal; - if (value == "isolated") - return SVGGlyph::Isolated; - if (value == "initial") - return SVGGlyph::Initial; - - return SVGGlyph::None; -} - -static inline SVGGlyph::Orientation parseOrientation(const AtomicString& value) -{ - if (value == "h") - return SVGGlyph::Horizontal; - if (value == "v") - return SVGGlyph::Vertical; - - return SVGGlyph::Both; -} - -void SVGGlyphElement::inheritUnspecifiedAttributes(SVGGlyph& identifier, const SVGFontData* svgFontData) -{ - if (identifier.horizontalAdvanceX == SVGGlyph::inheritedValue()) - identifier.horizontalAdvanceX = svgFontData->horizontalAdvanceX(); - - if (identifier.verticalOriginX == SVGGlyph::inheritedValue()) - identifier.verticalOriginX = svgFontData->verticalOriginX(); - - if (identifier.verticalOriginY == SVGGlyph::inheritedValue()) - identifier.verticalOriginY = svgFontData->verticalOriginY(); - - if (identifier.verticalAdvanceY == SVGGlyph::inheritedValue()) - identifier.verticalAdvanceY = svgFontData->verticalAdvanceY(); -} - -static inline float parseSVGGlyphAttribute(const SVGElement* element, const WebCore::QualifiedName& name) -{ - AtomicString value(element->fastGetAttribute(name)); - if (value.isEmpty()) - return SVGGlyph::inheritedValue(); - - return value.toFloat(); -} - -SVGGlyph SVGGlyphElement::buildGenericGlyphIdentifier(const SVGElement* element) -{ - SVGGlyph identifier; - buildPathFromString(element->fastGetAttribute(SVGNames::dAttr), identifier.pathData); - - // Spec: The horizontal advance after rendering the glyph in horizontal orientation. - // If the attribute is not specified, the effect is as if the attribute were set to the - // value of the font's horiz-adv-x attribute. Glyph widths are required to be non-negative, - // even if the glyph is typically rendered right-to-left, as in Hebrew and Arabic scripts. - identifier.horizontalAdvanceX = parseSVGGlyphAttribute(element, SVGNames::horiz_adv_xAttr); - - // Spec: The X-coordinate in the font coordinate system of the origin of the glyph to be - // used when drawing vertically oriented text. If the attribute is not specified, the effect - // is as if the attribute were set to the value of the font's vert-origin-x attribute. - identifier.verticalOriginX = parseSVGGlyphAttribute(element, SVGNames::vert_origin_xAttr); - - // Spec: The Y-coordinate in the font coordinate system of the origin of a glyph to be - // used when drawing vertically oriented text. If the attribute is not specified, the effect - // is as if the attribute were set to the value of the font's vert-origin-y attribute. - identifier.verticalOriginY = parseSVGGlyphAttribute(element, SVGNames::vert_origin_yAttr); - - // Spec: The vertical advance after rendering a glyph in vertical orientation. - // If the attribute is not specified, the effect is as if the attribute were set to the - // value of the font's vert-adv-y attribute. - identifier.verticalAdvanceY = parseSVGGlyphAttribute(element, SVGNames::vert_adv_yAttr); - - return identifier; -} - -SVGGlyph SVGGlyphElement::buildGlyphIdentifier() const -{ - SVGGlyph identifier(buildGenericGlyphIdentifier(this)); - identifier.glyphName = fastGetAttribute(SVGNames::glyph_nameAttr); - identifier.orientation = parseOrientation(fastGetAttribute(SVGNames::orientationAttr)); - identifier.arabicForm = parseArabicForm(fastGetAttribute(SVGNames::arabic_formAttr)); - - String language = fastGetAttribute(SVGNames::langAttr); - if (!language.isEmpty()) - identifier.languages = parseDelimitedString(language, ','); - - return identifier; + return adoptRef(*new SVGGlyphElement(tagName, document)); } } diff --git a/Source/WebCore/svg/SVGGlyphElement.h b/Source/WebCore/svg/SVGGlyphElement.h index 7b7d38a10..24f15ceae 100644 --- a/Source/WebCore/svg/SVGGlyphElement.h +++ b/Source/WebCore/svg/SVGGlyphElement.h @@ -19,47 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGGlyphElement_h -#define SVGGlyphElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGElement.h" -#include "SVGGlyph.h" namespace WebCore { -class SVGFontData; - class SVGGlyphElement final : public SVGElement { public: - static PassRefPtr<SVGGlyphElement> create(const QualifiedName&, Document&); - - SVGGlyph buildGlyphIdentifier() const; + static Ref<SVGGlyphElement> create(const QualifiedName&, Document&); // Helper function used by SVGFont - static void inheritUnspecifiedAttributes(SVGGlyph&, const SVGFontData*); static String querySVGFontLanguage(const SVGElement*); - // Helper function shared between SVGGlyphElement & SVGMissingGlyphElement - static SVGGlyph buildGenericGlyphIdentifier(const SVGElement*); - private: SVGGlyphElement(const QualifiedName&, Document&); - // FIXME: svgAttributeChanged missing. - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } - - void invalidateGlyphCache(); + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGGlyphElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif diff --git a/Source/WebCore/svg/SVGGlyphElement.idl b/Source/WebCore/svg/SVGGlyphElement.idl index a05b5c887..e75e2cfb8 100644 --- a/Source/WebCore/svg/SVGGlyphElement.idl +++ b/Source/WebCore/svg/SVGGlyphElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGGlyphElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGGlyphMap.h b/Source/WebCore/svg/SVGGlyphMap.h deleted file mode 100644 index 08bfa5981..000000000 --- a/Source/WebCore/svg/SVGGlyphMap.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. 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 SVGGlyphMap_h -#define SVGGlyphMap_h - -#if ENABLE(SVG_FONTS) -#include "SurrogatePairAwareTextIterator.h" -#include "SVGGlyph.h" - -#include <wtf/HashMap.h> -#include <wtf/Vector.h> - -namespace WebCore { - -struct GlyphMapNode; -class SVGFontData; - -typedef HashMap<UChar32, RefPtr<GlyphMapNode>> GlyphMapLayer; - -struct GlyphMapNode : public RefCounted<GlyphMapNode> { -private: - GlyphMapNode() { } -public: - static PassRefPtr<GlyphMapNode> create() { return adoptRef(new GlyphMapNode); } - - Vector<SVGGlyph> glyphs; - - GlyphMapLayer children; -}; - -class SVGGlyphMap { -public: - SVGGlyphMap() : m_currentPriority(0) { } - - void addGlyph(const String& glyphName, const String& unicodeString, SVGGlyph glyph) - { - ASSERT(!glyphName.isEmpty() || !unicodeString.isEmpty()); - - bool hasGlyphName = !glyphName.isEmpty(); - if (unicodeString.isEmpty()) { - // Register named glyph in the named glyph map and in the glyph table. - ASSERT(hasGlyphName); - appendToGlyphTable(glyph); - m_namedGlyphs.add(glyphName, glyph.tableEntry); - return; - } - - GlyphMapLayer* currentLayer = &m_rootLayer; - RefPtr<GlyphMapNode> node; - size_t length = unicodeString.length(); - - UChar32 character = 0; - unsigned clusterLength = 0; - SurrogatePairAwareTextIterator textIterator(unicodeString.deprecatedCharacters(), 0, length, length); - while (textIterator.consume(character, clusterLength)) { - node = currentLayer->get(character); - if (!node) { - node = GlyphMapNode::create(); - currentLayer->set(character, node); - } - currentLayer = &node->children; - textIterator.advance(clusterLength); - } - - if (!node) - return; - - // Register glyph associated with an unicode string into the glyph map. - node->glyphs.append(glyph); - SVGGlyph& lastGlyph = node->glyphs.last(); - lastGlyph.priority = m_currentPriority++; - lastGlyph.unicodeStringLength = length; - - // If the glyph is named, also add it to the named glyph name, and to the glyph table in both cases. - appendToGlyphTable(lastGlyph); - if (hasGlyphName) - m_namedGlyphs.add(glyphName, lastGlyph.tableEntry); - } - - void appendToGlyphTable(SVGGlyph& glyph) - { - size_t tableEntry = m_glyphTable.size(); - ASSERT(tableEntry < std::numeric_limits<unsigned short>::max()); - - // The first table entry starts with 1. 0 denotes an unknown glyph. - glyph.tableEntry = tableEntry + 1; - m_glyphTable.append(glyph); - } - - static inline bool compareGlyphPriority(const SVGGlyph& first, const SVGGlyph& second) - { - return first.priority < second.priority; - } - - void collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs) - { - GlyphMapLayer* currentLayer = &m_rootLayer; - - const UChar* characters = string.deprecatedCharacters(); - size_t length = string.length(); - - UChar32 character = 0; - unsigned clusterLength = 0; - SurrogatePairAwareTextIterator textIterator(characters, 0, length, length); - while (textIterator.consume(character, clusterLength)) { - RefPtr<GlyphMapNode> node = currentLayer->get(character); - if (!node) - break; - glyphs.appendVector(node->glyphs); - currentLayer = &node->children; - textIterator.advance(clusterLength); - } - - std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority); - } - - void clear() - { - m_rootLayer.clear(); - m_glyphTable.clear(); - m_currentPriority = 0; - } - - const SVGGlyph& svgGlyphForGlyph(Glyph glyph) const - { - if (!glyph || glyph > m_glyphTable.size()) { - DEFINE_STATIC_LOCAL(SVGGlyph, defaultGlyph, ()); - return defaultGlyph; - } - return m_glyphTable[glyph - 1]; - } - - const SVGGlyph& glyphIdentifierForGlyphName(const String& glyphName) const - { - return svgGlyphForGlyph(m_namedGlyphs.get(glyphName)); - } - -private: - GlyphMapLayer m_rootLayer; - Vector<SVGGlyph, 256> m_glyphTable; - HashMap<String, Glyph> m_namedGlyphs; - int m_currentPriority; -}; - -} - -#endif // ENABLE(SVG_FONTS) -#endif // SVGGlyphMap_h diff --git a/Source/WebCore/svg/SVGGlyphRefElement.cpp b/Source/WebCore/svg/SVGGlyphRefElement.cpp index 9b27eaef4..c3ffaa565 100644 --- a/Source/WebCore/svg/SVGGlyphRefElement.cpp +++ b/Source/WebCore/svg/SVGGlyphRefElement.cpp @@ -19,7 +19,7 @@ #include "config.h" -#if ENABLE(SVG) && ENABLE(SVG_FONTS) +#if ENABLE(SVG_FONTS) #include "SVGGlyphRefElement.h" #include "SVGGlyphElement.h" @@ -40,88 +40,66 @@ END_REGISTER_ANIMATED_PROPERTIES inline SVGGlyphRefElement::SVGGlyphRefElement(const QualifiedName& tagName, Document& document) : SVGElement(tagName, document) - , m_x(0) - , m_y(0) - , m_dx(0) - , m_dy(0) { ASSERT(hasTagName(SVGNames::glyphRefTag)); registerAnimatedPropertiesForSVGGlyphRefElement(); } -PassRefPtr<SVGGlyphRefElement> SVGGlyphRefElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGGlyphRefElement> SVGGlyphRefElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGGlyphRefElement(tagName, document)); + return adoptRef(*new SVGGlyphRefElement(tagName, document)); } bool SVGGlyphRefElement::hasValidGlyphElement(String& glyphName) const { // FIXME: We only support xlink:href so far. // https://bugs.webkit.org/show_bug.cgi?id=64787 - Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &glyphName); - if (!element || !element->hasTagName(SVGNames::glyphTag)) - return false; - return true; + return is<SVGGlyphElement>(targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &glyphName)); } -void SVGGlyphRefElement::parseAttribute(const QualifiedName& name, const AtomicString& value) +static float parseFloat(const AtomicString& value) { - const UChar* startPtr = value.string().deprecatedCharacters(); - const UChar* endPtr = startPtr + value.length(); + float result; + if (!parseNumberFromString(value, result)) + return 0; + return result; +} - // FIXME: We need some error handling here. +void SVGGlyphRefElement::parseAttribute(const QualifiedName& name, const AtomicString& value) +{ + // FIXME: Is the error handling in parseFloat correct for these attributes? if (name == SVGNames::xAttr) - parseNumber(startPtr, endPtr, m_x); + m_x = parseFloat(value); else if (name == SVGNames::yAttr) - parseNumber(startPtr, endPtr, m_y); + m_y = parseFloat(value); else if (name == SVGNames::dxAttr) - parseNumber(startPtr, endPtr, m_dx); + m_dx = parseFloat(value); else if (name == SVGNames::dyAttr) - parseNumber(startPtr, endPtr, m_dy); + m_dy = parseFloat(value); else { - if (SVGURIReference::parseAttribute(name, value)) - return; + SVGURIReference::parseAttribute(name, value); SVGElement::parseAttribute(name, value); } } -const AtomicString& SVGGlyphRefElement::glyphRef() const +void SVGGlyphRefElement::setX(float x) { - return fastGetAttribute(SVGNames::glyphRefAttr); + setAttribute(SVGNames::xAttr, AtomicString::number(x)); } -void SVGGlyphRefElement::setGlyphRef(const AtomicString&, ExceptionCode&) +void SVGGlyphRefElement::setY(float y) { - // FIXME: Set and honor attribute change. - // https://bugs.webkit.org/show_bug.cgi?id=64787 + setAttribute(SVGNames::yAttr, AtomicString::number(y)); } -void SVGGlyphRefElement::setX(float x, ExceptionCode&) +void SVGGlyphRefElement::setDx(float dx) { - // FIXME: Honor attribute change. - // https://bugs.webkit.org/show_bug.cgi?id=64787 - m_x = x; + setAttribute(SVGNames::dxAttr, AtomicString::number(dx)); } -void SVGGlyphRefElement::setY(float y , ExceptionCode&) +void SVGGlyphRefElement::setDy(float dy) { - // FIXME: Honor attribute change. - // https://bugs.webkit.org/show_bug.cgi?id=64787 - m_y = y; -} - -void SVGGlyphRefElement::setDx(float dx, ExceptionCode&) -{ - // FIXME: Honor attribute change. - // https://bugs.webkit.org/show_bug.cgi?id=64787 - m_dx = dx; -} - -void SVGGlyphRefElement::setDy(float dy, ExceptionCode&) -{ - // FIXME: Honor attribute change. - // https://bugs.webkit.org/show_bug.cgi?id=64787 - m_dy = dy; + setAttribute(SVGNames::dyAttr, AtomicString::number(dy)); } } diff --git a/Source/WebCore/svg/SVGGlyphRefElement.h b/Source/WebCore/svg/SVGGlyphRefElement.h index 542e95218..24fcc2475 100644 --- a/Source/WebCore/svg/SVGGlyphRefElement.h +++ b/Source/WebCore/svg/SVGGlyphRefElement.h @@ -17,53 +17,46 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGGlyphRefElement_h -#define SVGGlyphRefElement_h +#pragma once + +#if ENABLE(SVG_FONTS) -#if ENABLE(SVG) && ENABLE(SVG_FONTS) #include "SVGElement.h" #include "SVGURIReference.h" namespace WebCore { -class SVGGlyphRefElement final : public SVGElement, - public SVGURIReference { +class SVGGlyphRefElement final : public SVGElement, public SVGURIReference { public: - static PassRefPtr<SVGGlyphRefElement> create(const QualifiedName&, Document&); + static Ref<SVGGlyphRefElement> create(const QualifiedName&, Document&); bool hasValidGlyphElement(String& glyphName) const; - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - // DOM interface - const AtomicString& glyphRef() const; - void setGlyphRef(const AtomicString&, ExceptionCode&); float x() const { return m_x; } - void setX(float, ExceptionCode&); + void setX(float); float y() const { return m_y; } - void setY(float, ExceptionCode&); + void setY(float); float dx() const { return m_dx; } - void setDx(float, ExceptionCode&); + void setDx(float); float dy() const { return m_dy; } - void setDy(float, ExceptionCode&); + void setDy(float); private: SVGGlyphRefElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + void parseAttribute(const QualifiedName&, const AtomicString&) final; + bool rendererIsNeeded(const RenderStyle&) final { return false; } BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGlyphRefElement) - DECLARE_ANIMATED_STRING(Href, href) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) END_DECLARE_ANIMATED_PROPERTIES - float m_x; - float m_y; - float m_dx; - float m_dy; + float m_x { 0 }; + float m_y { 0 }; + float m_dx { 0 }; + float m_dy { 0 }; }; -NODE_TYPE_CASTS(SVGGlyphRefElement) - } #endif -#endif diff --git a/Source/WebCore/svg/SVGGlyphRefElement.idl b/Source/WebCore/svg/SVGGlyphRefElement.idl index 860271066..c707e0432 100644 --- a/Source/WebCore/svg/SVGGlyphRefElement.idl +++ b/Source/WebCore/svg/SVGGlyphRefElement.idl @@ -18,15 +18,14 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGGlyphRefElement : SVGElement { - // FIXME: Use [Reflect] after https://bugs.webkit.org/show_bug.cgi?id=64843 is fixed. - [SetterRaisesException] attribute DOMString glyphRef; + [Reflect=glyphRef] attribute DOMString glyphRef; [Reflect] attribute DOMString format; - [SetterRaisesException] attribute float x; - [SetterRaisesException] attribute float y; - [SetterRaisesException] attribute float dx; - [SetterRaisesException] attribute float dy; + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float dx; + attribute unrestricted float dy; }; SVGGlyphRefElement implements SVGURIReference; diff --git a/Source/WebCore/svg/SVGGradientElement.cpp b/Source/WebCore/svg/SVGGradientElement.cpp index d5d71efb8..e0659e69a 100644 --- a/Source/WebCore/svg/SVGGradientElement.cpp +++ b/Source/WebCore/svg/SVGGradientElement.cpp @@ -20,8 +20,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGGradientElement.h" #include "ElementIterator.h" @@ -29,13 +27,13 @@ #include "RenderSVGPath.h" #include "RenderSVGResourceLinearGradient.h" #include "RenderSVGResourceRadialGradient.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGStopElement.h" -#include "SVGTransformList.h" +#include "SVGTransformListValues.h" #include "SVGTransformable.h" #include "StyleResolver.h" #include "XLinkNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -65,33 +63,28 @@ SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document& d bool SVGGradientElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGURIReference::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::gradientUnitsAttr); - supportedAttributes.add(SVGNames::gradientTransformAttr); - supportedAttributes.add(SVGNames::spreadMethodAttr); + supportedAttributes.get().add(SVGNames::gradientUnitsAttr); + supportedAttributes.get().add(SVGNames::gradientTransformAttr); + supportedAttributes.get().add(SVGNames::spreadMethodAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGGradientElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::gradientUnitsAttr) { - SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); + auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); if (propertyValue > 0) setGradientUnitsBaseValue(propertyValue); return; } if (name == SVGNames::gradientTransformAttr) { - SVGTransformList newList; + SVGTransformListValues newList; newList.parse(value); detachAnimatedGradientTransformListWrappers(newList.size()); setGradientTransformBaseValue(newList); @@ -99,18 +92,15 @@ void SVGGradientElement::parseAttribute(const QualifiedName& name, const AtomicS } if (name == SVGNames::spreadMethodAttr) { - SVGSpreadMethodType propertyValue = SVGPropertyTraits<SVGSpreadMethodType>::fromString(value); + auto propertyValue = SVGPropertyTraits<SVGSpreadMethodType>::fromString(value); if (propertyValue > 0) setSpreadMethodBaseValue(propertyValue); return; } - if (SVGURIReference::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName) @@ -120,7 +110,7 @@ void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (RenderObject* object = renderer()) object->setNeedsLayout(); @@ -143,7 +133,7 @@ Vector<Gradient::ColorStop> SVGGradientElement::buildStops() float previousOffset = 0.0f; for (auto& stop : childrenOfType<SVGStopElement>(*this)) { - Color color = stop.stopColorIncludingOpacity(); + const Color& color = stop.stopColorIncludingOpacity(); // Figure out right monotonic offset float offset = stop.offset(); @@ -161,11 +151,4 @@ Vector<Gradient::ColorStop> SVGGradientElement::buildStops() return stops; } -bool isSVGGradientElement(const Node& node) -{ - return node.hasTagName(SVGNames::radialGradientTag) || node.hasTagName(SVGNames::linearGradientTag); } - -} - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGGradientElement.h b/Source/WebCore/svg/SVGGradientElement.h index 904547a78..e26a185e9 100644 --- a/Source/WebCore/svg/SVGGradientElement.h +++ b/Source/WebCore/svg/SVGGradientElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGGradientElement_h -#define SVGGradientElement_h +#pragma once -#if ENABLE(SVG) #include "Gradient.h" #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" @@ -51,11 +49,11 @@ struct SVGPropertyTraits<SVGSpreadMethodType> { case SVGSpreadMethodUnknown: return emptyString(); case SVGSpreadMethodPad: - return "pad"; + return ASCIILiteral("pad"); case SVGSpreadMethodReflect: - return "reflect"; + return ASCIILiteral("reflect"); case SVGSpreadMethodRepeat: - return "repeat"; + return ASCIILiteral("repeat"); } ASSERT_NOT_REACHED(); @@ -90,29 +88,33 @@ public: protected: SVGGradientElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; private: - virtual bool needsPendingResourceHandling() const override { return false; } + bool needsPendingResourceHandling() const override { return false; } - virtual void childrenChanged(const ChildChange&) override; + void childrenChanged(const ChildChange&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGradientElement) DECLARE_ANIMATED_ENUMERATION(SpreadMethod, spreadMethod, SVGSpreadMethodType) DECLARE_ANIMATED_ENUMERATION(GradientUnits, gradientUnits, SVGUnitTypes::SVGUnitType) DECLARE_ANIMATED_TRANSFORM_LIST(GradientTransform, gradientTransform) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -void isSVGGradientElement(const SVGGradientElement&); // Catch unnecessary runtime check of type known at compile time. -bool isSVGGradientElement(const Node&); -NODE_TYPE_CASTS(SVGGradientElement) - } // namespace WebCore -#endif // ENABLE(SVG) -#endif +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGGradientElement) +static bool isType(const WebCore::SVGElement& element) +{ + return element.hasTagName(WebCore::SVGNames::radialGradientTag) || element.hasTagName(WebCore::SVGNames::linearGradientTag); +} +static bool isType(const WebCore::Node& node) +{ + return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); +} +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/SVGGradientElement.idl b/Source/WebCore/svg/SVGGradientElement.idl index 993be3423..2ba9fe795 100644 --- a/Source/WebCore/svg/SVGGradientElement.idl +++ b/Source/WebCore/svg/SVGGradientElement.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, DoNotCheckConstants ] interface SVGGradientElement : SVGElement { // Spread Method Types diff --git a/Source/WebCore/svg/SVGGraphicsElement.cpp b/Source/WebCore/svg/SVGGraphicsElement.cpp index 53ba8db0b..f5f929329 100644 --- a/Source/WebCore/svg/SVGGraphicsElement.cpp +++ b/Source/WebCore/svg/SVGGraphicsElement.cpp @@ -19,17 +19,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGGraphicsElement.h" -#include "AffineTransform.h" -#include "Attribute.h" #include "RenderSVGPath.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" +#include "SVGMatrix.h" #include "SVGNames.h" #include "SVGPathData.h" +#include "SVGRect.h" +#include "SVGStringList.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -44,6 +43,7 @@ END_REGISTER_ANIMATED_PROPERTIES SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& document) : SVGElement(tagName, document) + , m_shouldIsolateBlending(false) { registerAnimatedPropertiesForSVGGraphicsElement(); } @@ -52,11 +52,21 @@ SVGGraphicsElement::~SVGGraphicsElement() { } +Ref<SVGMatrix> SVGGraphicsElement::getCTMForBindings() +{ + return SVGMatrix::create(getCTM()); +} + AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrategy) { return SVGLocatable::computeCTM(this, SVGLocatable::NearestViewportScope, styleUpdateStrategy); } +Ref<SVGMatrix> SVGGraphicsElement::getScreenCTMForBindings() +{ + return SVGMatrix::create(getScreenCTM()); +} + AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy) { return SVGLocatable::computeCTM(this, SVGLocatable::ScreenScope, styleUpdateStrategy); @@ -65,7 +75,7 @@ AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdate AffineTransform SVGGraphicsElement::animatedLocalTransform() const { AffineTransform matrix; - RenderStyle* style = renderer() ? &renderer()->style() : nullptr; + auto* style = renderer() ? &renderer()->style() : nullptr; // If CSS property was set, use that, otherwise fallback to attribute (if set). if (style && style->hasTransform()) { @@ -76,6 +86,14 @@ AffineTransform SVGGraphicsElement::animatedLocalTransform() const // Flatten any 3D transform. matrix = transform.toAffineTransform(); + // CSS bakes the zoom factor into lengths, including translation components. + // In order to align CSS & SVG transforms, we need to invert this operation. + float zoom = style->effectiveZoom(); + if (zoom != 1) { + matrix.setE(matrix.e() / zoom); + matrix.setF(matrix.f() / zoom); + } + } else transform().concatenate(matrix); @@ -93,33 +111,26 @@ AffineTransform* SVGGraphicsElement::supplementalTransform() bool SVGGraphicsElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGTests::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::transformAttr); + supportedAttributes.get().add(SVGNames::transformAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGGraphicsElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::transformAttr) { - SVGTransformList newList; + SVGTransformListValues newList; newList.parse(value); detachAnimatedTransformListWrappers(newList.size()); setTransformBaseValue(newList); return; } - if (SVGTests::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); + SVGTests::parseAttribute(name, value); } void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName) @@ -129,7 +140,7 @@ void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (SVGTests::handleAttributeChange(this, attrName)) return; @@ -157,15 +168,19 @@ SVGElement* SVGGraphicsElement::farthestViewportElement() const return SVGTransformable::farthestViewportElement(this); } +Ref<SVGRect> SVGGraphicsElement::getBBoxForBindings() +{ + return SVGRect::create(getBBox()); +} + FloatRect SVGGraphicsElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) { return SVGTransformable::getBBox(this, styleUpdateStrategy); } -RenderPtr<RenderElement> SVGGraphicsElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGGraphicsElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - // By default, any subclass is expected to do path-based drawing - return createRenderer<RenderSVGPath>(*this, std::move(style)); + return createRenderer<RenderSVGPath>(*this, WTFMove(style)); } void SVGGraphicsElement::toClipPath(Path& path) @@ -175,6 +190,19 @@ void SVGGraphicsElement::toClipPath(Path& path) path.transform(animatedLocalTransform()); } +Ref<SVGStringList> SVGGraphicsElement::requiredFeatures() +{ + return SVGTests::requiredFeatures(*this); +} + +Ref<SVGStringList> SVGGraphicsElement::requiredExtensions() +{ + return SVGTests::requiredExtensions(*this); +} + +Ref<SVGStringList> SVGGraphicsElement::systemLanguage() +{ + return SVGTests::systemLanguage(*this); } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGGraphicsElement.h b/Source/WebCore/svg/SVGGraphicsElement.h index 6ea9213b4..7523cfc19 100644 --- a/Source/WebCore/svg/SVGGraphicsElement.h +++ b/Source/WebCore/svg/SVGGraphicsElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGGraphicsElement_h -#define SVGGraphicsElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedTransformList.h" #include "SVGElement.h" #include "SVGTests.h" @@ -31,55 +29,75 @@ namespace WebCore { class AffineTransform; class Path; +class SVGRect; +class SVGMatrix; class SVGGraphicsElement : public SVGElement, public SVGTransformable, public SVGTests { public: virtual ~SVGGraphicsElement(); - virtual AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) override; - virtual AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) override; - virtual SVGElement* nearestViewportElement() const override; - virtual SVGElement* farthestViewportElement() const override; + Ref<SVGMatrix> getCTMForBindings(); + AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate) override; - virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const override { return SVGTransformable::localCoordinateSpaceTransform(mode); } - virtual AffineTransform animatedLocalTransform() const override; - virtual AffineTransform* supplementalTransform() override; + Ref<SVGMatrix> getScreenCTMForBindings(); + AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate) override; - virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) override; + SVGElement* nearestViewportElement() const override; + SVGElement* farthestViewportElement() const override; + + AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const override { return SVGTransformable::localCoordinateSpaceTransform(mode); } + AffineTransform animatedLocalTransform() const override; + AffineTransform* supplementalTransform() override; + + Ref<SVGRect> getBBoxForBindings(); + FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) override; + + bool shouldIsolateBlending() const { return m_shouldIsolateBlending; } + void setShouldIsolateBlending(bool isolate) { m_shouldIsolateBlending = isolate; } // "base class" methods for all the elements which render as paths virtual void toClipPath(Path&); - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + + size_t approximateMemoryCost() const override { return sizeof(*this); } + + // SVGTests + Ref<SVGStringList> requiredFeatures(); + Ref<SVGStringList> requiredExtensions(); + Ref<SVGStringList> systemLanguage(); protected: SVGGraphicsElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + bool supportsFocus() const override { return Element::supportsFocus() || hasFocusEventListeners(); } + + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGraphicsElement) DECLARE_ANIMATED_TRANSFORM_LIST(Transform, transform) END_DECLARE_ANIMATED_PROPERTIES private: - virtual bool isSVGGraphicsElement() const override { return true; } + bool isSVGGraphicsElement() const override { return true; } + + static bool isSupportedAttribute(const QualifiedName&); // SVGTests - virtual void synchronizeRequiredFeatures() override { SVGTests::synchronizeRequiredFeatures(this); } - virtual void synchronizeRequiredExtensions() override { SVGTests::synchronizeRequiredExtensions(this); } - virtual void synchronizeSystemLanguage() override { SVGTests::synchronizeSystemLanguage(this); } + void synchronizeRequiredFeatures() final { SVGTests::synchronizeRequiredFeatures(*this); } + void synchronizeRequiredExtensions() final { SVGTests::synchronizeRequiredExtensions(*this); } + void synchronizeSystemLanguage() final { SVGTests::synchronizeSystemLanguage(*this); } // Used by <animateMotion> std::unique_ptr<AffineTransform> m_supplementalTransform; -}; -void isSVGGraphicsElement(const SVGGraphicsElement&); // Catch unnecessary runtime check of type known at compile time. -inline bool isSVGGraphicsElement(const SVGElement& element) { return element.isSVGGraphicsElement(); } -inline bool isSVGGraphicsElement(const Node& node) { return node.isSVGElement() && toSVGElement(node).isSVGGraphicsElement(); } -NODE_TYPE_CASTS(SVGGraphicsElement) + // Used to isolate blend operations caused by masking. + bool m_shouldIsolateBlending; +}; } // namespace WebCore -#endif // ENABLE(SVG) -#endif // SVGGraphicsElement_h +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGGraphicsElement) + static bool isType(const WebCore::SVGElement& element) { return element.isSVGGraphicsElement(); } + static bool isType(const WebCore::Node& node) { return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/SVGGraphicsElement.idl b/Source/WebCore/svg/SVGGraphicsElement.idl index 8d3740c75..f12bb6a3b 100644 --- a/Source/WebCore/svg/SVGGraphicsElement.idl +++ b/Source/WebCore/svg/SVGGraphicsElement.idl @@ -23,18 +23,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGGraphicsElement : SVGElement { +interface SVGGraphicsElement : SVGElement { readonly attribute SVGAnimatedTransformList transform; readonly attribute SVGElement nearestViewportElement; readonly attribute SVGElement farthestViewportElement; - SVGRect getBBox(); - SVGMatrix getCTM(); - SVGMatrix getScreenCTM(); - [RaisesException] SVGMatrix getTransformToElement([Default=Undefined] optional SVGElement element); + [ImplementedAs=getBBoxForBindings, NewObject] SVGRect getBBox(); + [ImplementedAs=getCTMForBindings, NewObject] SVGMatrix getCTM(); + [ImplementedAs=getScreenCTMForBindings, NewObject] SVGMatrix getScreenCTM(); + [MayThrowException, NewObject] SVGMatrix getTransformToElement(optional SVGElement? element = null); }; SVGGraphicsElement implements SVGTests; diff --git a/Source/WebCore/svg/SVGHKernElement.cpp b/Source/WebCore/svg/SVGHKernElement.cpp index 1688487a8..4392fdf9c 100644 --- a/Source/WebCore/svg/SVGHKernElement.cpp +++ b/Source/WebCore/svg/SVGHKernElement.cpp @@ -36,46 +36,29 @@ inline SVGHKernElement::SVGHKernElement(const QualifiedName& tagName, Document& ASSERT(hasTagName(SVGNames::hkernTag)); } -PassRefPtr<SVGHKernElement> SVGHKernElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGHKernElement> SVGHKernElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGHKernElement(tagName, document)); + return adoptRef(*new SVGHKernElement(tagName, document)); } -Node::InsertionNotificationRequest SVGHKernElement::insertedInto(ContainerNode& rootParent) +bool SVGHKernElement::buildHorizontalKerningPair(SVGKerningPair& kerningPair) const { - ContainerNode* fontNode = parentNode(); - if (fontNode && isSVGFontElement(fontNode)) - toSVGFontElement(fontNode)->invalidateGlyphCache(); - - return SVGElement::insertedInto(rootParent); -} - -void SVGHKernElement::removedFrom(ContainerNode& rootParent) -{ - ContainerNode* fontNode = parentNode(); - if (fontNode && isSVGFontElement(fontNode)) - toSVGFontElement(fontNode)->invalidateGlyphCache(); - - SVGElement::removedFrom(rootParent); -} - -void SVGHKernElement::buildHorizontalKerningPair(SVGKerningMap& kerningMap) -{ - String u1 = fastGetAttribute(SVGNames::u1Attr); - String g1 = fastGetAttribute(SVGNames::g1Attr); - String u2 = fastGetAttribute(SVGNames::u2Attr); - String g2 = fastGetAttribute(SVGNames::g2Attr); + String u1 = attributeWithoutSynchronization(SVGNames::u1Attr); + String g1 = attributeWithoutSynchronization(SVGNames::g1Attr); + String u2 = attributeWithoutSynchronization(SVGNames::u2Attr); + String g2 = attributeWithoutSynchronization(SVGNames::g2Attr); if ((u1.isEmpty() && g1.isEmpty()) || (u2.isEmpty() && g2.isEmpty())) - return; + return false; - SVGKerningPair kerningPair; if (parseGlyphName(g1, kerningPair.glyphName1) && parseGlyphName(g2, kerningPair.glyphName2) && parseKerningUnicodeString(u1, kerningPair.unicodeRange1, kerningPair.unicodeName1) && parseKerningUnicodeString(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)) { - kerningPair.kerning = fastGetAttribute(SVGNames::kAttr).string().toFloat(); - kerningMap.insert(kerningPair); + bool ok = false; + kerningPair.kerning = attributeWithoutSynchronization(SVGNames::kAttr).string().toFloat(&ok); + return ok; } + return false; } } diff --git a/Source/WebCore/svg/SVGHKernElement.h b/Source/WebCore/svg/SVGHKernElement.h index e5d8b78fd..feab463d2 100644 --- a/Source/WebCore/svg/SVGHKernElement.h +++ b/Source/WebCore/svg/SVGHKernElement.h @@ -19,32 +19,26 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGHKernElement_h -#define SVGHKernElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGFontElement.h" namespace WebCore { class SVGHKernElement final : public SVGElement { public: - static PassRefPtr<SVGHKernElement> create(const QualifiedName&, Document&); + static Ref<SVGHKernElement> create(const QualifiedName&, Document&); - void buildHorizontalKerningPair(SVGKerningMap&); + bool buildHorizontalKerningPair(SVGKerningPair& kerningPair) const; private: SVGHKernElement(const QualifiedName&, Document&); - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGHKernElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif diff --git a/Source/WebCore/svg/SVGHKernElement.idl b/Source/WebCore/svg/SVGHKernElement.idl index 9bca9f7ff..20fee2133 100644 --- a/Source/WebCore/svg/SVGHKernElement.idl +++ b/Source/WebCore/svg/SVGHKernElement.idl @@ -18,7 +18,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGHKernElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGImageElement.cpp b/Source/WebCore/svg/SVGImageElement.cpp index 0ad8f793b..b361b741e 100644 --- a/Source/WebCore/svg/SVGImageElement.cpp +++ b/Source/WebCore/svg/SVGImageElement.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Rob Buis <buis@kde.org> * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -20,19 +21,15 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGImageElement.h" -#include "Attribute.h" #include "CSSPropertyNames.h" #include "RenderImageResource.h" #include "RenderSVGImage.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGNames.h" -#include "SVGSVGElement.h" #include "XLinkNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -62,74 +59,66 @@ inline SVGImageElement::SVGImageElement(const QualifiedName& tagName, Document& , m_y(LengthModeHeight) , m_width(LengthModeWidth) , m_height(LengthModeHeight) - , m_imageLoader(this) + , m_imageLoader(*this) { registerAnimatedPropertiesForSVGImageElement(); } -PassRefPtr<SVGImageElement> SVGImageElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGImageElement> SVGImageElement::create(const QualifiedName& tagName, Document& document) +{ + return adoptRef(*new SVGImageElement(tagName, document)); +} + +bool SVGImageElement::hasSingleSecurityOrigin() const { - return adoptRef(new SVGImageElement(tagName, document)); + auto* renderer = downcast<RenderSVGImage>(this->renderer()); + if (!renderer || !renderer->imageResource().hasImage()) + return true; + auto* image = renderer->imageResource().cachedImage()->image(); + return !image || image->hasSingleSecurityOrigin(); } bool SVGImageElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); SVGURIReference::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); - supportedAttributes.add(SVGNames::preserveAspectRatioAttr); + supportedAttributes.get().add(SVGNames::xAttr); + supportedAttributes.get().add(SVGNames::yAttr); + supportedAttributes.get().add(SVGNames::widthAttr); + supportedAttributes.get().add(SVGNames::heightAttr); + supportedAttributes.get().add(SVGNames::preserveAspectRatioAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - -bool SVGImageElement::isPresentationAttribute(const QualifiedName& name) const -{ - if (name == SVGNames::widthAttr || name == SVGNames::heightAttr) - return true; - return SVGGraphicsElement::isPresentationAttribute(name); -} - -void SVGImageElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style) -{ - if (!isSupportedAttribute(name)) - SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style); - else if (name == SVGNames::widthAttr) - addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value); - else if (name == SVGNames::heightAttr) - addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { + if (name == SVGNames::preserveAspectRatioAttr) { + SVGPreserveAspectRatioValue preserveAspectRatio; + preserveAspectRatio.parse(value); + setPreserveAspectRatioBaseValue(preserveAspectRatio); + return; + } + SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (name == SVGNames::preserveAspectRatioAttr) { - SVGPreserveAspectRatio preserveAspectRatio; - preserveAspectRatio.parse(value); - setPreserveAspectRatioBaseValue(preserveAspectRatio); - } else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); + else if (name == SVGNames::widthAttr) + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value) - || SVGURIReference::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); } void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) @@ -139,8 +128,14 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - + InstanceInvalidationGuard guard(*this); + + if (attrName == SVGNames::widthAttr + || attrName == SVGNames::heightAttr) { + invalidateSVGPresentationAttributeStyle(); + return; + } + bool isLengthAttribute = attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr @@ -154,12 +149,12 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) return; } - auto renderer = this->renderer(); + auto* renderer = this->renderer(); if (!renderer) return; if (isLengthAttribute) { - if (toRenderSVGImage(renderer)->updateImageViewport()) + if (downcast<RenderSVGImage>(*renderer).updateImageViewport()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } @@ -174,17 +169,9 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) ASSERT_NOT_REACHED(); } -bool SVGImageElement::selfHasRelativeLengths() const +RenderPtr<RenderElement> SVGImageElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return x().isRelative() - || y().isRelative() - || width().isRelative() - || height().isRelative(); -} - -RenderPtr<RenderElement> SVGImageElement::createElementRenderer(PassRef<RenderStyle> style) -{ - return createRenderer<RenderSVGImage>(*this, std::move(style)); + return createRenderer<RenderSVGImage>(*this, WTFMove(style)); } bool SVGImageElement::haveLoadedRequiredResources() @@ -194,7 +181,7 @@ bool SVGImageElement::haveLoadedRequiredResources() void SVGImageElement::didAttachRenderers() { - if (RenderSVGImage* imageObj = toRenderSVGImage(renderer())) { + if (auto* imageObj = downcast<RenderSVGImage>(renderer())) { if (imageObj->imageResource().hasImage()) return; @@ -205,7 +192,7 @@ void SVGImageElement::didAttachRenderers() Node::InsertionNotificationRequest SVGImageElement::insertedInto(ContainerNode& rootParent) { SVGGraphicsElement::insertedInto(rootParent); - if (!rootParent.inDocument()) + if (!rootParent.isConnected()) return InsertionDone; // Update image loader, as soon as we're living in the tree. // We can only resolve base URIs properly, after that! @@ -225,12 +212,10 @@ void SVGImageElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const addSubresourceURL(urls, document().completeURL(href())); } -void SVGImageElement::didMoveToNewDocument(Document* oldDocument) +void SVGImageElement::didMoveToNewDocument(Document& oldDocument) { m_imageLoader.elementDidMoveToNewDocument(); SVGGraphicsElement::didMoveToNewDocument(oldDocument); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGImageElement.h b/Source/WebCore/svg/SVGImageElement.h index a89ac5641..683db4a89 100644 --- a/Source/WebCore/svg/SVGImageElement.h +++ b/Source/WebCore/svg/SVGImageElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGImageElement_h -#define SVGImageElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGAnimatedPreserveAspectRatio.h" @@ -36,32 +34,31 @@ class SVGImageElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired, public SVGURIReference { public: - static PassRefPtr<SVGImageElement> create(const QualifiedName&, Document&); + static Ref<SVGImageElement> create(const QualifiedName&, Document&); + + bool hasSingleSecurityOrigin() const; private: SVGImageElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool isPresentationAttribute(const QualifiedName&) const override; - virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual void didAttachRenderers() override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; + void didAttachRenderers() final; + InsertionNotificationRequest insertedInto(ContainerNode&) final; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; - virtual const AtomicString& imageSourceURL() const override; - virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override; + const AtomicString& imageSourceURL() const final; + void addSubresourceAttributeURLs(ListHashSet<URL>&) const final; - virtual bool haveLoadedRequiredResources() override; + bool haveLoadedRequiredResources() final; - virtual bool selfHasRelativeLengths() const override; - virtual void didMoveToNewDocument(Document* oldDocument) override; + bool selfHasRelativeLengths() const final { return true; } + void didMoveToNewDocument(Document& oldDocument) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGImageElement) DECLARE_ANIMATED_LENGTH(X, x) @@ -69,16 +66,11 @@ private: DECLARE_ANIMATED_LENGTH(Width, width) DECLARE_ANIMATED_LENGTH(Height, height) DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES SVGImageLoader m_imageLoader; }; -NODE_TYPE_CASTS(SVGImageElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGImageElement.idl b/Source/WebCore/svg/SVGImageElement.idl index 94ba3dfb5..53355a0db 100644 --- a/Source/WebCore/svg/SVGImageElement.idl +++ b/Source/WebCore/svg/SVGImageElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGImageElement : SVGGraphicsElement { +interface SVGImageElement : SVGGraphicsElement { readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; readonly attribute SVGAnimatedLength width; diff --git a/Source/WebCore/svg/SVGImageLoader.cpp b/Source/WebCore/svg/SVGImageLoader.cpp index f65f671ef..170d60c51 100644 --- a/Source/WebCore/svg/SVGImageLoader.cpp +++ b/Source/WebCore/svg/SVGImageLoader.cpp @@ -19,43 +19,41 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGImageLoader.h" #include "CachedImage.h" #include "Event.h" #include "EventNames.h" #include "HTMLParserIdioms.h" -#include "RenderImage.h" #include "SVGImageElement.h" namespace WebCore { -SVGImageLoader::SVGImageLoader(SVGImageElement* node) - : ImageLoader(node) +SVGImageLoader::SVGImageLoader(SVGImageElement& element) + : ImageLoader(element) +{ +} + +SVGImageLoader::~SVGImageLoader() { } void SVGImageLoader::dispatchLoadEvent() { if (image()->errorOccurred()) - element()->dispatchEvent(Event::create(eventNames().errorEvent, false, false)); + element().dispatchEvent(Event::create(eventNames().errorEvent, false, false)); else { - SVGImageElement* imageElement = toSVGImageElement(element()); - if (imageElement->externalResourcesRequiredBaseValue()) - imageElement->sendSVGLoadEventIfPossible(true); + if (downcast<SVGImageElement>(element()).externalResourcesRequiredBaseValue()) + downcast<SVGImageElement>(ImageLoader::element()).sendSVGLoadEventIfPossible(true); } } String SVGImageLoader::sourceURI(const AtomicString& attribute) const { - URL base = element()->baseURI(); - if (base.isValid()) + URL base = element().baseURI(); + if (base != blankURL()) return URL(base, stripLeadingAndTrailingHTMLSpaces(attribute)).string(); - return element()->document().completeURL(stripLeadingAndTrailingHTMLSpaces(attribute)); + return element().document().completeURL(stripLeadingAndTrailingHTMLSpaces(attribute)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGImageLoader.h b/Source/WebCore/svg/SVGImageLoader.h index e853b57ea..94fabf20e 100644 --- a/Source/WebCore/svg/SVGImageLoader.h +++ b/Source/WebCore/svg/SVGImageLoader.h @@ -17,26 +17,22 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGImageLoader_h -#define SVGImageLoader_h +#pragma once -#if ENABLE(SVG) #include "ImageLoader.h" namespace WebCore { class SVGImageElement; -class SVGImageLoader : public ImageLoader { +class SVGImageLoader final : public ImageLoader { public: - SVGImageLoader(SVGImageElement*); + explicit SVGImageLoader(SVGImageElement&); + virtual ~SVGImageLoader(); private: - virtual void dispatchLoadEvent() override; - virtual String sourceURI(const AtomicString&) const override; + void dispatchLoadEvent() override; + String sourceURI(const AtomicString&) const override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGImageLoader_h diff --git a/Source/WebCore/svg/SVGLangSpace.cpp b/Source/WebCore/svg/SVGLangSpace.cpp index abd15c663..b6518044e 100644 --- a/Source/WebCore/svg/SVGLangSpace.cpp +++ b/Source/WebCore/svg/SVGLangSpace.cpp @@ -19,11 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGLangSpace.h" -#include "Attribute.h" #include "SVGElement.h" #include "XMLNames.h" #include <wtf/StdLibExtras.h> @@ -38,7 +35,7 @@ void SVGLangSpace::setXmllang(const AtomicString& xmlLang) const AtomicString& SVGLangSpace::xmlspace() const { if (!m_space) { - DEFINE_STATIC_LOCAL(const AtomicString, defaultString, ("default", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> defaultString("default", AtomicString::ConstructFromLiteral); return defaultString; } @@ -50,18 +47,12 @@ void SVGLangSpace::setXmlspace(const AtomicString& xmlSpace) m_space = xmlSpace; } -bool SVGLangSpace::parseAttribute(const QualifiedName& name, const AtomicString& value) +void SVGLangSpace::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (name.matches(XMLNames::langAttr)) { + if (name.matches(XMLNames::langAttr)) setXmllang(value); - return true; - } - if (name.matches(XMLNames::spaceAttr)) { + if (name.matches(XMLNames::spaceAttr)) setXmlspace(value); - return true; - } - - return false; } bool SVGLangSpace::isKnownAttribute(const QualifiedName& attrName) @@ -71,7 +62,7 @@ bool SVGLangSpace::isKnownAttribute(const QualifiedName& attrName) void SVGLangSpace::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) { - DEFINE_STATIC_LOCAL(AtomicString, xmlPrefix, ("xml", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> xmlPrefix("xml", AtomicString::ConstructFromLiteral); QualifiedName langWithPrefix = XMLNames::langAttr; langWithPrefix.setPrefix(xmlPrefix); @@ -85,5 +76,3 @@ void SVGLangSpace::addSupportedAttributes(HashSet<QualifiedName>& supportedAttri } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGLangSpace.h b/Source/WebCore/svg/SVGLangSpace.h index d8badb496..22c4118a8 100644 --- a/Source/WebCore/svg/SVGLangSpace.h +++ b/Source/WebCore/svg/SVGLangSpace.h @@ -18,17 +18,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGLangSpace_h -#define SVGLangSpace_h +#pragma once -#if ENABLE(SVG) #include "QualifiedName.h" #include <wtf/HashSet.h> namespace WebCore { -class Attribute; - class SVGLangSpace { public: const AtomicString& xmllang() const { return m_lang; } @@ -37,9 +33,10 @@ public: const AtomicString& xmlspace() const; void setXmlspace(const AtomicString& xmlSpace); - bool parseAttribute(const QualifiedName&, const AtomicString&); - bool isKnownAttribute(const QualifiedName&); - void addSupportedAttributes(HashSet<QualifiedName>&); + void parseAttribute(const QualifiedName&, const AtomicString&); + + static bool isKnownAttribute(const QualifiedName&); + static void addSupportedAttributes(HashSet<QualifiedName>&); private: AtomicString m_lang; @@ -47,6 +44,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGLangSpace_h diff --git a/Source/WebCore/svg/SVGLength.cpp b/Source/WebCore/svg/SVGLength.cpp deleted file mode 100644 index 0a2284896..000000000 --- a/Source/WebCore/svg/SVGLength.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007 Apple Inc. 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 "SVGLength.h" - -#include "CSSHelper.h" -#include "CSSPrimitiveValue.h" -#include "ExceptionCode.h" -#include "ExceptionCodePlaceholder.h" -#include "FloatConversion.h" -#include "SVGNames.h" -#include "SVGParserUtilities.h" - -#include <wtf/MathExtras.h> -#include <wtf/text/WTFString.h> - -namespace WebCore { - -// Helper functions -static inline unsigned int storeUnit(SVGLengthMode mode, SVGLengthType type) -{ - return (mode << 4) | type; -} - -static inline SVGLengthMode extractMode(unsigned int unit) -{ - unsigned int mode = unit >> 4; - return static_cast<SVGLengthMode>(mode); -} - -static inline SVGLengthType extractType(unsigned int unit) -{ - unsigned int mode = unit >> 4; - unsigned int type = unit ^ (mode << 4); - return static_cast<SVGLengthType>(type); -} - -static inline String lengthTypeToString(SVGLengthType type) -{ - switch (type) { - case LengthTypeUnknown: - case LengthTypeNumber: - return ""; - case LengthTypePercentage: - return "%"; - case LengthTypeEMS: - return "em"; - case LengthTypeEXS: - return "ex"; - case LengthTypePX: - return "px"; - case LengthTypeCM: - return "cm"; - case LengthTypeMM: - return "mm"; - case LengthTypeIN: - return "in"; - case LengthTypePT: - return "pt"; - case LengthTypePC: - return "pc"; - } - - ASSERT_NOT_REACHED(); - return String(); -} - -inline SVGLengthType stringToLengthType(const UChar*& ptr, const UChar* end) -{ - if (ptr == end) - return LengthTypeNumber; - - const UChar firstChar = *ptr; - - if (++ptr == end) - return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown; - - const UChar secondChar = *ptr; - - if (++ptr != end) - return LengthTypeUnknown; - - if (firstChar == 'e' && secondChar == 'm') - return LengthTypeEMS; - if (firstChar == 'e' && secondChar == 'x') - return LengthTypeEXS; - if (firstChar == 'p' && secondChar == 'x') - return LengthTypePX; - if (firstChar == 'c' && secondChar == 'm') - return LengthTypeCM; - if (firstChar == 'm' && secondChar == 'm') - return LengthTypeMM; - if (firstChar == 'i' && secondChar == 'n') - return LengthTypeIN; - if (firstChar == 'p' && secondChar == 't') - return LengthTypePT; - if (firstChar == 'p' && secondChar == 'c') - return LengthTypePC; - - return LengthTypeUnknown; -} - -SVGLength::SVGLength(SVGLengthMode mode, const String& valueAsString) - : m_valueInSpecifiedUnits(0) - , m_unit(storeUnit(mode, LengthTypeNumber)) -{ - setValueAsString(valueAsString, IGNORE_EXCEPTION); -} - -SVGLength::SVGLength(const SVGLengthContext& context, float value, SVGLengthMode mode, SVGLengthType unitType) - : m_valueInSpecifiedUnits(0) - , m_unit(storeUnit(mode, unitType)) -{ - setValue(value, context, ASSERT_NO_EXCEPTION); -} - -SVGLength::SVGLength(const SVGLength& other) - : m_valueInSpecifiedUnits(other.m_valueInSpecifiedUnits) - , m_unit(other.m_unit) -{ -} - -void SVGLength::setValueAsString(const String& valueAsString, SVGLengthMode mode, ExceptionCode& ec) -{ - m_valueInSpecifiedUnits = 0; - m_unit = storeUnit(mode, LengthTypeNumber); - setValueAsString(valueAsString, ec); -} - -bool SVGLength::operator==(const SVGLength& other) const -{ - return m_unit == other.m_unit - && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits; -} - -bool SVGLength::operator!=(const SVGLength& other) const -{ - return !operator==(other); -} - -SVGLength SVGLength::construct(SVGLengthMode mode, const String& valueAsString, SVGParsingError& parseError, SVGLengthNegativeValuesMode negativeValuesMode) -{ - ExceptionCode ec = 0; - SVGLength length(mode); - - length.setValueAsString(valueAsString, ec); - - if (ec) - parseError = ParsingAttributeFailedError; - else if (negativeValuesMode == ForbidNegativeLengths && length.valueInSpecifiedUnits() < 0) - parseError = NegativeValueForbiddenError; - - return length; -} - -SVGLengthType SVGLength::unitType() const -{ - return extractType(m_unit); -} - -SVGLengthMode SVGLength::unitMode() const -{ - return extractMode(m_unit); -} - -float SVGLength::value(const SVGLengthContext& context) const -{ - return value(context, IGNORE_EXCEPTION); -} - -float SVGLength::value(const SVGLengthContext& context, ExceptionCode& ec) const -{ - return context.convertValueToUserUnits(m_valueInSpecifiedUnits, extractMode(m_unit), extractType(m_unit), ec); -} - -void SVGLength::setValue(const SVGLengthContext& context, float value, SVGLengthMode mode, SVGLengthType unitType, ExceptionCode& ec) -{ - m_unit = storeUnit(mode, unitType); - setValue(value, context, ec); -} - -void SVGLength::setValue(float value, const SVGLengthContext& context, ExceptionCode& ec) -{ - // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed - if (extractType(m_unit) == LengthTypePercentage) - value = value / 100; - - ec = 0; - float convertedValue = context.convertValueFromUserUnits(value, extractMode(m_unit), extractType(m_unit), ec); - if (!ec) - m_valueInSpecifiedUnits = convertedValue; -} -float SVGLength::valueAsPercentage() const -{ - // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed - if (extractType(m_unit) == LengthTypePercentage) - return m_valueInSpecifiedUnits / 100; - - return m_valueInSpecifiedUnits; -} - -void SVGLength::setValueAsString(const String& string, ExceptionCode& ec) -{ - if (string.isEmpty()) - return; - - float convertedNumber = 0; - const UChar* ptr = string.deprecatedCharacters(); - const UChar* end = ptr + string.length(); - - if (!parseNumber(ptr, end, convertedNumber, false)) { - ec = SYNTAX_ERR; - return; - } - - SVGLengthType type = stringToLengthType(ptr, end); - ASSERT(ptr <= end); - if (type == LengthTypeUnknown) { - ec = SYNTAX_ERR; - return; - } - - m_unit = storeUnit(extractMode(m_unit), type); - m_valueInSpecifiedUnits = convertedNumber; -} - -String SVGLength::valueAsString() const -{ - return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(extractType(m_unit)); -} - -void SVGLength::newValueSpecifiedUnits(unsigned short type, float value, ExceptionCode& ec) -{ - if (type == LengthTypeUnknown || type > LengthTypePC) { - ec = NOT_SUPPORTED_ERR; - return; - } - - m_unit = storeUnit(extractMode(m_unit), static_cast<SVGLengthType>(type)); - m_valueInSpecifiedUnits = value; -} - -void SVGLength::convertToSpecifiedUnits(unsigned short type, const SVGLengthContext& context, ExceptionCode& ec) -{ - if (type == LengthTypeUnknown || type > LengthTypePC) { - ec = NOT_SUPPORTED_ERR; - return; - } - - float valueInUserUnits = value(context, ec); - if (ec) - return; - - unsigned int originalUnitAndType = m_unit; - m_unit = storeUnit(extractMode(m_unit), static_cast<SVGLengthType>(type)); - setValue(valueInUserUnits, context, ec); - if (!ec) - return; - - // Eventually restore old unit and type - m_unit = originalUnitAndType; -} - -SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value) -{ - ASSERT(value); - - SVGLengthType svgType; - switch (value->primitiveType()) { - case CSSPrimitiveValue::CSS_NUMBER: - svgType = LengthTypeNumber; - break; - case CSSPrimitiveValue::CSS_PERCENTAGE: - svgType = LengthTypePercentage; - break; - case CSSPrimitiveValue::CSS_EMS: - svgType = LengthTypeEMS; - break; - case CSSPrimitiveValue::CSS_EXS: - svgType = LengthTypeEXS; - break; - case CSSPrimitiveValue::CSS_PX: - svgType = LengthTypePX; - break; - case CSSPrimitiveValue::CSS_CM: - svgType = LengthTypeCM; - break; - case CSSPrimitiveValue::CSS_MM: - svgType = LengthTypeMM; - break; - case CSSPrimitiveValue::CSS_IN: - svgType = LengthTypeIN; - break; - case CSSPrimitiveValue::CSS_PT: - svgType = LengthTypePT; - break; - case CSSPrimitiveValue::CSS_PC: - svgType = LengthTypePC; - break; - case CSSPrimitiveValue::CSS_UNKNOWN: - default: - svgType = LengthTypeUnknown; - break; - }; - - if (svgType == LengthTypeUnknown) - return SVGLength(); - - ExceptionCode ec = 0; - SVGLength length; - length.newValueSpecifiedUnits(svgType, value->getFloatValue(), ec); - if (ec) - return SVGLength(); - - return length; -} - -PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& length) -{ - CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN; - switch (length.unitType()) { - case LengthTypeUnknown: - break; - case LengthTypeNumber: - cssType = CSSPrimitiveValue::CSS_NUMBER; - break; - case LengthTypePercentage: - cssType = CSSPrimitiveValue::CSS_PERCENTAGE; - break; - case LengthTypeEMS: - cssType = CSSPrimitiveValue::CSS_EMS; - break; - case LengthTypeEXS: - cssType = CSSPrimitiveValue::CSS_EXS; - break; - case LengthTypePX: - cssType = CSSPrimitiveValue::CSS_PX; - break; - case LengthTypeCM: - cssType = CSSPrimitiveValue::CSS_CM; - break; - case LengthTypeMM: - cssType = CSSPrimitiveValue::CSS_MM; - break; - case LengthTypeIN: - cssType = CSSPrimitiveValue::CSS_IN; - break; - case LengthTypePT: - cssType = CSSPrimitiveValue::CSS_PT; - break; - case LengthTypePC: - cssType = CSSPrimitiveValue::CSS_PC; - break; - }; - - return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType); -} - -SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedName& attrName) -{ - typedef HashMap<QualifiedName, SVGLengthMode> LengthModeForLengthAttributeMap; - DEFINE_STATIC_LOCAL(LengthModeForLengthAttributeMap, s_lengthModeMap, ()); - - if (s_lengthModeMap.isEmpty()) { - s_lengthModeMap.set(SVGNames::xAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::yAttr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::cxAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::cyAttr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::dxAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::dyAttr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::fxAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::fyAttr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::rAttr, LengthModeOther); - s_lengthModeMap.set(SVGNames::widthAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::heightAttr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::x1Attr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::x2Attr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::y1Attr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::y2Attr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::refXAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::refYAttr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::markerWidthAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::markerHeightAttr, LengthModeHeight); - s_lengthModeMap.set(SVGNames::textLengthAttr, LengthModeWidth); - s_lengthModeMap.set(SVGNames::startOffsetAttr, LengthModeWidth); - } - - if (s_lengthModeMap.contains(attrName)) - return s_lengthModeMap.get(attrName); - - return LengthModeOther; -} - -} - -#endif diff --git a/Source/WebCore/svg/SVGLength.h b/Source/WebCore/svg/SVGLength.h index 24f6907c2..352c2d1d7 100644 --- a/Source/WebCore/svg/SVGLength.h +++ b/Source/WebCore/svg/SVGLength.h @@ -1,46 +1,37 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGLength_h -#define SVGLength_h +#pragma once -#if ENABLE(SVG) -#include "AnimationUtilities.h" -#include "SVGLengthContext.h" -#include "SVGParsingError.h" -#include "SVGPropertyTraits.h" +#include "ExceptionCode.h" +#include "SVGLengthValue.h" +#include "SVGPropertyTearOff.h" namespace WebCore { -class CSSPrimitiveValue; -class QualifiedName; - -typedef int ExceptionCode; - -enum SVGLengthNegativeValuesMode { - AllowNegativeLengths, - ForbidNegativeLengths -}; - -class SVGLength { - WTF_MAKE_FAST_ALLOCATED; +class SVGLength : public SVGPropertyTearOff<SVGLengthValue> { public: // Forward declare these enums in the w3c naming scheme, for IDL generation enum { @@ -57,120 +48,126 @@ public: SVG_LENGTHTYPE_PC = LengthTypePC }; - SVGLength(SVGLengthMode = LengthModeOther, const String& valueAsString = String()); - SVGLength(const SVGLengthContext&, float, SVGLengthMode = LengthModeOther, SVGLengthType = LengthTypeNumber); - SVGLength(const SVGLength&); - - SVGLengthType unitType() const; - SVGLengthMode unitMode() const; - - bool operator==(const SVGLength&) const; - bool operator!=(const SVGLength&) const; - - static SVGLength construct(SVGLengthMode, const String&, SVGParsingError&, SVGLengthNegativeValuesMode = AllowNegativeLengths); - - float value(const SVGLengthContext&) const; - float value(const SVGLengthContext&, ExceptionCode&) const; - void setValue(float, const SVGLengthContext&, ExceptionCode&); - void setValue(const SVGLengthContext&, float, SVGLengthMode, SVGLengthType, ExceptionCode&); - - float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; } - void setValueInSpecifiedUnits(float value) { m_valueInSpecifiedUnits = value; } - - float valueAsPercentage() const; - - String valueAsString() const; - void setValueAsString(const String&, ExceptionCode&); - void setValueAsString(const String&, SVGLengthMode, ExceptionCode&); - - void newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits, ExceptionCode&); - void convertToSpecifiedUnits(unsigned short, const SVGLengthContext&, ExceptionCode&); - - // Helper functions - inline bool isRelative() const + static Ref<SVGLength> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGLengthValue& value) { - SVGLengthType type = unitType(); - return type == LengthTypePercentage || type == LengthTypeEMS || type == LengthTypeEXS; + return adoptRef(*new SVGLength(animatedProperty, role, value)); } - bool isZero() const - { - return !m_valueInSpecifiedUnits; + static Ref<SVGLength> create(const SVGLengthValue& initialValue = { }) + { + return adoptRef(*new SVGLength(initialValue)); } - static SVGLength fromCSSPrimitiveValue(CSSPrimitiveValue*); - static PassRefPtr<CSSPrimitiveValue> toCSSPrimitiveValue(const SVGLength&); - static SVGLengthMode lengthModeForAnimatedLengthAttribute(const QualifiedName&); - - SVGLength blend(const SVGLength& from, float progress) const + static Ref<SVGLength> create(const SVGLengthValue* initialValue) { - SVGLengthType toType = unitType(); - SVGLengthType fromType = from.unitType(); - if ((from.isZero() && isZero()) - || fromType == LengthTypeUnknown - || toType == LengthTypeUnknown - || (!from.isZero() && fromType != LengthTypePercentage && toType == LengthTypePercentage) - || (!isZero() && fromType == LengthTypePercentage && toType != LengthTypePercentage) - || (!from.isZero() && !isZero() && (fromType == LengthTypeEMS || fromType == LengthTypeEXS) && fromType != toType)) - return *this; + return adoptRef(*new SVGLength(initialValue)); + } - SVGLength length; - ExceptionCode ec = 0; + template<typename T> static ExceptionOr<Ref<SVGLength>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } - if (fromType == LengthTypePercentage || toType == LengthTypePercentage) { - float fromPercent = from.valueAsPercentage() * 100; - float toPercent = valueAsPercentage() * 100; - length.newValueSpecifiedUnits(LengthTypePercentage, WebCore::blend(fromPercent, toPercent, progress), ec); - if (ec) - return SVGLength(); - return length; - } + unsigned short unitType() + { + return propertyReference().unitType(); + } - if (fromType == toType || from.isZero() || isZero() || fromType == LengthTypeEMS || fromType == LengthTypeEXS) { - float fromValue = from.valueInSpecifiedUnits(); - float toValue = valueInSpecifiedUnits(); - if (isZero()) - length.newValueSpecifiedUnits(fromType, WebCore::blend(fromValue, toValue, progress), ec); - else - length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress), ec); - if (ec) - return SVGLength(); - return length; - } + ExceptionOr<float> valueForBindings() + { + return propertyReference().valueForBindings(SVGLengthContext { contextElement() }); + } - ASSERT(!isRelative()); - ASSERT(!from.isRelative()); + ExceptionOr<void> setValueForBindings(float value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().setValue(value, SVGLengthContext { contextElement() }); + if (result.hasException()) + return result; + + commitChange(); + return result; + } + + float valueInSpecifiedUnits() + { + return propertyReference().valueInSpecifiedUnits(); + } - SVGLengthContext nonRelativeLengthContext(0); - float fromValueInUserUnits = nonRelativeLengthContext.convertValueToUserUnits(from.valueInSpecifiedUnits(), from.unitMode(), fromType, ec); - if (ec) - return SVGLength(); + ExceptionOr<void> setValueInSpecifiedUnits(float valueInSpecifiedUnits) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; - float fromValue = nonRelativeLengthContext.convertValueFromUserUnits(fromValueInUserUnits, unitMode(), toType, ec); - if (ec) - return SVGLength(); + propertyReference().setValueInSpecifiedUnits(valueInSpecifiedUnits); + commitChange(); + + return { }; + } + + String valueAsString() + { + return propertyReference().valueAsString(); + } - float toValue = valueInSpecifiedUnits(); - length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress), ec); + ExceptionOr<void> setValueAsString(const String& value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().setValueAsString(value); + if (result.hasException()) + return result; + + commitChange(); + return result; + } - if (ec) - return SVGLength(); - return length; + ExceptionOr<void> newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().newValueSpecifiedUnits(unitType, valueInSpecifiedUnits); + if (result.hasException()) + return result; + + commitChange(); + return result; + } + + ExceptionOr<void> convertToSpecifiedUnits(unsigned short unitType) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().convertToSpecifiedUnits(unitType, SVGLengthContext { contextElement() }); + if (result.hasException()) + return result; + + commitChange(); + return result; } private: - float m_valueInSpecifiedUnits; - unsigned int m_unit; -}; + SVGLength(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGLengthValue& value) + : SVGPropertyTearOff<SVGLengthValue>(&animatedProperty, role, value) + { + } -template<> -struct SVGPropertyTraits<SVGLength> { - static SVGLength initialValue() { return SVGLength(); } - static String toString(const SVGLength& type) { return type.valueAsString(); } -}; + explicit SVGLength(const SVGLengthValue& initialValue) + : SVGPropertyTearOff<SVGLengthValue>(initialValue) + { + } + explicit SVGLength(const SVGLengthValue* initialValue) + : SVGPropertyTearOff<SVGLengthValue>(initialValue) + { + } +}; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGLength_h diff --git a/Source/WebCore/svg/SVGLength.idl b/Source/WebCore/svg/SVGLength.idl index 566d0c9f1..3bc3d44f7 100644 --- a/Source/WebCore/svg/SVGLength.idl +++ b/Source/WebCore/svg/SVGLength.idl @@ -20,31 +20,26 @@ * Boston, MA 02110-1301, USA. */ -[ - Conditional=SVG, -] interface SVGLength { +interface SVGLength { // Length Unit Types - const unsigned short SVG_LENGTHTYPE_UNKNOWN = 0; - const unsigned short SVG_LENGTHTYPE_NUMBER = 1; + const unsigned short SVG_LENGTHTYPE_UNKNOWN = 0; + const unsigned short SVG_LENGTHTYPE_NUMBER = 1; const unsigned short SVG_LENGTHTYPE_PERCENTAGE = 2; - const unsigned short SVG_LENGTHTYPE_EMS = 3; - const unsigned short SVG_LENGTHTYPE_EXS = 4; - const unsigned short SVG_LENGTHTYPE_PX = 5; - const unsigned short SVG_LENGTHTYPE_CM = 6; - const unsigned short SVG_LENGTHTYPE_MM = 7; - const unsigned short SVG_LENGTHTYPE_IN = 8; - const unsigned short SVG_LENGTHTYPE_PT = 9; - const unsigned short SVG_LENGTHTYPE_PC = 10; + const unsigned short SVG_LENGTHTYPE_EMS = 3; + const unsigned short SVG_LENGTHTYPE_EXS = 4; + const unsigned short SVG_LENGTHTYPE_PX = 5; + const unsigned short SVG_LENGTHTYPE_CM = 6; + const unsigned short SVG_LENGTHTYPE_MM = 7; + const unsigned short SVG_LENGTHTYPE_IN = 8; + const unsigned short SVG_LENGTHTYPE_PT = 9; + const unsigned short SVG_LENGTHTYPE_PC = 10; readonly attribute unsigned short unitType; - [GetterRaisesException, SetterRaisesException, Custom, StrictTypeChecking] attribute float value; + [GetterMayThrowException, SetterMayThrowException, ImplementedAs=valueForBindings] attribute unrestricted float value; - [StrictTypeChecking] attribute float valueInSpecifiedUnits; - [TreatNullAs=NullString, StrictTypeChecking, SetterRaisesException] attribute DOMString valueAsString; + [SetterMayThrowException] attribute unrestricted float valueInSpecifiedUnits; + [SetterMayThrowException] attribute DOMString valueAsString; - [StrictTypeChecking, RaisesException] void newValueSpecifiedUnits(unsigned short unitType, - float valueInSpecifiedUnits); - - [Custom, StrictTypeChecking, RaisesException] void convertToSpecifiedUnits(unsigned short unitType); + [MayThrowException] void newValueSpecifiedUnits(unsigned short unitType, unrestricted float valueInSpecifiedUnits); + [MayThrowException] void convertToSpecifiedUnits(unsigned short unitType); }; - diff --git a/Source/WebCore/svg/SVGLengthContext.cpp b/Source/WebCore/svg/SVGLengthContext.cpp index 07b2045bf..fff1e879f 100644 --- a/Source/WebCore/svg/SVGLengthContext.cpp +++ b/Source/WebCore/svg/SVGLengthContext.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> * Copyright (C) 2007 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -21,18 +22,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGLengthContext.h" #include "CSSHelper.h" #include "ExceptionCode.h" #include "FontMetrics.h" #include "Frame.h" +#include "LengthFunctions.h" #include "RenderSVGRoot.h" #include "RenderSVGViewportContainer.h" #include "RenderView.h" -#include "SVGNames.h" #include "SVGSVGElement.h" namespace WebCore { @@ -48,7 +47,7 @@ SVGLengthContext::SVGLengthContext(const SVGElement* context, const FloatRect& v { } -FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, const SVGLength& x, const SVGLength& y, const SVGLength& width, const SVGLength& height) +FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, const SVGLengthValue& x, const SVGLengthValue& y, const SVGLengthValue& width, const SVGLengthValue& height) { ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { @@ -63,7 +62,7 @@ FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitT height.value(lengthContext)); } -FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x, const SVGLength& y) +FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLengthValue& x, const SVGLengthValue& y) { ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { @@ -75,7 +74,7 @@ FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitType return FloatPoint(x.valueAsPercentage(), y.valueAsPercentage()); } -float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x) +float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLengthValue& x) { ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { @@ -87,30 +86,54 @@ float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::S return x.valueAsPercentage(); } -float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit, ExceptionCode& ec) const +float SVGLengthContext::valueForLength(const Length& length, SVGLengthMode mode) +{ + if (length.isPercent()) { + auto result = convertValueFromPercentageToUserUnits(length.value() / 100, mode); + if (result.hasException()) + return 0; + return result.releaseReturnValue(); + } + if (length.isAuto() || !length.isSpecified()) + return 0; + + FloatSize viewportSize; + determineViewport(viewportSize); + + switch (mode) { + case LengthModeWidth: + return floatValueForLength(length, viewportSize.width()); + case LengthModeHeight: + return floatValueForLength(length, viewportSize.height()); + case LengthModeOther: + return floatValueForLength(length, std::sqrt(viewportSize.diagonalLengthSquared() / 2)); + }; + return 0; +} + +ExceptionOr<float> SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit) const { // If the SVGLengthContext carries a custom viewport, force resolving against it. if (!m_overridenViewport.isEmpty()) { // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed if (fromUnit == LengthTypePercentage) value /= 100; - return convertValueFromPercentageToUserUnits(value, mode, ec); + return convertValueFromPercentageToUserUnits(value, mode); } switch (fromUnit) { case LengthTypeUnknown: - ec = NOT_SUPPORTED_ERR; - return 0; + return Exception { NOT_SUPPORTED_ERR }; case LengthTypeNumber: return value; case LengthTypePX: return value; case LengthTypePercentage: - return convertValueFromPercentageToUserUnits(value / 100, mode, ec); + return convertValueFromPercentageToUserUnits(value / 100, mode); case LengthTypeEMS: - return convertValueFromEMSToUserUnits(value, ec); + return convertValueFromEMSToUserUnits(value); case LengthTypeEXS: - return convertValueFromEXSToUserUnits(value, ec); + return convertValueFromEXSToUserUnits(value); case LengthTypeCM: return value * cssPixelsPerInch / 2.54f; case LengthTypeMM: @@ -127,20 +150,19 @@ float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, return 0; } -float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mode, SVGLengthType toUnit, ExceptionCode& ec) const +ExceptionOr<float> SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mode, SVGLengthType toUnit) const { switch (toUnit) { case LengthTypeUnknown: - ec = NOT_SUPPORTED_ERR; - return 0; + return Exception { NOT_SUPPORTED_ERR }; case LengthTypeNumber: return value; case LengthTypePercentage: - return convertValueFromUserUnitsToPercentage(value * 100, mode, ec); + return convertValueFromUserUnitsToPercentage(value * 100, mode); case LengthTypeEMS: - return convertValueFromUserUnitsToEMS(value, ec); + return convertValueFromUserUnitsToEMS(value); case LengthTypeEXS: - return convertValueFromUserUnitsToEXS(value, ec); + return convertValueFromUserUnitsToEXS(value); case LengthTypePX: return value; case LengthTypeCM: @@ -159,13 +181,11 @@ float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mod return 0; } -float SVGLengthContext::convertValueFromUserUnitsToPercentage(float value, SVGLengthMode mode, ExceptionCode& ec) const +ExceptionOr<float> SVGLengthContext::convertValueFromUserUnitsToPercentage(float value, SVGLengthMode mode) const { FloatSize viewportSize; - if (!determineViewport(viewportSize)) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + if (!determineViewport(viewportSize)) + return Exception { NOT_SUPPORTED_ERR }; switch (mode) { case LengthModeWidth: @@ -173,20 +193,18 @@ float SVGLengthContext::convertValueFromUserUnitsToPercentage(float value, SVGLe case LengthModeHeight: return value / viewportSize.height() * 100; case LengthModeOther: - return value / (sqrtf(viewportSize.diagonalLengthSquared() / 2)) * 100; + return value / (std::sqrt(viewportSize.diagonalLengthSquared() / 2)) * 100; }; ASSERT_NOT_REACHED(); return 0; } -float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLengthMode mode, ExceptionCode& ec) const +ExceptionOr<float> SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLengthMode mode) const { FloatSize viewportSize; - if (!determineViewport(viewportSize)) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + if (!determineViewport(viewportSize)) + return Exception { NOT_SUPPORTED_ERR }; switch (mode) { case LengthModeWidth: @@ -194,14 +212,14 @@ float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLe case LengthModeHeight: return value * viewportSize.height(); case LengthModeOther: - return value * sqrtf(viewportSize.diagonalLengthSquared() / 2); + return value * std::sqrt(viewportSize.diagonalLengthSquared() / 2); }; ASSERT_NOT_REACHED(); return 0; } -static inline RenderStyle* renderStyleForLengthResolving(const SVGElement* context) +static inline const RenderStyle* renderStyleForLengthResolving(const SVGElement* context) { if (!context) return nullptr; @@ -215,67 +233,55 @@ static inline RenderStyle* renderStyleForLengthResolving(const SVGElement* conte // There must be at least a RenderSVGRoot renderer, carrying a style. ASSERT_NOT_REACHED(); - return 0; + return nullptr; } -float SVGLengthContext::convertValueFromUserUnitsToEMS(float value, ExceptionCode& ec) const +ExceptionOr<float> SVGLengthContext::convertValueFromUserUnitsToEMS(float value) const { - RenderStyle* style = renderStyleForLengthResolving(m_context); - if (!style) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + auto* style = renderStyleForLengthResolving(m_context); + if (!style) + return Exception { NOT_SUPPORTED_ERR }; float fontSize = style->fontSize(); - if (!fontSize) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + if (!fontSize) + return Exception { NOT_SUPPORTED_ERR }; return value / fontSize; } -float SVGLengthContext::convertValueFromEMSToUserUnits(float value, ExceptionCode& ec) const +ExceptionOr<float> SVGLengthContext::convertValueFromEMSToUserUnits(float value) const { - RenderStyle* style = renderStyleForLengthResolving(m_context); - if (!style) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + auto* style = renderStyleForLengthResolving(m_context); + if (!style) + return Exception { NOT_SUPPORTED_ERR }; return value * style->fontSize(); } -float SVGLengthContext::convertValueFromUserUnitsToEXS(float value, ExceptionCode& ec) const +ExceptionOr<float> SVGLengthContext::convertValueFromUserUnitsToEXS(float value) const { - RenderStyle* style = renderStyleForLengthResolving(m_context); - if (!style) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + auto* style = renderStyleForLengthResolving(m_context); + if (!style) + return Exception { NOT_SUPPORTED_ERR }; // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg // if this causes problems in real world cases maybe it would be best to remove this - float xHeight = ceilf(style->fontMetrics().xHeight()); - if (!xHeight) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + float xHeight = std::ceil(style->fontMetrics().xHeight()); + if (!xHeight) + return Exception { NOT_SUPPORTED_ERR }; return value / xHeight; } -float SVGLengthContext::convertValueFromEXSToUserUnits(float value, ExceptionCode& ec) const +ExceptionOr<float> SVGLengthContext::convertValueFromEXSToUserUnits(float value) const { - RenderStyle* style = renderStyleForLengthResolving(m_context); - if (!style) { - ec = NOT_SUPPORTED_ERR; - return 0; - } + auto* style = renderStyleForLengthResolving(m_context); + if (!style) + return Exception { NOT_SUPPORTED_ERR }; // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg // if this causes problems in real world cases maybe it would be best to remove this - return value * ceilf(style->fontMetrics().xHeight()); + return value * std::ceil(style->fontMetrics().xHeight()); } bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const @@ -291,23 +297,21 @@ bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const // Root <svg> element lengths are resolved against the top level viewport. if (m_context->isOutermostSVGSVGElement()) { - viewportSize = toSVGSVGElement(m_context)->currentViewportSize(); + viewportSize = downcast<SVGSVGElement>(*m_context).currentViewportSize(); return true; } // Take size from nearest viewport element. SVGElement* viewportElement = m_context->viewportElement(); - if (!viewportElement || !isSVGSVGElement(viewportElement)) + if (!is<SVGSVGElement>(viewportElement)) return false; - const SVGSVGElement* svg = toSVGSVGElement(viewportElement); - viewportSize = svg->currentViewBoxRect().size(); + const SVGSVGElement& svg = downcast<SVGSVGElement>(*viewportElement); + viewportSize = svg.currentViewBoxRect().size(); if (viewportSize.isEmpty()) - viewportSize = svg->currentViewportSize(); + viewportSize = svg.currentViewportSize(); return true; } } - -#endif diff --git a/Source/WebCore/svg/SVGLengthContext.h b/Source/WebCore/svg/SVGLengthContext.h index c7070f8b6..b03eb1f8f 100644 --- a/Source/WebCore/svg/SVGLengthContext.h +++ b/Source/WebCore/svg/SVGLengthContext.h @@ -17,19 +17,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGLengthContext_h -#define SVGLengthContext_h +#pragma once -#if ENABLE(SVG) +#include "ExceptionOr.h" #include "FloatRect.h" #include "SVGUnitTypes.h" namespace WebCore { class SVGElement; -class SVGLength; +class SVGLengthValue; -typedef int ExceptionCode; +struct Length; enum SVGLengthType { LengthTypeUnknown = 0, @@ -61,32 +60,30 @@ public: return SVGLengthContext::resolveRectangle(context, type, viewport, context->x(), context->y(), context->width(), context->height()); } - static FloatRect resolveRectangle(const SVGElement*, SVGUnitTypes::SVGUnitType, const FloatRect& viewport, const SVGLength& x, const SVGLength& y, const SVGLength& width, const SVGLength& height); - static FloatPoint resolvePoint(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLength& x, const SVGLength& y); - static float resolveLength(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLength&); + static FloatRect resolveRectangle(const SVGElement*, SVGUnitTypes::SVGUnitType, const FloatRect& viewport, const SVGLengthValue& x, const SVGLengthValue& y, const SVGLengthValue& width, const SVGLengthValue& height); + static FloatPoint resolvePoint(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLengthValue& x, const SVGLengthValue& y); + static float resolveLength(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLengthValue&); - float convertValueToUserUnits(float, SVGLengthMode, SVGLengthType fromUnit, ExceptionCode&) const; - float convertValueFromUserUnits(float, SVGLengthMode, SVGLengthType toUnit, ExceptionCode&) const; + float valueForLength(const Length&, SVGLengthMode = LengthModeOther); + ExceptionOr<float> convertValueToUserUnits(float, SVGLengthMode, SVGLengthType fromUnit) const; + ExceptionOr<float> convertValueFromUserUnits(float, SVGLengthMode, SVGLengthType toUnit) const; bool determineViewport(FloatSize&) const; private: SVGLengthContext(const SVGElement*, const FloatRect& viewport); - float convertValueFromUserUnitsToPercentage(float value, SVGLengthMode, ExceptionCode&) const; - float convertValueFromPercentageToUserUnits(float value, SVGLengthMode, ExceptionCode&) const; + ExceptionOr<float> convertValueFromUserUnitsToPercentage(float value, SVGLengthMode) const; + ExceptionOr<float> convertValueFromPercentageToUserUnits(float value, SVGLengthMode) const; - float convertValueFromUserUnitsToEMS(float value, ExceptionCode&) const; - float convertValueFromEMSToUserUnits(float value, ExceptionCode&) const; + ExceptionOr<float> convertValueFromUserUnitsToEMS(float value) const; + ExceptionOr<float> convertValueFromEMSToUserUnits(float value) const; - float convertValueFromUserUnitsToEXS(float value, ExceptionCode&) const; - float convertValueFromEXSToUserUnits(float value, ExceptionCode&) const; + ExceptionOr<float> convertValueFromUserUnitsToEXS(float value) const; + ExceptionOr<float> convertValueFromEXSToUserUnits(float value) const; const SVGElement* m_context; FloatRect m_overridenViewport; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGLengthContext_h diff --git a/Source/WebCore/svg/SVGLengthList.h b/Source/WebCore/svg/SVGLengthList.h index 865f7bcba..9abaa4ffe 100644 --- a/Source/WebCore/svg/SVGLengthList.h +++ b/Source/WebCore/svg/SVGLengthList.h @@ -1,49 +1,51 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGLengthList_h -#define SVGLengthList_h +#pragma once -#if ENABLE(SVG) -#include "SVGLength.h" -#include <wtf/Vector.h> +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGLengthListValues.h" +#include "SVGListPropertyTearOff.h" namespace WebCore { -class SVGLengthList : public Vector<SVGLength> { +class SVGLengthList : public SVGListPropertyTearOff<SVGLengthListValues> { public: - SVGLengthList() { } - - void parse(const String& value, SVGLengthMode); - String valueAsString() const; -}; - -template<> -struct SVGPropertyTraits<SVGLengthList> { - typedef SVGLength ListItemType; - - static SVGLengthList initialValue() { return SVGLengthList(); } - static String toString(const SVGLengthList& type) { return type.valueAsString(); } + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<SVGLengthListValues>; + using ListWrapperCache = AnimatedListPropertyTearOff::ListWrapperCache; + + static Ref<SVGLengthList> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGLengthListValues& values, ListWrapperCache& wrappers) + { + return adoptRef(*new SVGLengthList(animatedProperty, role, values, wrappers)); + } + +private: + SVGLengthList(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGLengthListValues& values, ListWrapperCache& wrappers) + : SVGListPropertyTearOff<SVGLengthListValues>(animatedProperty, role, values, wrappers) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGLengthList.idl b/Source/WebCore/svg/SVGLengthList.idl index f52cc80ee..dd89097f8 100644 --- a/Source/WebCore/svg/SVGLengthList.idl +++ b/Source/WebCore/svg/SVGLengthList.idl @@ -25,16 +25,15 @@ */ [ - Conditional=SVG, -] interface SVGLengthList { + SkipVTableValidation +] interface SVGLengthList { readonly attribute unsigned long numberOfItems; - [RaisesException] void clear(); - [StrictTypeChecking, RaisesException] SVGLength initialize(SVGLength item); - [StrictTypeChecking, RaisesException] SVGLength getItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGLength insertItemBefore(SVGLength item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGLength replaceItem(SVGLength item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGLength removeItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGLength appendItem(SVGLength item); + [MayThrowException] void clear(); + [MayThrowException] SVGLength initialize(SVGLength item); + [MayThrowException] SVGLength getItem(unsigned long index); + [MayThrowException] SVGLength insertItemBefore(SVGLength item, unsigned long index); + [MayThrowException] SVGLength replaceItem(SVGLength item, unsigned long index); + [MayThrowException] SVGLength removeItem(unsigned long index); + [MayThrowException] SVGLength appendItem(SVGLength item); }; - diff --git a/Source/WebCore/svg/SVGLengthList.cpp b/Source/WebCore/svg/SVGLengthListValues.cpp index 31c73f437..ba2064823 100644 --- a/Source/WebCore/svg/SVGLengthList.cpp +++ b/Source/WebCore/svg/SVGLengthListValues.cpp @@ -19,21 +19,19 @@ */ #include "config.h" - -#if ENABLE(SVG) -#include "SVGLengthList.h" +#include "SVGLengthListValues.h" #include "SVGParserUtilities.h" #include <wtf/text/StringBuilder.h> namespace WebCore { -void SVGLengthList::parse(const String& value, SVGLengthMode mode) +void SVGLengthListValues::parse(const String& value, SVGLengthMode mode) { clear(); - ExceptionCode ec = 0; - const UChar* ptr = value.deprecatedCharacters(); + auto upconvertedCharacters = StringView(value).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + value.length(); while (ptr < end) { const UChar* start = ptr; @@ -42,19 +40,18 @@ void SVGLengthList::parse(const String& value, SVGLengthMode mode) if (ptr == start) break; - SVGLength length(mode); + SVGLengthValue length(mode); String valueString(start, ptr - start); if (valueString.isEmpty()) return; - length.setValueAsString(valueString, ec); - if (ec) + if (length.setValueAsString(valueString).hasException()) return; append(length); skipOptionalSVGSpacesOrDelimiter(ptr, end); } } -String SVGLengthList::valueAsString() const +String SVGLengthListValues::valueAsString() const { StringBuilder builder; @@ -70,5 +67,3 @@ String SVGLengthList::valueAsString() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGElementInstanceList.h b/Source/WebCore/svg/SVGLengthListValues.h index ed190c012..fdc839fc1 100644 --- a/Source/WebCore/svg/SVGElementInstanceList.h +++ b/Source/WebCore/svg/SVGLengthListValues.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,35 +18,29 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGElementInstanceList_h -#define SVGElementInstanceList_h +#pragma once -#if ENABLE(SVG) -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> +#include "SVGLengthValue.h" +#include <wtf/Vector.h> namespace WebCore { -class SVGElementInstance; +class SVGLength; +class SVGLengthList; -class SVGElementInstanceList : public RefCounted<SVGElementInstanceList> { +class SVGLengthListValues final : public Vector<SVGLengthValue> { public: - static PassRefPtr<SVGElementInstanceList> create(PassRefPtr<SVGElementInstance> root) { return adoptRef(new SVGElementInstanceList(root)); } - virtual ~SVGElementInstanceList(); - - unsigned length() const; - SVGElementInstance* item(unsigned index); + void parse(const String& value, SVGLengthMode); + String valueAsString() const; +}; -private: - SVGElementInstanceList(PassRefPtr<SVGElementInstance>); +template<> struct SVGPropertyTraits<SVGLengthListValues> { + using ListItemType = SVGLengthValue; + using ListItemTearOff = SVGLength; + using ListPropertyTearOff = SVGLengthList; - RefPtr<SVGElementInstance> m_rootInstance; + static SVGLengthListValues initialValue() { return { }; } + static String toString(const SVGLengthListValues& type) { return type.valueAsString(); } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGLengthValue.cpp b/Source/WebCore/svg/SVGLengthValue.cpp new file mode 100644 index 000000000..6387e4a91 --- /dev/null +++ b/Source/WebCore/svg/SVGLengthValue.cpp @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2007 Apple Inc. 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" +#include "SVGLengthValue.h" + +#include "CSSHelper.h" +#include "CSSPrimitiveValue.h" +#include "ExceptionCode.h" +#include "FloatConversion.h" +#include "SVGNames.h" +#include "SVGParserUtilities.h" +#include "TextStream.h" +#include <wtf/MathExtras.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/text/StringView.h> + +namespace WebCore { + +// Helper functions +static inline unsigned storeUnit(SVGLengthMode mode, SVGLengthType type) +{ + return (mode << 4) | type; +} + +static inline SVGLengthMode extractMode(unsigned unit) +{ + unsigned mode = unit >> 4; + return static_cast<SVGLengthMode>(mode); +} + +static inline SVGLengthType extractType(unsigned unit) +{ + return static_cast<SVGLengthType>(unit & ((1 << 4) - 1)); +} + +static inline const char* lengthTypeToString(SVGLengthType type) +{ + switch (type) { + case LengthTypeUnknown: + case LengthTypeNumber: + return ""; + case LengthTypePercentage: + return "%"; + case LengthTypeEMS: + return "em"; + case LengthTypeEXS: + return "ex"; + case LengthTypePX: + return "px"; + case LengthTypeCM: + return "cm"; + case LengthTypeMM: + return "mm"; + case LengthTypeIN: + return "in"; + case LengthTypePT: + return "pt"; + case LengthTypePC: + return "pc"; + } + + ASSERT_NOT_REACHED(); + return ""; +} + +inline SVGLengthType parseLengthType(const UChar* ptr, const UChar* end) +{ + if (ptr == end) + return LengthTypeNumber; + + const UChar firstChar = *ptr; + + if (++ptr == end) + return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown; + + const UChar secondChar = *ptr; + + if (++ptr != end) + return LengthTypeUnknown; + + if (firstChar == 'e' && secondChar == 'm') + return LengthTypeEMS; + if (firstChar == 'e' && secondChar == 'x') + return LengthTypeEXS; + if (firstChar == 'p' && secondChar == 'x') + return LengthTypePX; + if (firstChar == 'c' && secondChar == 'm') + return LengthTypeCM; + if (firstChar == 'm' && secondChar == 'm') + return LengthTypeMM; + if (firstChar == 'i' && secondChar == 'n') + return LengthTypeIN; + if (firstChar == 'p' && secondChar == 't') + return LengthTypePT; + if (firstChar == 'p' && secondChar == 'c') + return LengthTypePC; + + return LengthTypeUnknown; +} + +SVGLengthValue::SVGLengthValue(SVGLengthMode mode, const String& valueAsString) + : m_unit(storeUnit(mode, LengthTypeNumber)) +{ + setValueAsString(valueAsString); +} + +SVGLengthValue::SVGLengthValue(const SVGLengthContext& context, float value, SVGLengthMode mode, SVGLengthType unitType) + : m_unit(storeUnit(mode, unitType)) +{ + setValue(value, context); +} + +ExceptionOr<void> SVGLengthValue::setValueAsString(const String& valueAsString, SVGLengthMode mode) +{ + m_valueInSpecifiedUnits = 0; + m_unit = storeUnit(mode, LengthTypeNumber); + return setValueAsString(valueAsString); +} + +bool SVGLengthValue::operator==(const SVGLengthValue& other) const +{ + return m_unit == other.m_unit && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits; +} + +bool SVGLengthValue::operator!=(const SVGLengthValue& other) const +{ + return !operator==(other); +} + +SVGLengthValue SVGLengthValue::construct(SVGLengthMode mode, const String& valueAsString, SVGParsingError& parseError, SVGLengthNegativeValuesMode negativeValuesMode) +{ + SVGLengthValue length(mode); + + if (length.setValueAsString(valueAsString).hasException()) + parseError = ParsingAttributeFailedError; + else if (negativeValuesMode == ForbidNegativeLengths && length.valueInSpecifiedUnits() < 0) + parseError = NegativeValueForbiddenError; + + return length; +} + +SVGLengthType SVGLengthValue::unitType() const +{ + return extractType(m_unit); +} + +SVGLengthMode SVGLengthValue::unitMode() const +{ + return extractMode(m_unit); +} + +float SVGLengthValue::value(const SVGLengthContext& context) const +{ + auto result = valueForBindings(context); + if (result.hasException()) + return 0; + return result.releaseReturnValue(); +} + +ExceptionOr<float> SVGLengthValue::valueForBindings(const SVGLengthContext& context) const +{ + return context.convertValueToUserUnits(m_valueInSpecifiedUnits, extractMode(m_unit), extractType(m_unit)); +} + +ExceptionOr<void> SVGLengthValue::setValue(const SVGLengthContext& context, float value, SVGLengthMode mode, SVGLengthType unitType) +{ + // FIXME: Seems like a bug that we change the value of m_unit even if setValue throws an exception. + m_unit = storeUnit(mode, unitType); + return setValue(value, context); +} + +ExceptionOr<void> SVGLengthValue::setValue(float value, const SVGLengthContext& context) +{ + // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed + if (extractType(m_unit) == LengthTypePercentage) + value = value / 100; + + auto convertedValue = context.convertValueFromUserUnits(value, extractMode(m_unit), extractType(m_unit)); + if (convertedValue.hasException()) + return convertedValue.releaseException(); + m_valueInSpecifiedUnits = convertedValue.releaseReturnValue(); + return { }; +} +float SVGLengthValue::valueAsPercentage() const +{ + // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed + if (extractType(m_unit) == LengthTypePercentage) + return m_valueInSpecifiedUnits / 100; + + return m_valueInSpecifiedUnits; +} + +ExceptionOr<void> SVGLengthValue::setValueAsString(const String& string) +{ + if (string.isEmpty()) + return { }; + + float convertedNumber = 0; + auto upconvertedCharacters = StringView(string).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; + const UChar* end = ptr + string.length(); + + if (!parseNumber(ptr, end, convertedNumber, false)) + return Exception { SYNTAX_ERR }; + + auto type = parseLengthType(ptr, end); + if (type == LengthTypeUnknown) + return Exception { SYNTAX_ERR }; + + m_unit = storeUnit(extractMode(m_unit), type); + m_valueInSpecifiedUnits = convertedNumber; + return { }; +} + +String SVGLengthValue::valueAsString() const +{ + return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(extractType(m_unit)); +} + +ExceptionOr<void> SVGLengthValue::newValueSpecifiedUnits(unsigned short type, float value) +{ + if (type == LengthTypeUnknown || type > LengthTypePC) + return Exception { NOT_SUPPORTED_ERR }; + + m_unit = storeUnit(extractMode(m_unit), static_cast<SVGLengthType>(type)); + m_valueInSpecifiedUnits = value; + return { }; +} + +ExceptionOr<void> SVGLengthValue::convertToSpecifiedUnits(unsigned short type, const SVGLengthContext& context) +{ + if (type == LengthTypeUnknown || type > LengthTypePC) + return Exception { NOT_SUPPORTED_ERR }; + + auto valueInUserUnits = valueForBindings(context); + if (valueInUserUnits.hasException()) + return valueInUserUnits.releaseException(); + + auto originalUnitAndType = m_unit; + m_unit = storeUnit(extractMode(m_unit), static_cast<SVGLengthType>(type)); + auto result = setValue(valueInUserUnits.releaseReturnValue(), context); + if (result.hasException()) { + m_unit = originalUnitAndType; + return result.releaseException(); + } + + return { }; +} + +SVGLengthValue SVGLengthValue::fromCSSPrimitiveValue(const CSSPrimitiveValue& value) +{ + SVGLengthType type; + switch (value.primitiveType()) { + case CSSPrimitiveValue::CSS_NUMBER: + type = LengthTypeNumber; + break; + case CSSPrimitiveValue::CSS_PERCENTAGE: + type = LengthTypePercentage; + break; + case CSSPrimitiveValue::CSS_EMS: + type = LengthTypeEMS; + break; + case CSSPrimitiveValue::CSS_EXS: + type = LengthTypeEXS; + break; + case CSSPrimitiveValue::CSS_PX: + type = LengthTypePX; + break; + case CSSPrimitiveValue::CSS_CM: + type = LengthTypeCM; + break; + case CSSPrimitiveValue::CSS_MM: + type = LengthTypeMM; + break; + case CSSPrimitiveValue::CSS_IN: + type = LengthTypeIN; + break; + case CSSPrimitiveValue::CSS_PT: + type = LengthTypePT; + break; + case CSSPrimitiveValue::CSS_PC: + type = LengthTypePC; + break; + case CSSPrimitiveValue::CSS_UNKNOWN: + default: + return { }; + }; + + SVGLengthValue length; + length.newValueSpecifiedUnits(type, value.floatValue()); + return length; +} + +Ref<CSSPrimitiveValue> SVGLengthValue::toCSSPrimitiveValue(const SVGLengthValue& length) +{ + CSSPrimitiveValue::UnitType cssType = CSSPrimitiveValue::CSS_UNKNOWN; + switch (length.unitType()) { + case LengthTypeUnknown: + break; + case LengthTypeNumber: + cssType = CSSPrimitiveValue::CSS_NUMBER; + break; + case LengthTypePercentage: + cssType = CSSPrimitiveValue::CSS_PERCENTAGE; + break; + case LengthTypeEMS: + cssType = CSSPrimitiveValue::CSS_EMS; + break; + case LengthTypeEXS: + cssType = CSSPrimitiveValue::CSS_EXS; + break; + case LengthTypePX: + cssType = CSSPrimitiveValue::CSS_PX; + break; + case LengthTypeCM: + cssType = CSSPrimitiveValue::CSS_CM; + break; + case LengthTypeMM: + cssType = CSSPrimitiveValue::CSS_MM; + break; + case LengthTypeIN: + cssType = CSSPrimitiveValue::CSS_IN; + break; + case LengthTypePT: + cssType = CSSPrimitiveValue::CSS_PT; + break; + case LengthTypePC: + cssType = CSSPrimitiveValue::CSS_PC; + break; + }; + + return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType); +} + +SVGLengthMode SVGLengthValue::lengthModeForAnimatedLengthAttribute(const QualifiedName& attrName) +{ + using Map = HashMap<QualifiedName, SVGLengthMode>; + static NeverDestroyed<Map> map = [] { + struct Mode { + const QualifiedName& name; + SVGLengthMode mode; + }; + static const Mode modes[] = { + { SVGNames::xAttr, LengthModeWidth }, + { SVGNames::yAttr, LengthModeHeight }, + { SVGNames::cxAttr, LengthModeWidth }, + { SVGNames::cyAttr, LengthModeHeight }, + { SVGNames::dxAttr, LengthModeWidth }, + { SVGNames::dyAttr, LengthModeHeight }, + { SVGNames::fxAttr, LengthModeWidth }, + { SVGNames::fyAttr, LengthModeHeight }, + { SVGNames::widthAttr, LengthModeWidth }, + { SVGNames::heightAttr, LengthModeHeight }, + { SVGNames::x1Attr, LengthModeWidth }, + { SVGNames::x2Attr, LengthModeWidth }, + { SVGNames::y1Attr, LengthModeHeight }, + { SVGNames::y2Attr, LengthModeHeight }, + { SVGNames::refXAttr, LengthModeWidth }, + { SVGNames::refYAttr, LengthModeHeight }, + { SVGNames::markerWidthAttr, LengthModeWidth }, + { SVGNames::markerHeightAttr, LengthModeHeight }, + { SVGNames::textLengthAttr, LengthModeWidth }, + { SVGNames::startOffsetAttr, LengthModeWidth }, + }; + Map map; + for (auto& mode : modes) + map.add(mode.name, mode.mode); + return map; + }(); + + auto result = map.get().find(attrName); + if (result == map.get().end()) + return LengthModeOther; + return result->value; +} + +TextStream& operator<<(TextStream& ts, const SVGLengthValue& length) +{ + ts << length.valueAsString(); + return ts; +} + +} diff --git a/Source/WebCore/svg/SVGLengthValue.h b/Source/WebCore/svg/SVGLengthValue.h new file mode 100644 index 000000000..c7082b4fa --- /dev/null +++ b/Source/WebCore/svg/SVGLengthValue.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@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. + */ + +#pragma once + +#include "AnimationUtilities.h" +#include "SVGLengthContext.h" +#include "SVGParsingError.h" +#include "SVGPropertyTraits.h" + +namespace WebCore { + +class CSSPrimitiveValue; +class QualifiedName; + +enum SVGLengthNegativeValuesMode { + AllowNegativeLengths, + ForbidNegativeLengths +}; + +class SVGLengthValue { + WTF_MAKE_FAST_ALLOCATED; +public: + // FIXME: Once all SVGLengthValue users use Length internally, we make this a wrapper for Length. + SVGLengthValue(SVGLengthMode = LengthModeOther, const String& valueAsString = String()); + SVGLengthValue(const SVGLengthContext&, float, SVGLengthMode = LengthModeOther, SVGLengthType = LengthTypeNumber); + + SVGLengthType unitType() const; + SVGLengthMode unitMode() const; + + bool operator==(const SVGLengthValue&) const; + bool operator!=(const SVGLengthValue&) const; + + static SVGLengthValue construct(SVGLengthMode, const String&, SVGParsingError&, SVGLengthNegativeValuesMode = AllowNegativeLengths); + + float value(const SVGLengthContext&) const; + ExceptionOr<float> valueForBindings(const SVGLengthContext&) const; + ExceptionOr<void> setValue(float, const SVGLengthContext&); + ExceptionOr<void> setValue(const SVGLengthContext&, float, SVGLengthMode, SVGLengthType); + + float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; } + void setValueInSpecifiedUnits(float value) { m_valueInSpecifiedUnits = value; } + + float valueAsPercentage() const; + + String valueAsString() const; + ExceptionOr<void> setValueAsString(const String&); + ExceptionOr<void> setValueAsString(const String&, SVGLengthMode); + + ExceptionOr<void> newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits); + ExceptionOr<void> convertToSpecifiedUnits(unsigned short, const SVGLengthContext&); + + // Helper functions + bool isRelative() const + { + auto type = unitType(); + return type == LengthTypePercentage || type == LengthTypeEMS || type == LengthTypeEXS; + } + + bool isZero() const + { + return !m_valueInSpecifiedUnits; + } + + static SVGLengthValue fromCSSPrimitiveValue(const CSSPrimitiveValue&); + static Ref<CSSPrimitiveValue> toCSSPrimitiveValue(const SVGLengthValue&); + static SVGLengthMode lengthModeForAnimatedLengthAttribute(const QualifiedName&); + + SVGLengthValue blend(const SVGLengthValue& from, float progress) const + { + auto toType = unitType(); + auto fromType = from.unitType(); + if ((from.isZero() && isZero()) + || fromType == LengthTypeUnknown + || toType == LengthTypeUnknown + || (!from.isZero() && fromType != LengthTypePercentage && toType == LengthTypePercentage) + || (!isZero() && fromType == LengthTypePercentage && toType != LengthTypePercentage) + || (!from.isZero() && !isZero() && (fromType == LengthTypeEMS || fromType == LengthTypeEXS) && fromType != toType)) + return *this; + + SVGLengthValue length; + + if (fromType == LengthTypePercentage || toType == LengthTypePercentage) { + auto fromPercent = from.valueAsPercentage() * 100; + auto toPercent = valueAsPercentage() * 100; + auto result = length.newValueSpecifiedUnits(LengthTypePercentage, WebCore::blend(fromPercent, toPercent, progress)); + if (result.hasException()) + return { }; + return length; + } + + if (fromType == toType || from.isZero() || isZero() || fromType == LengthTypeEMS || fromType == LengthTypeEXS) { + auto fromValue = from.valueInSpecifiedUnits(); + auto toValue = valueInSpecifiedUnits(); + if (isZero()) { + auto result = length.newValueSpecifiedUnits(fromType, WebCore::blend(fromValue, toValue, progress)); + if (result.hasException()) + return { }; + } else { + auto result = length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress)); + if (result.hasException()) + return { }; + } + return length; + } + + ASSERT(!isRelative()); + ASSERT(!from.isRelative()); + + SVGLengthContext nonRelativeLengthContext(nullptr); + auto fromValueInUserUnits = nonRelativeLengthContext.convertValueToUserUnits(from.valueInSpecifiedUnits(), from.unitMode(), fromType); + if (fromValueInUserUnits.hasException()) + return { }; + + auto fromValue = nonRelativeLengthContext.convertValueFromUserUnits(fromValueInUserUnits.releaseReturnValue(), unitMode(), toType); + if (fromValue.hasException()) + return { }; + + float toValue = valueInSpecifiedUnits(); + auto result = length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue.releaseReturnValue(), toValue, progress)); + if (result.hasException()) + return { }; + return length; + } + +private: + float m_valueInSpecifiedUnits { 0 }; + unsigned m_unit; +}; + +template<> struct SVGPropertyTraits<SVGLengthValue> { + static SVGLengthValue initialValue() { return { }; } + static String toString(const SVGLengthValue& type) { return type.valueAsString(); } +}; + +TextStream& operator<<(TextStream&, const SVGLengthValue&); + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGLineElement.cpp b/Source/WebCore/svg/SVGLineElement.cpp index 00d07e5c7..526d7b018 100644 --- a/Source/WebCore/svg/SVGLineElement.cpp +++ b/Source/WebCore/svg/SVGLineElement.cpp @@ -19,17 +19,14 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGLineElement.h" -#include "Attribute.h" #include "FloatPoint.h" #include "RenderSVGPath.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" -#include "SVGLength.h" +#include "SVGLengthValue.h" #include "SVGNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -60,45 +57,42 @@ inline SVGLineElement::SVGLineElement(const QualifiedName& tagName, Document& do registerAnimatedPropertiesForSVGLineElement(); } -PassRefPtr<SVGLineElement> SVGLineElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGLineElement> SVGLineElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGLineElement(tagName, document)); + return adoptRef(*new SVGLineElement(tagName, document)); } bool SVGLineElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::x1Attr); - supportedAttributes.add(SVGNames::x2Attr); - supportedAttributes.add(SVGNames::y1Attr); - supportedAttributes.add(SVGNames::y2Attr); + supportedAttributes.get().add(SVGNames::x1Attr); + supportedAttributes.get().add(SVGNames::x2Attr); + supportedAttributes.get().add(SVGNames::y1Attr); + supportedAttributes.get().add(SVGNames::y2Attr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGLineElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::x1Attr) - setX1BaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::x1Attr) + setX1BaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::y1Attr) - setY1BaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setY1BaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::x2Attr) - setX2BaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setX2BaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::y2Attr) - setY2BaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setY2BaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) @@ -108,7 +102,7 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); bool isLengthAttribute = attrName == SVGNames::x1Attr || attrName == SVGNames::y1Attr @@ -118,7 +112,7 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) if (isLengthAttribute) updateRelativeLengthsInformation(); - RenderSVGShape* renderer = toRenderSVGShape(this->renderer()); + auto* renderer = downcast<RenderSVGShape>(this->renderer()); if (!renderer) return; @@ -145,5 +139,3 @@ bool SVGLineElement::selfHasRelativeLengths() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGLineElement.h b/Source/WebCore/svg/SVGLineElement.h index e4b252f63..e12ff18ec 100644 --- a/Source/WebCore/svg/SVGLineElement.h +++ b/Source/WebCore/svg/SVGLineElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGLineElement_h -#define SVGLineElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGExternalResourcesRequired.h" @@ -32,34 +30,28 @@ namespace WebCore { class SVGLineElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGLineElement> create(const QualifiedName&, Document&); + static Ref<SVGLineElement> create(const QualifiedName&, Document&); private: SVGLineElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool supportsMarkers() const override { return true; } + bool supportsMarkers() const final { return true; } - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGLineElement) DECLARE_ANIMATED_LENGTH(X1, x1) DECLARE_ANIMATED_LENGTH(Y1, y1) DECLARE_ANIMATED_LENGTH(X2, x2) DECLARE_ANIMATED_LENGTH(Y2, y2) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGLineElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGLineElement.idl b/Source/WebCore/svg/SVGLineElement.idl index 7c17db2a8..6c8de66ec 100644 --- a/Source/WebCore/svg/SVGLineElement.idl +++ b/Source/WebCore/svg/SVGLineElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGLineElement : SVGGraphicsElement { +interface SVGLineElement : SVGGraphicsElement { readonly attribute SVGAnimatedLength x1; readonly attribute SVGAnimatedLength y1; readonly attribute SVGAnimatedLength x2; diff --git a/Source/WebCore/svg/SVGLinearGradientElement.cpp b/Source/WebCore/svg/SVGLinearGradientElement.cpp index 78b024f0e..948c6c3d7 100644 --- a/Source/WebCore/svg/SVGLinearGradientElement.cpp +++ b/Source/WebCore/svg/SVGLinearGradientElement.cpp @@ -22,21 +22,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGLinearGradientElement.h" -#include "Attribute.h" #include "Document.h" #include "FloatPoint.h" #include "LinearGradientAttributes.h" #include "RenderSVGResourceLinearGradient.h" -#include "SVGElementInstance.h" -#include "SVGLength.h" +#include "SVGLengthValue.h" #include "SVGNames.h" -#include "SVGTransform.h" -#include "SVGTransformList.h" #include "SVGUnitTypes.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -66,41 +61,39 @@ inline SVGLinearGradientElement::SVGLinearGradientElement(const QualifiedName& t registerAnimatedPropertiesForSVGLinearGradientElement(); } -PassRefPtr<SVGLinearGradientElement> SVGLinearGradientElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGLinearGradientElement> SVGLinearGradientElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGLinearGradientElement(tagName, document)); + return adoptRef(*new SVGLinearGradientElement(tagName, document)); } bool SVGLinearGradientElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::x1Attr); - supportedAttributes.add(SVGNames::x2Attr); - supportedAttributes.add(SVGNames::y1Attr); - supportedAttributes.add(SVGNames::y2Attr); + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { + supportedAttributes.get().add(SVGNames::x1Attr); + supportedAttributes.get().add(SVGNames::x2Attr); + supportedAttributes.get().add(SVGNames::y1Attr); + supportedAttributes.get().add(SVGNames::y2Attr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGLinearGradientElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGradientElement::parseAttribute(name, value); - else if (name == SVGNames::x1Attr) - setX1BaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::x1Attr) + setX1BaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::y1Attr) - setY1BaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setY1BaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::x2Attr) - setX2BaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setX2BaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::y2Attr) - setY2BaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else - ASSERT_NOT_REACHED(); + setY2BaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); reportAttributeParsingError(parseError, name, value); + + SVGGradientElement::parseAttribute(name, value); } void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName) @@ -110,7 +103,7 @@ void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); updateRelativeLengthsInformation(); @@ -118,9 +111,9 @@ void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName object->setNeedsLayout(); } -RenderPtr<RenderElement> SVGLinearGradientElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGLinearGradientElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceLinearGradient>(*this, std::move(style)); + return createRenderer<RenderSVGResourceLinearGradient>(*this, WTFMove(style)); } static void setGradientAttributes(SVGGradientElement& element, LinearGradientAttributes& attributes, bool isLinear = true) @@ -144,19 +137,19 @@ static void setGradientAttributes(SVGGradientElement& element, LinearGradientAtt } if (isLinear) { - SVGLinearGradientElement* linear = toSVGLinearGradientElement(&element); + SVGLinearGradientElement& linear = downcast<SVGLinearGradientElement>(element); if (!attributes.hasX1() && element.hasAttribute(SVGNames::x1Attr)) - attributes.setX1(linear->x1()); + attributes.setX1(linear.x1()); if (!attributes.hasY1() && element.hasAttribute(SVGNames::y1Attr)) - attributes.setY1(linear->y1()); + attributes.setY1(linear.y1()); if (!attributes.hasX2() && element.hasAttribute(SVGNames::x2Attr)) - attributes.setX2(linear->x2()); + attributes.setX2(linear.x2()); if (!attributes.hasY2() && element.hasAttribute(SVGNames::y2Attr)) - attributes.setY2(linear->y2()); + attributes.setY2(linear.y2()); } } @@ -174,8 +167,8 @@ bool SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttribute while (true) { // Respect xlink:href, take attributes from referenced element Node* refNode = SVGURIReference::targetElementFromIRIString(current->href(), document()); - if (refNode && isSVGGradientElement(*refNode)) { - current = toSVGGradientElement(refNode); + if (is<SVGGradientElement>(refNode)) { + current = downcast<SVGGradientElement>(refNode); // Cycle detection if (processedGradients.contains(current)) @@ -203,5 +196,3 @@ bool SVGLinearGradientElement::selfHasRelativeLengths() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGLinearGradientElement.h b/Source/WebCore/svg/SVGLinearGradientElement.h index 4b1bb6f9b..ef3dec084 100644 --- a/Source/WebCore/svg/SVGLinearGradientElement.h +++ b/Source/WebCore/svg/SVGLinearGradientElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGLinearGradientElement_h -#define SVGLinearGradientElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedLength.h" #include "SVGGradientElement.h" #include "SVGNames.h" @@ -32,20 +30,20 @@ struct LinearGradientAttributes; class SVGLinearGradientElement final : public SVGGradientElement { public: - static PassRefPtr<SVGLinearGradientElement> create(const QualifiedName&, Document&); + static Ref<SVGLinearGradientElement> create(const QualifiedName&, Document&); bool collectGradientAttributes(LinearGradientAttributes&); private: SVGLinearGradientElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGLinearGradientElement) DECLARE_ANIMATED_LENGTH(X1, x1) @@ -55,9 +53,4 @@ private: END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGLinearGradientElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGLinearGradientElement.idl b/Source/WebCore/svg/SVGLinearGradientElement.idl index 4aa3435eb..0d8964a1f 100644 --- a/Source/WebCore/svg/SVGLinearGradientElement.idl +++ b/Source/WebCore/svg/SVGLinearGradientElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGLinearGradientElement : SVGGradientElement { +interface SVGLinearGradientElement : SVGGradientElement { readonly attribute SVGAnimatedLength x1; readonly attribute SVGAnimatedLength y1; readonly attribute SVGAnimatedLength x2; diff --git a/Source/WebCore/svg/SVGLocatable.cpp b/Source/WebCore/svg/SVGLocatable.cpp index cad52c884..b7fab2d32 100644 --- a/Source/WebCore/svg/SVGLocatable.cpp +++ b/Source/WebCore/svg/SVGLocatable.cpp @@ -21,14 +21,13 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGLocatable.h" #include "RenderElement.h" #include "SVGException.h" #include "SVGGraphicsElement.h" #include "SVGImageElement.h" +#include "SVGMatrix.h" #include "SVGNames.h" namespace WebCore { @@ -38,7 +37,7 @@ static bool isViewportElement(Node* node) return (node->hasTagName(SVGNames::svgTag) || node->hasTagName(SVGNames::symbolTag) || node->hasTagName(SVGNames::foreignObjectTag) - || isSVGImageElement(node)); + || is<SVGImageElement>(*node)); } SVGElement* SVGLocatable::nearestViewportElement(const SVGElement* element) @@ -46,19 +45,19 @@ SVGElement* SVGLocatable::nearestViewportElement(const SVGElement* element) ASSERT(element); for (Element* current = element->parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) { if (isViewportElement(current)) - return toSVGElement(current); + return downcast<SVGElement>(current); } - return 0; + return nullptr; } SVGElement* SVGLocatable::farthestViewportElement(const SVGElement* element) { ASSERT(element); - SVGElement* farthest = 0; + SVGElement* farthest = nullptr; for (Element* current = element->parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) { if (isViewportElement(current)) - farthest = toSVGElement(current); + farthest = downcast<SVGElement>(current); } return farthest; } @@ -84,12 +83,12 @@ AffineTransform SVGLocatable::computeCTM(SVGElement* element, CTMScope mode, Sty AffineTransform ctm; - SVGElement* stopAtElement = mode == NearestViewportScope ? nearestViewportElement(element) : 0; + SVGElement* stopAtElement = mode == NearestViewportScope ? nearestViewportElement(element) : nullptr; for (Element* currentElement = element; currentElement; currentElement = currentElement->parentOrShadowHostElement()) { if (!currentElement->isSVGElement()) break; - ctm = toSVGElement(currentElement)->localCoordinateSpaceTransform(mode).multiply(ctm); + ctm = downcast<SVGElement>(*currentElement).localCoordinateSpaceTransform(mode).multiply(ctm); // For getCTM() computation, stop at the nearest viewport element if (currentElement == stopAtElement) @@ -99,22 +98,19 @@ AffineTransform SVGLocatable::computeCTM(SVGElement* element, CTMScope mode, Sty return ctm; } -AffineTransform SVGLocatable::getTransformToElement(SVGElement* target, ExceptionCode& ec, StyleUpdateStrategy styleUpdateStrategy) +ExceptionOr<Ref<SVGMatrix>> SVGLocatable::getTransformToElement(SVGElement* target, StyleUpdateStrategy styleUpdateStrategy) { AffineTransform ctm = getCTM(styleUpdateStrategy); - if (target && target->isSVGGraphicsElement()) { - AffineTransform targetCTM = toSVGGraphicsElement(target)->getCTM(styleUpdateStrategy); - if (!targetCTM.isInvertible()) { - ec = SVGException::SVG_MATRIX_NOT_INVERTABLE; - return ctm; - } - ctm = targetCTM.inverse() * ctm; + if (is<SVGGraphicsElement>(target)) { + AffineTransform targetCTM = downcast<SVGGraphicsElement>(*target).getCTM(styleUpdateStrategy); + if (auto inverse = targetCTM.inverse()) + ctm = inverse.value() * ctm; + else + return Exception { SVGException::SVG_MATRIX_NOT_INVERTABLE }; } - return ctm; + return SVGMatrix::create(ctm); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGLocatable.h b/Source/WebCore/svg/SVGLocatable.h index 334343af1..acbe7e848 100644 --- a/Source/WebCore/svg/SVGLocatable.h +++ b/Source/WebCore/svg/SVGLocatable.h @@ -19,18 +19,16 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGLocatable_h -#define SVGLocatable_h +#pragma once -#if ENABLE(SVG) #include "AffineTransform.h" +#include "ExceptionOr.h" namespace WebCore { class FloatRect; class SVGElement; - -typedef int ExceptionCode; +class SVGMatrix; class SVGLocatable { public: @@ -45,7 +43,8 @@ public: virtual FloatRect getBBox(StyleUpdateStrategy) = 0; virtual AffineTransform getCTM(StyleUpdateStrategy) = 0; virtual AffineTransform getScreenCTM(StyleUpdateStrategy) = 0; - AffineTransform getTransformToElement(SVGElement*, ExceptionCode&, StyleUpdateStrategy = AllowStyleUpdate); + + ExceptionOr<Ref<SVGMatrix>> getTransformToElement(SVGElement*, StyleUpdateStrategy = AllowStyleUpdate); static SVGElement* nearestViewportElement(const SVGElement*); static SVGElement* farthestViewportElement(const SVGElement*); @@ -63,6 +62,3 @@ protected: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGLocatable_h diff --git a/Source/WebCore/svg/SVGMPathElement.cpp b/Source/WebCore/svg/SVGMPathElement.cpp index e5d1c226f..ff7d4872d 100644 --- a/Source/WebCore/svg/SVGMPathElement.cpp +++ b/Source/WebCore/svg/SVGMPathElement.cpp @@ -18,8 +18,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGMPathElement.h" #include "Document.h" @@ -47,9 +45,9 @@ inline SVGMPathElement::SVGMPathElement(const QualifiedName& tagName, Document& registerAnimatedPropertiesForSVGMPathElement(); } -PassRefPtr<SVGMPathElement> SVGMPathElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGMPathElement> SVGMPathElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGMPathElement(tagName, document)); + return adoptRef(*new SVGMPathElement(tagName, document)); } SVGMPathElement::~SVGMPathElement() @@ -60,24 +58,24 @@ SVGMPathElement::~SVGMPathElement() void SVGMPathElement::buildPendingResource() { clearResourceReferences(); - if (!inDocument()) + if (!isConnected()) return; String id; Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id); if (!target) { // Do not register as pending if we are already pending this resource. - if (document().accessSVGExtensions()->isPendingResource(this, id)) + if (document().accessSVGExtensions().isPendingResource(this, id)) return; if (!id.isEmpty()) { - document().accessSVGExtensions()->addPendingResource(id, this); + document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); } } else if (target->isSVGElement()) { // Register us with the target in the dependencies map. Any change of hrefElement // that leads to relayout/repainting now informs us, so we can react to it. - document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target)); + document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target)); } targetPathChanged(); @@ -85,76 +83,54 @@ void SVGMPathElement::buildPendingResource() void SVGMPathElement::clearResourceReferences() { - document().accessSVGExtensions()->removeAllTargetReferencesForElement(this); + document().accessSVGExtensions().removeAllTargetReferencesForElement(this); } Node::InsertionNotificationRequest SVGMPathElement::insertedInto(ContainerNode& rootParent) { SVGElement::insertedInto(rootParent); - if (rootParent.inDocument()) - buildPendingResource(); + if (rootParent.isConnected()) + return InsertionShouldCallFinishedInsertingSubtree; return InsertionDone; } +void SVGMPathElement::finishedInsertingSubtree() +{ + buildPendingResource(); +} + void SVGMPathElement::removedFrom(ContainerNode& rootParent) { SVGElement::removedFrom(rootParent); notifyParentOfPathChange(&rootParent); - if (rootParent.inDocument()) + if (rootParent.isConnected()) clearResourceReferences(); } -bool SVGMPathElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGURIReference::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGMPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - - if (SVGURIReference::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGMPathElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (SVGURIReference::isKnownAttribute(attrName)) { + InstanceInvalidationGuard guard(*this); buildPendingResource(); return; } - if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) - return; - - ASSERT_NOT_REACHED(); + SVGElement::svgAttributeChanged(attrName); } SVGPathElement* SVGMPathElement::pathElement() { Element* target = targetElementFromIRIString(href(), document()); - if (target && target->hasTagName(SVGNames::pathTag)) - return toSVGPathElement(target); - return 0; + if (is<SVGPathElement>(target)) + return downcast<SVGPathElement>(target); + return nullptr; } void SVGMPathElement::targetPathChanged() @@ -164,10 +140,8 @@ void SVGMPathElement::targetPathChanged() void SVGMPathElement::notifyParentOfPathChange(ContainerNode* parent) { - if (parent && isSVGAnimateMotionElement(parent)) - toSVGAnimateMotionElement(parent)->updateAnimationPath(); + if (is<SVGAnimateMotionElement>(parent)) + downcast<SVGAnimateMotionElement>(*parent).updateAnimationPath(); } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGMPathElement.h b/Source/WebCore/svg/SVGMPathElement.h index aa392fcbe..246973c79 100644 --- a/Source/WebCore/svg/SVGMPathElement.h +++ b/Source/WebCore/svg/SVGMPathElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGMPathElement_h -#define SVGMPathElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedString.h" #include "SVGElement.h" @@ -32,11 +30,9 @@ namespace WebCore { class SVGPathElement; -class SVGMPathElement final : public SVGElement, - public SVGURIReference, - public SVGExternalResourcesRequired { +class SVGMPathElement final : public SVGElement, public SVGURIReference, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGMPathElement> create(const QualifiedName&, Document&); + static Ref<SVGMPathElement> create(const QualifiedName&, Document&); virtual ~SVGMPathElement(); @@ -47,28 +43,23 @@ public: private: SVGMPathElement(const QualifiedName&, Document&); - void buildPendingResource() override; + void buildPendingResource() final; void clearResourceReferences(); - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + InsertionNotificationRequest insertedInto(ContainerNode&) final; + void removedFrom(ContainerNode&) final; - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } + void finishedInsertingSubtree() final; void notifyParentOfPathChange(ContainerNode*); BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMPathElement) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGMPathElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGMPathElement_h diff --git a/Source/WebCore/svg/SVGMPathElement.idl b/Source/WebCore/svg/SVGMPathElement.idl index eb3f4c093..c5d58b654 100644 --- a/Source/WebCore/svg/SVGMPathElement.idl +++ b/Source/WebCore/svg/SVGMPathElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGMPathElement : SVGElement { +interface SVGMPathElement : SVGElement { }; SVGMPathElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGMarkerElement.cpp b/Source/WebCore/svg/SVGMarkerElement.cpp index 40b1288b0..9fc4a7ffb 100644 --- a/Source/WebCore/svg/SVGMarkerElement.cpp +++ b/Source/WebCore/svg/SVGMarkerElement.cpp @@ -20,16 +20,12 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGMarkerElement.h" -#include "Attribute.h" #include "RenderSVGResourceMarker.h" -#include "SVGElementInstance.h" #include "SVGFitToViewBox.h" #include "SVGNames.h" -#include "SVGSVGElement.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -87,20 +83,20 @@ inline SVGMarkerElement::SVGMarkerElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGMarkerElement(); } -PassRefPtr<SVGMarkerElement> SVGMarkerElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGMarkerElement> SVGMarkerElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGMarkerElement(tagName, document)); + return adoptRef(*new SVGMarkerElement(tagName, document)); } const AtomicString& SVGMarkerElement::orientTypeIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientType", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGOrientType", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGMarkerElement::orientAngleIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientAngle", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGOrientAngle", AtomicString::ConstructFromLiteral); return s_identifier; } @@ -111,53 +107,56 @@ AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float bool SVGMarkerElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); SVGFitToViewBox::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::markerUnitsAttr); - supportedAttributes.add(SVGNames::refXAttr); - supportedAttributes.add(SVGNames::refYAttr); - supportedAttributes.add(SVGNames::markerWidthAttr); - supportedAttributes.add(SVGNames::markerHeightAttr); - supportedAttributes.add(SVGNames::orientAttr); + supportedAttributes.get().add(SVGNames::markerUnitsAttr); + supportedAttributes.get().add(SVGNames::refXAttr); + supportedAttributes.get().add(SVGNames::refYAttr); + supportedAttributes.get().add(SVGNames::markerWidthAttr); + supportedAttributes.get().add(SVGNames::markerHeightAttr); + supportedAttributes.get().add(SVGNames::orientAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - SVGParsingError parseError = NoError; - - if (!isSupportedAttribute(name)) - SVGElement::parseAttribute(name, value); - else if (name == SVGNames::markerUnitsAttr) { - SVGMarkerUnitsType propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value); + if (name == SVGNames::markerUnitsAttr) { + auto propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value); if (propertyValue > 0) setMarkerUnitsBaseValue(propertyValue); - } else if (name == SVGNames::refXAttr) - setRefXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); - else if (name == SVGNames::refYAttr) - setRefYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (name == SVGNames::markerWidthAttr) - setMarkerWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); - else if (name == SVGNames::markerHeightAttr) - setMarkerHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (name == SVGNames::orientAttr) { - SVGAngle angle; - SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle); + return; + } + + if (name == SVGNames::orientAttr) { + SVGAngleValue angle; + auto orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle); if (orientType > 0) setOrientTypeBaseValue(orientType); if (orientType == SVGMarkerOrientAngle) setOrientAngleBaseValue(angle); - } else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value) - || SVGFitToViewBox::parseAttribute(this, name, value)) { - } else - ASSERT_NOT_REACHED(); + return; + } + + SVGParsingError parseError = NoError; + + if (name == SVGNames::refXAttr) + setRefXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); + else if (name == SVGNames::refYAttr) + setRefYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); + else if (name == SVGNames::markerWidthAttr) + setMarkerWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); + else if (name == SVGNames::markerHeightAttr) + setMarkerHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); reportAttributeParsingError(parseError, name, value); + + SVGElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGFitToViewBox::parseAttribute(this, name, value); } void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) @@ -167,7 +166,7 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (attrName == SVGNames::refXAttr || attrName == SVGNames::refYAttr @@ -190,11 +189,11 @@ void SVGMarkerElement::childrenChanged(const ChildChange& change) object->setNeedsLayout(); } -void SVGMarkerElement::setOrientToAuto() +void SVGMarkerElement::setOrient(SVGMarkerOrientType orientType, const SVGAngleValue& angle) { - setOrientTypeBaseValue(SVGMarkerOrientAuto); - setOrientAngleBaseValue(SVGAngle()); - + setOrientTypeBaseValue(orientType); + setOrientAngleBaseValue(angle); + // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization. m_orientAngle.shouldSynchronize = true; m_orientType.shouldSynchronize = true; @@ -202,21 +201,19 @@ void SVGMarkerElement::setOrientToAuto() svgAttributeChanged(orientAnglePropertyInfo()->attributeName); } -void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle) +void SVGMarkerElement::setOrientToAuto() { - setOrientTypeBaseValue(SVGMarkerOrientAngle); - setOrientAngleBaseValue(angle); + setOrient(SVGMarkerOrientAuto, { }); +} - // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization. - m_orientAngle.shouldSynchronize = true; - m_orientType.shouldSynchronize = true; - invalidateSVGAttributes(); - svgAttributeChanged(orientAnglePropertyInfo()->attributeName); +void SVGMarkerElement::setOrientToAngle(SVGAngle& angle) +{ + setOrient(SVGMarkerOrientAngle, angle.propertyReference()); } -RenderPtr<RenderElement> SVGMarkerElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGMarkerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceMarker>(*this, std::move(style)); + return createRenderer<RenderSVGResourceMarker>(*this, WTFMove(style)); } bool SVGMarkerElement::selfHasRelativeLengths() const @@ -230,32 +227,46 @@ bool SVGMarkerElement::selfHasRelativeLengths() const void SVGMarkerElement::synchronizeOrientType(SVGElement* contextElement) { ASSERT(contextElement); - SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement); - if (!ownerType->m_orientType.shouldSynchronize) + SVGMarkerElement& ownerType = downcast<SVGMarkerElement>(*contextElement); + if (!ownerType.m_orientType.shouldSynchronize) return; - // If orient is not auto, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle. - if (ownerType->m_orientType.value != SVGMarkerOrientAuto) + static NeverDestroyed<AtomicString> autoString("auto", AtomicString::ConstructFromLiteral); + static NeverDestroyed<AtomicString> autoStartReverseString("auto-start-reverse", AtomicString::ConstructFromLiteral); + + // If orient is not auto or auto-start-reverse, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle. + if (ownerType.m_orientType.value == SVGMarkerOrientAuto) { + ownerType.m_orientType.synchronize(&ownerType, orientTypePropertyInfo()->attributeName, autoString); return; + } - DEFINE_STATIC_LOCAL(AtomicString, autoString, ("auto", AtomicString::ConstructFromLiteral)); - ownerType->m_orientType.synchronize(ownerType, orientTypePropertyInfo()->attributeName, autoString); + if (ownerType.m_orientType.value == SVGMarkerOrientAutoStartReverse) + ownerType.m_orientType.synchronize(&ownerType, orientTypePropertyInfo()->attributeName, autoStartReverseString); } -PassRefPtr<SVGAnimatedProperty> SVGMarkerElement::lookupOrCreateOrientTypeWrapper(SVGElement* contextElement) +Ref<SVGAnimatedProperty> SVGMarkerElement::lookupOrCreateOrientTypeWrapper(SVGElement* contextElement) { ASSERT(contextElement); - SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement); + SVGMarkerElement& ownerType = downcast<SVGMarkerElement>(*contextElement); return SVGAnimatedProperty::lookupOrCreateWrapper<SVGMarkerElement, SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>, SVGMarkerOrientType> - (ownerType, orientTypePropertyInfo(), ownerType->m_orientType.value); + (&ownerType, orientTypePropertyInfo(), ownerType.m_orientType.value); } - -PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>> SVGMarkerElement::orientTypeAnimated() + +SVGMarkerOrientType& SVGMarkerElement::orientType() const { - m_orientType.shouldSynchronize = true; - return static_pointer_cast<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>>(lookupOrCreateOrientTypeWrapper(this)); + if (auto wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, SVGAnimatedEnumeration>(this, orientTypePropertyInfo())) { + if (wrapper->isAnimating()) { + ASSERT(wrapper->currentAnimatedValue() < SVGMarkerOrientMax); + return reinterpret_cast<SVGMarkerOrientType&>(wrapper->currentAnimatedValue()); + } + } + return m_orientType.value; } +Ref<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>> SVGMarkerElement::orientTypeAnimated() +{ + m_orientType.shouldSynchronize = true; + return static_reference_cast<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>>(lookupOrCreateOrientTypeWrapper(this)); } -#endif +} diff --git a/Source/WebCore/svg/SVGMarkerElement.h b/Source/WebCore/svg/SVGMarkerElement.h index ecf563ee0..c757d1d92 100644 --- a/Source/WebCore/svg/SVGMarkerElement.h +++ b/Source/WebCore/svg/SVGMarkerElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGMarkerElement_h -#define SVGMarkerElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedAngle.h" #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" @@ -43,7 +41,11 @@ enum SVGMarkerUnitsType { enum SVGMarkerOrientType { SVGMarkerOrientUnknown = 0, SVGMarkerOrientAuto, - SVGMarkerOrientAngle + SVGMarkerOrientAngle, + SVGMarkerOrientAutoStartReverse, + + // Add new elements before here. + SVGMarkerOrientMax }; template<> @@ -56,9 +58,9 @@ struct SVGPropertyTraits<SVGMarkerUnitsType> { case SVGMarkerUnitsUnknown: return emptyString(); case SVGMarkerUnitsUserSpaceOnUse: - return "userSpaceOnUse"; + return ASCIILiteral("userSpaceOnUse"); case SVGMarkerUnitsStrokeWidth: - return "strokeWidth"; + return ASCIILiteral("strokeWidth"); } ASSERT_NOT_REACHED(); @@ -76,21 +78,23 @@ struct SVGPropertyTraits<SVGMarkerUnitsType> { }; template<> -struct SVGPropertyTraits<SVGMarkerOrientType> { - static unsigned highestEnumValue() { return SVGMarkerOrientAngle; } +inline unsigned SVGIDLEnumLimits<SVGMarkerOrientType>::highestExposedEnumValue() { return SVGMarkerOrientAngle; } + +template<> struct SVGPropertyTraits<SVGMarkerOrientType> { + static unsigned highestEnumValue() { return SVGMarkerOrientAutoStartReverse; } // toString is not needed, synchronizeOrientType() handles this on its own. - static SVGMarkerOrientType fromString(const String& value, SVGAngle& angle) + static SVGMarkerOrientType fromString(const String& value, SVGAngleValue& angle) { if (value == "auto") return SVGMarkerOrientAuto; - - ExceptionCode ec = 0; - angle.setValueAsString(value, ec); - if (!ec) - return SVGMarkerOrientAngle; - return SVGMarkerOrientUnknown; + if (value == "auto-start-reverse") + return SVGMarkerOrientAutoStartReverse; + auto setValueResult = angle.setValueAsString(value); + if (setValueResult.hasException()) + return SVGMarkerOrientUnknown; + return SVGMarkerOrientAngle; } }; @@ -108,32 +112,35 @@ public: enum { SVG_MARKER_ORIENT_UNKNOWN = SVGMarkerOrientUnknown, SVG_MARKER_ORIENT_AUTO = SVGMarkerOrientAuto, - SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle + SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle, + SVG_MARKER_ORIENT_AUTOSTARTREVERSE = SVGMarkerOrientAutoStartReverse }; - static PassRefPtr<SVGMarkerElement> create(const QualifiedName&, Document&); + static Ref<SVGMarkerElement> create(const QualifiedName&, Document&); AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const; void setOrientToAuto(); - void setOrientToAngle(const SVGAngle&); + void setOrientToAngle(SVGAngle&); static const SVGPropertyInfo* orientTypePropertyInfo(); private: SVGMarkerElement(const QualifiedName&, Document&); - virtual bool needsPendingResourceHandling() const override { return false; } + bool needsPendingResourceHandling() const override { return false; } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void childrenChanged(const ChildChange&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + void childrenChanged(const ChildChange&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool rendererIsNeeded(const RenderStyle&) override { return true; } + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool rendererIsNeeded(const RenderStyle&) override { return true; } - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const override; + + void setOrient(SVGMarkerOrientType, const SVGAngleValue&); void synchronizeOrientType(); @@ -147,7 +154,7 @@ private: DECLARE_ANIMATED_LENGTH(MarkerHeight, markerHeight) DECLARE_ANIMATED_ENUMERATION(MarkerUnits, markerUnits, SVGMarkerUnitsType) DECLARE_ANIMATED_ANGLE(OrientAngle, orientAngle) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) DECLARE_ANIMATED_RECT(ViewBox, viewBox) DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) END_DECLARE_ANIMATED_PROPERTIES @@ -155,19 +162,14 @@ private: public: // Custom 'orientType' property. static void synchronizeOrientType(SVGElement* contextElement); - static PassRefPtr<SVGAnimatedProperty> lookupOrCreateOrientTypeWrapper(SVGElement* contextElement); - SVGMarkerOrientType& orientType() const { return m_orientType.value; } + static Ref<SVGAnimatedProperty> lookupOrCreateOrientTypeWrapper(SVGElement* contextElement); + SVGMarkerOrientType& orientType() const; SVGMarkerOrientType& orientTypeBaseValue() const { return m_orientType.value; } void setOrientTypeBaseValue(const SVGMarkerOrientType& type) { m_orientType.value = type; } - PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>> orientTypeAnimated(); + Ref<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>> orientTypeAnimated(); private: mutable SVGSynchronizableAnimatedProperty<SVGMarkerOrientType> m_orientType; }; -NODE_TYPE_CASTS(SVGMarkerElement) - -} - -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGMarkerElement.idl b/Source/WebCore/svg/SVGMarkerElement.idl index 1773a1fb6..edd8de54d 100644 --- a/Source/WebCore/svg/SVGMarkerElement.idl +++ b/Source/WebCore/svg/SVGMarkerElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGMarkerElement : SVGElement { +interface SVGMarkerElement : SVGElement { // Marker Unit Types const unsigned short SVG_MARKERUNITS_UNKNOWN = 0; const unsigned short SVG_MARKERUNITS_USERSPACEONUSE = 1; @@ -45,7 +43,7 @@ readonly attribute SVGAnimatedAngle orientAngle; void setOrientToAuto(); - void setOrientToAngle([Default=Undefined] optional SVGAngle angle); + void setOrientToAngle(SVGAngle angle); }; SVGMarkerElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGMaskElement.cpp b/Source/WebCore/svg/SVGMaskElement.cpp index 42ed45ff5..f7a4180df 100644 --- a/Source/WebCore/svg/SVGMaskElement.cpp +++ b/Source/WebCore/svg/SVGMaskElement.cpp @@ -4,6 +4,7 @@ * Copyright (C) 2005 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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,17 +23,15 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGMaskElement.h" -#include "Attribute.h" #include "RenderSVGResourceMasker.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGRenderSupport.h" +#include "SVGStringList.h" #include "SVGUnitTypes.h" #include "StyleResolver.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -72,59 +71,59 @@ inline SVGMaskElement::SVGMaskElement(const QualifiedName& tagName, Document& do registerAnimatedPropertiesForSVGMaskElement(); } -PassRefPtr<SVGMaskElement> SVGMaskElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGMaskElement> SVGMaskElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGMaskElement(tagName, document)); + return adoptRef(*new SVGMaskElement(tagName, document)); } bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGTests::addSupportedAttributes(supportedAttributes); SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::maskUnitsAttr); - supportedAttributes.add(SVGNames::maskContentUnitsAttr); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); + supportedAttributes.get().add(SVGNames::maskUnitsAttr); + supportedAttributes.get().add(SVGNames::maskContentUnitsAttr); + supportedAttributes.get().add(SVGNames::xAttr); + supportedAttributes.get().add(SVGNames::yAttr); + supportedAttributes.get().add(SVGNames::widthAttr); + supportedAttributes.get().add(SVGNames::heightAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - SVGParsingError parseError = NoError; - - if (!isSupportedAttribute(name)) - SVGElement::parseAttribute(name, value); - else if (name == SVGNames::maskUnitsAttr) { - SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); + if (name == SVGNames::maskUnitsAttr) { + auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); if (propertyValue > 0) setMaskUnitsBaseValue(propertyValue); return; - } else if (name == SVGNames::maskContentUnitsAttr) { - SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); + } + if (name == SVGNames::maskContentUnitsAttr) { + auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); if (propertyValue > 0) setMaskContentUnitsBaseValue(propertyValue); return; - } else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + } + + SVGParsingError parseError = NoError; + + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (SVGTests::parseAttribute(name, value) - || SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); reportAttributeParsingError(parseError, name, value); + + SVGElement::parseAttribute(name, value); + SVGTests::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName) @@ -134,13 +133,15 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - + InstanceInvalidationGuard guard(*this); + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr - || attrName == SVGNames::heightAttr) - updateRelativeLengthsInformation(); + || attrName == SVGNames::heightAttr) { + invalidateSVGPresentationAttributeStyle(); + return; + } if (RenderObject* object = renderer()) object->setNeedsLayout(); @@ -157,19 +158,24 @@ void SVGMaskElement::childrenChanged(const ChildChange& change) object->setNeedsLayout(); } -RenderPtr<RenderElement> SVGMaskElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGMaskElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceMasker>(*this, std::move(style)); + return createRenderer<RenderSVGResourceMasker>(*this, WTFMove(style)); } -bool SVGMaskElement::selfHasRelativeLengths() const +Ref<SVGStringList> SVGMaskElement::requiredFeatures() { - return x().isRelative() - || y().isRelative() - || width().isRelative() - || height().isRelative(); + return SVGTests::requiredFeatures(*this); } +Ref<SVGStringList> SVGMaskElement::requiredExtensions() +{ + return SVGTests::requiredExtensions(*this); } -#endif // ENABLE(SVG) +Ref<SVGStringList> SVGMaskElement::systemLanguage() +{ + return SVGTests::systemLanguage(*this); +} + +} diff --git a/Source/WebCore/svg/SVGMaskElement.h b/Source/WebCore/svg/SVGMaskElement.h index fc051841d..34f45b527 100644 --- a/Source/WebCore/svg/SVGMaskElement.h +++ b/Source/WebCore/svg/SVGMaskElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGMaskElement_h -#define SVGMaskElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedLength.h" @@ -32,26 +30,29 @@ namespace WebCore { -class SVGMaskElement final : public SVGElement, - public SVGTests, - public SVGExternalResourcesRequired { +class SVGMaskElement final : public SVGElement, public SVGTests, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGMaskElement> create(const QualifiedName&, Document&); + static Ref<SVGMaskElement> create(const QualifiedName&, Document&); + + // SVGTests + Ref<SVGStringList> requiredFeatures(); + Ref<SVGStringList> requiredExtensions(); + Ref<SVGStringList> systemLanguage(); private: SVGMaskElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool needsPendingResourceHandling() const override { return false; } + bool isValid() const final { return SVGTests::isValid(); } + bool needsPendingResourceHandling() const final { return false; } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void childrenChanged(const ChildChange&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; + void childrenChanged(const ChildChange&) final; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final { return true; } BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMaskElement) DECLARE_ANIMATED_ENUMERATION(MaskUnits, maskUnits, SVGUnitTypes::SVGUnitType) @@ -60,18 +61,13 @@ private: DECLARE_ANIMATED_LENGTH(Y, y) DECLARE_ANIMATED_LENGTH(Width, width) DECLARE_ANIMATED_LENGTH(Height, height) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES // SVGTests - virtual void synchronizeRequiredFeatures() override { SVGTests::synchronizeRequiredFeatures(this); } - virtual void synchronizeRequiredExtensions() override { SVGTests::synchronizeRequiredExtensions(this); } - virtual void synchronizeSystemLanguage() override { SVGTests::synchronizeSystemLanguage(this); } + void synchronizeRequiredFeatures() final { SVGTests::synchronizeRequiredFeatures(*this); } + void synchronizeRequiredExtensions() final { SVGTests::synchronizeRequiredExtensions(*this); } + void synchronizeSystemLanguage() final { SVGTests::synchronizeSystemLanguage(*this); } }; -NODE_TYPE_CASTS(SVGMaskElement) - -} - -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGMaskElement.idl b/Source/WebCore/svg/SVGMaskElement.idl index ba053f677..e5bb8c38b 100644 --- a/Source/WebCore/svg/SVGMaskElement.idl +++ b/Source/WebCore/svg/SVGMaskElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGMaskElement : SVGElement { +interface SVGMaskElement : SVGElement { readonly attribute SVGAnimatedEnumeration maskUnits; readonly attribute SVGAnimatedEnumeration maskContentUnits; diff --git a/Source/WebCore/svg/SVGMatrix.h b/Source/WebCore/svg/SVGMatrix.h index e48ae003e..14247331d 100644 --- a/Source/WebCore/svg/SVGMatrix.h +++ b/Source/WebCore/svg/SVGMatrix.h @@ -1,132 +1,296 @@ /* - * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGMatrix_h -#define SVGMatrix_h +#pragma once -#if ENABLE(SVG) -#include "AffineTransform.h" -#include "SVGException.h" +#include "ExceptionCode.h" +#include "SVGMatrixValue.h" +#include "SVGPropertyTearOff.h" namespace WebCore { -typedef int ExceptionCode; - -// Only used in the bindings. -class SVGMatrix : public AffineTransform { +class SVGMatrix : public SVGPropertyTearOff<SVGMatrixValue> { public: - SVGMatrix() { } - SVGMatrix(const AffineTransform& other) - : AffineTransform(other) + static Ref<SVGMatrix> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGMatrixValue& value) + { + return adoptRef(*new SVGMatrix(animatedProperty, role, value)); + } + + static Ref<SVGMatrix> create(const SVGMatrixValue& initialValue = { }) + { + return adoptRef(*new SVGMatrix(initialValue)); + } + + static Ref<SVGMatrix> create(const SVGMatrixValue* initialValue) + { + return adoptRef(*new SVGMatrix(initialValue)); + } + + template<typename T> static ExceptionOr<Ref<SVGMatrix>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } + + double a() + { + return propertyReference().a(); + } + + ExceptionOr<void> setA(double value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setA(value); + commitChange(); + + return { }; + } + + double b() { + return propertyReference().b(); } - SVGMatrix(double a, double b, double c, double d, double e, double f) - : AffineTransform(a, b, c, d, e, f) + ExceptionOr<void> setB(double value) { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setB(value); + commitChange(); + + return { }; } - SVGMatrix translate(double tx, double ty) + double c() { - AffineTransform copy = *this; - copy.translate(tx, ty); - return static_cast<SVGMatrix>(copy); + return propertyReference().c(); } - SVGMatrix scale(double s) + ExceptionOr<void> setC(double value) { - AffineTransform copy = *this; - copy.scale(s, s); - return static_cast<SVGMatrix>(copy); + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setC(value); + commitChange(); + + return { }; } - SVGMatrix scaleNonUniform(double sx, double sy) + double d() { - AffineTransform copy = *this; - copy.scale(sx, sy); - return static_cast<SVGMatrix>(copy); + return propertyReference().d(); } - SVGMatrix rotate(double d) + ExceptionOr<void> setD(double value) { - AffineTransform copy = *this; - copy.rotate(d); - return static_cast<SVGMatrix>(copy); + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setD(value); + commitChange(); + + return { }; } - SVGMatrix flipX() + double e() { - AffineTransform copy = *this; - copy.flipX(); - return static_cast<SVGMatrix>(copy); + return propertyReference().e(); } - SVGMatrix flipY() + ExceptionOr<void> setE(double value) { - AffineTransform copy = *this; - copy.flipY(); - return static_cast<SVGMatrix>(copy); + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setE(value); + commitChange(); + + return { }; } - SVGMatrix skewX(double angle) + double f() { - AffineTransform copy = *this; - copy.skewX(angle); - return static_cast<SVGMatrix>(copy); + return propertyReference().f(); } - SVGMatrix skewY(double angle) + ExceptionOr<void> setF(double value) { - AffineTransform copy = *this; - copy.skewY(angle); - return static_cast<SVGMatrix>(copy); + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setF(value); + commitChange(); + + return { }; } - SVGMatrix multiply(const SVGMatrix& other) + ExceptionOr<Ref<SVGMatrix>> multiply(SVGMatrix& secondMatrix) { - AffineTransform copy = *this; - copy *= static_cast<const AffineTransform&>(other); - return static_cast<SVGMatrix>(copy); + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().multiply(secondMatrix.propertyReference()); + commitChange(); + + return SVGMatrix::create(result); + } + + ExceptionOr<Ref<SVGMatrix>> inverse() + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().inverse(); + if (result.hasException()) + return result.releaseException(); + + commitChange(); + return SVGMatrix::create(result.releaseReturnValue()); } - SVGMatrix inverse(ExceptionCode& ec) const + ExceptionOr<Ref<SVGMatrix>> translate(float x, float y) { - AffineTransform transform = AffineTransform::inverse(); - if (!isInvertible()) - ec = SVGException::SVG_MATRIX_NOT_INVERTABLE; + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().translate(x, y); + commitChange(); - return transform; + return SVGMatrix::create(result); } - SVGMatrix rotateFromVector(double x, double y, ExceptionCode& ec) + ExceptionOr<Ref<SVGMatrix>> scale(float scaleFactor) { - if (!x || !y) - ec = SVGException::SVG_INVALID_VALUE_ERR; + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().scale(scaleFactor); + commitChange(); - AffineTransform copy = *this; - copy.rotateFromVector(x, y); - return static_cast<SVGMatrix>(copy); + return SVGMatrix::create(result); } + ExceptionOr<Ref<SVGMatrix>> scaleNonUniform(float scaleFactorX, float scaleFactorY) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().scaleNonUniform(scaleFactorX, scaleFactorY); + commitChange(); + + return SVGMatrix::create(result); + } + + ExceptionOr<Ref<SVGMatrix>> rotate(float angle) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().rotate(angle); + commitChange(); + + return SVGMatrix::create(result); + } + + ExceptionOr<Ref<SVGMatrix>> rotateFromVector(float x, float y) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().rotateFromVector(x, y); + if (result.hasException()) + return result.releaseException(); + + commitChange(); + return SVGMatrix::create(result.releaseReturnValue()); + } + + ExceptionOr<Ref<SVGMatrix>> flipX() + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().flipX(); + commitChange(); + + return SVGMatrix::create(result); + } + + ExceptionOr<Ref<SVGMatrix>> flipY() + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().flipY(); + commitChange(); + + return SVGMatrix::create(result); + } + + ExceptionOr<Ref<SVGMatrix>> skewX(float angle) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().skewX(angle); + commitChange(); + + return SVGMatrix::create(result); + } + + ExceptionOr<Ref<SVGMatrix>> skewY(float angle) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().skewY(angle); + commitChange(); + + return SVGMatrix::create(result); + } + +protected: + SVGMatrix(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGMatrixValue& value) + : SVGPropertyTearOff<SVGMatrixValue>(&animatedProperty, role, value) + { + } + + explicit SVGMatrix(const SVGMatrixValue& initialValue) + : SVGPropertyTearOff<SVGMatrixValue>(initialValue) + { + } + + explicit SVGMatrix(const SVGMatrixValue* initialValue) + : SVGPropertyTearOff<SVGMatrixValue>(initialValue) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGMatrix.idl b/Source/WebCore/svg/SVGMatrix.idl index 11045b5ce..0747eb622 100644 --- a/Source/WebCore/svg/SVGMatrix.idl +++ b/Source/WebCore/svg/SVGMatrix.idl @@ -21,27 +21,26 @@ */ [ - Conditional=SVG, + SkipVTableValidation ] interface SVGMatrix { // FIXME: these attributes should all be floats but since we implement // AffineTransform with doubles setting these as doubles makes more sense. - [StrictTypeChecking] attribute double a; - [StrictTypeChecking] attribute double b; - [StrictTypeChecking] attribute double c; - [StrictTypeChecking] attribute double d; - [StrictTypeChecking] attribute double e; - [StrictTypeChecking] attribute double f; + [SetterMayThrowException] attribute unrestricted double a; + [SetterMayThrowException] attribute unrestricted double b; + [SetterMayThrowException] attribute unrestricted double c; + [SetterMayThrowException] attribute unrestricted double d; + [SetterMayThrowException] attribute unrestricted double e; + [SetterMayThrowException] attribute unrestricted double f; - [StrictTypeChecking] SVGMatrix multiply(SVGMatrix secondMatrix); - [RaisesException] SVGMatrix inverse(); - [Immutable, StrictTypeChecking] SVGMatrix translate(float x, float y); - [Immutable, StrictTypeChecking] SVGMatrix scale(float scaleFactor); - [Immutable, StrictTypeChecking] SVGMatrix scaleNonUniform(float scaleFactorX, float scaleFactorY); - [Immutable, StrictTypeChecking] SVGMatrix rotate(float angle); - [StrictTypeChecking, RaisesException] SVGMatrix rotateFromVector(float x, float y); - [Immutable] SVGMatrix flipX(); - [Immutable] SVGMatrix flipY(); - [Immutable, StrictTypeChecking] SVGMatrix skewX(float angle); - [Immutable, StrictTypeChecking] SVGMatrix skewY(float angle); + [MayThrowException] SVGMatrix multiply(SVGMatrix secondMatrix); + [MayThrowException] SVGMatrix inverse(); + [MayThrowException] SVGMatrix translate(unrestricted float x, unrestricted float y); + [MayThrowException] SVGMatrix scale(unrestricted float scaleFactor); + [MayThrowException] SVGMatrix scaleNonUniform(unrestricted float scaleFactorX, unrestricted float scaleFactorY); + [MayThrowException] SVGMatrix rotate(unrestricted float angle); + [MayThrowException] SVGMatrix rotateFromVector(unrestricted float x, unrestricted float y); + [MayThrowException] SVGMatrix flipX(); + [MayThrowException] SVGMatrix flipY(); + [MayThrowException] SVGMatrix skewX(unrestricted float angle); + [MayThrowException] SVGMatrix skewY(unrestricted float angle); }; - diff --git a/Source/WebCore/svg/SVGMatrixValue.h b/Source/WebCore/svg/SVGMatrixValue.h new file mode 100644 index 000000000..e02244b86 --- /dev/null +++ b/Source/WebCore/svg/SVGMatrixValue.h @@ -0,0 +1,125 @@ +/* + * 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. + */ + +#pragma once + +#include "AffineTransform.h" +#include "ExceptionOr.h" +#include "SVGException.h" + +namespace WebCore { + +class SVGMatrixValue final : public AffineTransform { +public: + SVGMatrixValue() = default; + + SVGMatrixValue(const AffineTransform& other) + : AffineTransform(other) + { + } + + SVGMatrixValue(double a, double b, double c, double d, double e, double f) + : AffineTransform(a, b, c, d, e, f) + { + } + + SVGMatrixValue translate(double tx, double ty) + { + AffineTransform copy { *this }; + copy.translate(tx, ty); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue scale(double s) + { + AffineTransform copy { *this }; + copy.scale(s, s); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue scaleNonUniform(double sx, double sy) + { + AffineTransform copy { *this }; + copy.scale(sx, sy); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue rotate(double d) + { + AffineTransform copy { *this }; + copy.rotate(d); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue flipX() + { + AffineTransform copy { *this }; + copy.flipX(); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue flipY() + { + AffineTransform copy { *this }; + copy.flipY(); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue skewX(double angle) + { + AffineTransform copy { *this }; + copy.skewX(angle); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue skewY(double angle) + { + AffineTransform copy { *this }; + copy.skewY(angle); + return SVGMatrixValue { copy }; + } + + SVGMatrixValue multiply(const SVGMatrixValue& other) + { + AffineTransform copy { *this }; + copy *= static_cast<const AffineTransform&>(other); + return SVGMatrixValue { copy }; + } + + ExceptionOr<SVGMatrixValue> inverse() const + { + if (auto inverse = AffineTransform::inverse()) + return SVGMatrixValue { inverse.value() }; + + return Exception { SVGException::SVG_MATRIX_NOT_INVERTABLE }; + } + + ExceptionOr<SVGMatrixValue> rotateFromVector(double x, double y) + { + if (!x || !y) + return Exception { SVGException::SVG_INVALID_VALUE_ERR }; + + AffineTransform copy { *this }; + copy.rotateFromVector(x, y); + return SVGMatrixValue { copy }; + } + +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGMetadataElement.cpp b/Source/WebCore/svg/SVGMetadataElement.cpp index 7cb2a56ee..4272869e4 100644 --- a/Source/WebCore/svg/SVGMetadataElement.cpp +++ b/Source/WebCore/svg/SVGMetadataElement.cpp @@ -19,8 +19,8 @@ */ #include "config.h" -#if ENABLE(SVG) #include "SVGMetadataElement.h" + #include "SVGNames.h" namespace WebCore { @@ -31,11 +31,9 @@ inline SVGMetadataElement::SVGMetadataElement(const QualifiedName& tagName, Docu ASSERT(hasTagName(SVGNames::metadataTag)); } -PassRefPtr<SVGMetadataElement> SVGMetadataElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGMetadataElement> SVGMetadataElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGMetadataElement(tagName, document)); + return adoptRef(*new SVGMetadataElement(tagName, document)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGMetadataElement.h b/Source/WebCore/svg/SVGMetadataElement.h index 69cafc225..d4c0e867c 100644 --- a/Source/WebCore/svg/SVGMetadataElement.h +++ b/Source/WebCore/svg/SVGMetadataElement.h @@ -18,9 +18,7 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGMetadataElement_h -#define SVGMetadataElement_h -#if ENABLE(SVG) +#pragma once #include "SVGElement.h" @@ -28,17 +26,12 @@ namespace WebCore { class SVGMetadataElement final : public SVGElement { public: - static PassRefPtr<SVGMetadataElement> create(const QualifiedName&, Document&); + static Ref<SVGMetadataElement> create(const QualifiedName&, Document&); private: SVGMetadataElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGMetadataElement.idl b/Source/WebCore/svg/SVGMetadataElement.idl index 877c8b148..fc1500a36 100644 --- a/Source/WebCore/svg/SVGMetadataElement.idl +++ b/Source/WebCore/svg/SVGMetadataElement.idl @@ -19,8 +19,6 @@ * Boston, MA 02110-1301, USA. */ -[ - Conditional=SVG -] interface SVGMetadataElement : SVGElement { +interface SVGMetadataElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGMissingGlyphElement.cpp b/Source/WebCore/svg/SVGMissingGlyphElement.cpp index 7d1ae0d8f..f9034c498 100644 --- a/Source/WebCore/svg/SVGMissingGlyphElement.cpp +++ b/Source/WebCore/svg/SVGMissingGlyphElement.cpp @@ -31,9 +31,9 @@ inline SVGMissingGlyphElement::SVGMissingGlyphElement(const QualifiedName& tagNa ASSERT(hasTagName(SVGNames::missing_glyphTag)); } -PassRefPtr<SVGMissingGlyphElement> SVGMissingGlyphElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGMissingGlyphElement> SVGMissingGlyphElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGMissingGlyphElement(tagName, document)); + return adoptRef(*new SVGMissingGlyphElement(tagName, document)); } } diff --git a/Source/WebCore/svg/SVGMissingGlyphElement.h b/Source/WebCore/svg/SVGMissingGlyphElement.h index f5637ee92..9b9e965d0 100644 --- a/Source/WebCore/svg/SVGMissingGlyphElement.h +++ b/Source/WebCore/svg/SVGMissingGlyphElement.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGMissingGlyphElement_h -#define SVGMissingGlyphElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGElement.h" #include "SVGNames.h" @@ -28,17 +28,14 @@ namespace WebCore { class SVGMissingGlyphElement final : public SVGElement { public: - static PassRefPtr<SVGMissingGlyphElement> create(const QualifiedName&, Document&); + static Ref<SVGMissingGlyphElement> create(const QualifiedName&, Document&); private: SVGMissingGlyphElement(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGMissingGlyphElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif diff --git a/Source/WebCore/svg/SVGMissingGlyphElement.idl b/Source/WebCore/svg/SVGMissingGlyphElement.idl index 9a0e3e629..c081c9bec 100644 --- a/Source/WebCore/svg/SVGMissingGlyphElement.idl +++ b/Source/WebCore/svg/SVGMissingGlyphElement.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGMissingGlyphElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGNumber.h b/Source/WebCore/svg/SVGNumber.h new file mode 100644 index 000000000..13b8a0a85 --- /dev/null +++ b/Source/WebCore/svg/SVGNumber.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "ExceptionCode.h" +#include "SVGPropertyTearOff.h" + +namespace WebCore { + +class SVGNumber : public SVGPropertyTearOff<float> { +public: + static Ref<SVGNumber> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, float& value) + { + return adoptRef(*new SVGNumber(animatedProperty, role, value)); + } + + static Ref<SVGNumber> create(const float& initialValue = { }) + { + return adoptRef(*new SVGNumber(initialValue)); + } + + static Ref<SVGNumber> create(const float* initialValue) + { + return adoptRef(*new SVGNumber(initialValue)); + } + + template<typename T> static ExceptionOr<Ref<SVGNumber>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } + + float valueForBindings() + { + return propertyReference(); + } + + ExceptionOr<void> setValueForBindings(float value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference() = value; + commitChange(); + + return { }; + } + +private: + SVGNumber(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, float& value) + : SVGPropertyTearOff<float>(&animatedProperty, role, value) + { + } + + explicit SVGNumber(const float& initialValue) + : SVGPropertyTearOff<float>(initialValue) + { + } + + explicit SVGNumber(const float* initialValue) + : SVGPropertyTearOff<float>(initialValue) + { + } +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGNumber.idl b/Source/WebCore/svg/SVGNumber.idl index 20c767e39..97ed6950e 100644 --- a/Source/WebCore/svg/SVGNumber.idl +++ b/Source/WebCore/svg/SVGNumber.idl @@ -20,9 +20,7 @@ * Boston, MA 02110-1301, USA. */ -[ - Conditional=SVG -] interface SVGNumber { - [StrictTypeChecking] attribute float value; +interface SVGNumber { + [SetterMayThrowException, ImplementedAs=valueForBindings] attribute unrestricted float value; }; diff --git a/Source/WebCore/svg/SVGNumberList.h b/Source/WebCore/svg/SVGNumberList.h index f42d93739..1e5cf8b5a 100644 --- a/Source/WebCore/svg/SVGNumberList.h +++ b/Source/WebCore/svg/SVGNumberList.h @@ -1,49 +1,51 @@ /* - * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGNumberList_h -#define SVGNumberList_h +#pragma once -#if ENABLE(SVG) -#include "SVGPropertyTraits.h" -#include <wtf/Vector.h> +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGListPropertyTearOff.h" +#include "SVGNumberListValues.h" namespace WebCore { -class SVGNumberList : public Vector<float> { +class SVGNumberList : public SVGListPropertyTearOff<SVGNumberListValues> { public: - SVGNumberList() { } - - void parse(const String&); - String valueAsString() const; -}; - -template<> -struct SVGPropertyTraits<SVGNumberList> { - typedef float ListItemType; - - static SVGNumberList initialValue() { return SVGNumberList(); } - static String toString(const SVGNumberList& type) { return type.valueAsString(); } + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<SVGNumberListValues>; + using ListWrapperCache = AnimatedListPropertyTearOff::ListWrapperCache; + + static Ref<SVGNumberList> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGNumberListValues& values, ListWrapperCache& wrappers) + { + return adoptRef(*new SVGNumberList(animatedProperty, role, values, wrappers)); + } + +private: + SVGNumberList(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGNumberListValues& values, ListWrapperCache& wrappers) + : SVGListPropertyTearOff<SVGNumberListValues>(animatedProperty, role, values, wrappers) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGNumberList.idl b/Source/WebCore/svg/SVGNumberList.idl index a4d539417..deae69d2e 100644 --- a/Source/WebCore/svg/SVGNumberList.idl +++ b/Source/WebCore/svg/SVGNumberList.idl @@ -24,17 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGNumberList { +interface SVGNumberList { readonly attribute unsigned long numberOfItems; - [RaisesException] void clear(); - [StrictTypeChecking, RaisesException] SVGNumber initialize(SVGNumber item); - [StrictTypeChecking, RaisesException] SVGNumber getItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGNumber insertItemBefore(SVGNumber item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGNumber replaceItem(SVGNumber item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGNumber removeItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGNumber appendItem(SVGNumber item); + [MayThrowException] void clear(); + [MayThrowException] SVGNumber initialize(SVGNumber item); + [MayThrowException] SVGNumber getItem(unsigned long index); + [MayThrowException] SVGNumber insertItemBefore(SVGNumber item, unsigned long index); + [MayThrowException] SVGNumber replaceItem(SVGNumber item, unsigned long index); + [MayThrowException] SVGNumber removeItem(unsigned long index); + [MayThrowException] SVGNumber appendItem(SVGNumber item); }; - diff --git a/Source/WebCore/svg/SVGNumberList.cpp b/Source/WebCore/svg/SVGNumberListValues.cpp index b1fd9464d..6dfd993b2 100644 --- a/Source/WebCore/svg/SVGNumberList.cpp +++ b/Source/WebCore/svg/SVGNumberListValues.cpp @@ -19,24 +19,23 @@ */ #include "config.h" - -#if ENABLE(SVG) -#include "SVGNumberList.h" +#include "SVGNumberListValues.h" #include "SVGParserUtilities.h" #include <wtf/text/StringBuilder.h> namespace WebCore { -void SVGNumberList::parse(const String& value) +void SVGNumberListValues::parse(const String& value) { clear(); float number = 0; - const UChar* ptr = value.deprecatedCharacters(); + auto upconvertedCharacters = StringView(value).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + value.length(); - // The spec strangely doesn't allow leading whitespace. We might choose to violate that intentionally. (section 4.1) + // The spec (section 4.1) strangely doesn't allow leading whitespace. We might choose to violate that intentionally. while (ptr < end) { if (!parseNumber(ptr, end, number)) return; @@ -44,7 +43,7 @@ void SVGNumberList::parse(const String& value) } } -String SVGNumberList::valueAsString() const +String SVGNumberListValues::valueAsString() const { StringBuilder builder; @@ -60,5 +59,3 @@ String SVGNumberList::valueAsString() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGNumberListValues.h b/Source/WebCore/svg/SVGNumberListValues.h new file mode 100644 index 000000000..7b4ac7789 --- /dev/null +++ b/Source/WebCore/svg/SVGNumberListValues.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@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. + */ + +#pragma once + +#include "SVGPropertyTraits.h" +#include <wtf/Vector.h> + +namespace WebCore { + +class SVGNumber; +class SVGNumberList; + +class SVGNumberListValues final : public Vector<float> { +public: + void parse(const String&); + String valueAsString() const; +}; + +template<> struct SVGPropertyTraits<SVGNumberListValues> { + static SVGNumberListValues initialValue() { return { }; } + static String toString(const SVGNumberListValues& list) { return list.valueAsString(); } + + using ListItemType = float; + using ListItemTearOff = SVGNumber; + using ListPropertyTearOff = SVGNumberList; +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGPaint.cpp b/Source/WebCore/svg/SVGPaint.cpp deleted file mode 100644 index 481c91cec..000000000 --- a/Source/WebCore/svg/SVGPaint.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) Research In Motion Limited 2010-2011. 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 "SVGPaint.h" - -#include "SVGException.h" -#include "SVGURIReference.h" -#include <wtf/text/WTFString.h> - -namespace WebCore { - -static inline SVGColor::SVGColorType colorTypeForPaintType(const SVGPaint::SVGPaintType& paintType) -{ - switch (paintType) { - case SVGPaint::SVG_PAINTTYPE_NONE: - case SVGPaint::SVG_PAINTTYPE_UNKNOWN: - case SVGPaint::SVG_PAINTTYPE_URI: - case SVGPaint::SVG_PAINTTYPE_URI_NONE: - return SVGColor::SVG_COLORTYPE_UNKNOWN; - case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR: - case SVGPaint::SVG_PAINTTYPE_RGBCOLOR: - return SVGColor::SVG_COLORTYPE_RGBCOLOR; - case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: - case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: - return SVGColor::SVG_COLORTYPE_RGBCOLOR_ICCCOLOR; - case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR: - case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR: - return SVGColor::SVG_COLORTYPE_CURRENTCOLOR; - } - - ASSERT_NOT_REACHED(); - return SVGColor::SVG_COLORTYPE_UNKNOWN; -} - -SVGPaint::SVGPaint(const SVGPaintType& paintType, const String& uri) - : SVGColor(SVGPaintClass, colorTypeForPaintType(paintType)) - , m_paintType(paintType) - , m_uri(uri) -{ -} - -void SVGPaint::setUri(const String&) -{ - // The whole SVGPaint interface is deprecated in SVG 1.1 (2nd edition). - // The setters are the most problematic part so we remove the support for those first. -} - -void SVGPaint::setPaint(unsigned short, const String&, const String&, const String&, ExceptionCode& ec) -{ - ec = NO_MODIFICATION_ALLOWED_ERR; -} - -String SVGPaint::customCSSText() const -{ - switch (m_paintType) { - case SVG_PAINTTYPE_UNKNOWN: - case SVG_PAINTTYPE_RGBCOLOR: - case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR: - case SVG_PAINTTYPE_CURRENTCOLOR: - return SVGColor::customCSSText(); - case SVG_PAINTTYPE_NONE: - return "none"; - case SVG_PAINTTYPE_URI_NONE: - return m_uri + " none"; - case SVG_PAINTTYPE_URI_CURRENTCOLOR: - case SVG_PAINTTYPE_URI_RGBCOLOR: - case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: { - String color = SVGColor::customCSSText(); - if (color.isEmpty()) - return m_uri; - return "url(" + m_uri + ") " + color; - } - case SVG_PAINTTYPE_URI: - return "url(" + m_uri + ')'; - }; - - ASSERT_NOT_REACHED(); - return String(); -} - -SVGPaint::SVGPaint(const SVGPaint& cloneFrom) - : SVGColor(SVGPaintClass, cloneFrom) - , m_paintType(cloneFrom.m_paintType) - , m_uri(cloneFrom.m_uri) -{ -} - -PassRefPtr<SVGPaint> SVGPaint::cloneForCSSOM() const -{ - return adoptRef(new SVGPaint(*this)); -} - -bool SVGPaint::equals(const SVGPaint& other) const -{ - return m_paintType == other.m_paintType && m_uri == other.m_uri && SVGColor::equals(other); -} - -} - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPaint.h b/Source/WebCore/svg/SVGPaint.h deleted file mode 100644 index 3941c8695..000000000 --- a/Source/WebCore/svg/SVGPaint.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmial.com> - * Copyright (C) Research In Motion Limited 2011. 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 SVGPaint_h -#define SVGPaint_h - -#if ENABLE(SVG) -#include "SVGColor.h" -#include <wtf/text/WTFString.h> - -namespace WebCore { - -class SVGPaint : public SVGColor { -public: - enum SVGPaintType { - SVG_PAINTTYPE_UNKNOWN = 0, - SVG_PAINTTYPE_RGBCOLOR = 1, - SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2, - SVG_PAINTTYPE_NONE = 101, - SVG_PAINTTYPE_CURRENTCOLOR = 102, - SVG_PAINTTYPE_URI_NONE = 103, - SVG_PAINTTYPE_URI_CURRENTCOLOR = 104, - SVG_PAINTTYPE_URI_RGBCOLOR = 105, - SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106, - SVG_PAINTTYPE_URI = 107 - }; - - static PassRef<SVGPaint> createUnknown() - { - return adoptRef(*new SVGPaint(SVG_PAINTTYPE_UNKNOWN)); - } - - static PassRef<SVGPaint> createNone() - { - return adoptRef(*new SVGPaint(SVG_PAINTTYPE_NONE)); - } - - static PassRef<SVGPaint> createCurrentColor() - { - return adoptRef(*new SVGPaint(SVG_PAINTTYPE_CURRENTCOLOR)); - } - - static PassRef<SVGPaint> createColor(const Color& color) - { - auto paint = adoptRef(*new SVGPaint(SVG_PAINTTYPE_RGBCOLOR)); - paint.get().setColor(color); - return paint; - } - - static PassRef<SVGPaint> createURI(const String& uri) - { - return adoptRef(*new SVGPaint(SVG_PAINTTYPE_URI, uri)); - } - - static PassRef<SVGPaint> createURIAndColor(const String& uri, const Color& color) - { - auto paint = adoptRef(*new SVGPaint(SVG_PAINTTYPE_URI_RGBCOLOR, uri)); - paint.get().setColor(color); - return paint; - } - - static PassRef<SVGPaint> createURIAndNone(const String& uri) - { - return adoptRef(*new SVGPaint(SVG_PAINTTYPE_URI_NONE, uri)); - } - - const SVGPaintType& paintType() const { return m_paintType; } - String uri() const { return m_uri; } - - void setUri(const String&); - void setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionCode&); - - String customCSSText() const; - - PassRefPtr<SVGPaint> cloneForCSSOM() const; - - bool equals(const SVGPaint&) const; - -private: - friend class ComputedStyleExtractor; - - static PassRef<SVGPaint> create(const SVGPaintType& type, const String& uri, const Color& color) - { - auto paint = adoptRef(*new SVGPaint(type, uri)); - paint.get().setColor(color); - return paint; - } - -private: - SVGPaint(const SVGPaintType&, const String& uri = String()); - SVGPaint(const SVGPaint& cloneFrom); - - SVGPaintType m_paintType; - String m_uri; -}; - -CSS_VALUE_TYPE_CASTS(SVGPaint, isSVGPaint()); - -} // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPaint_h diff --git a/Source/WebCore/svg/SVGPaint.idl b/Source/WebCore/svg/SVGPaint.idl deleted file mode 100644 index 1d7204127..000000000 --- a/Source/WebCore/svg/SVGPaint.idl +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2006 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -[ - Conditional=SVG, - ImplementationLacksVTable, -] interface SVGPaint : SVGColor { - const unsigned short SVG_PAINTTYPE_UNKNOWN = 0; - const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1; - const unsigned short SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2; - const unsigned short SVG_PAINTTYPE_NONE = 101; - const unsigned short SVG_PAINTTYPE_CURRENTCOLOR = 102; - const unsigned short SVG_PAINTTYPE_URI_NONE = 103; - const unsigned short SVG_PAINTTYPE_URI_CURRENTCOLOR = 104; - const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR = 105; - const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106; - const unsigned short SVG_PAINTTYPE_URI = 107; - - readonly attribute unsigned short paintType; - readonly attribute DOMString uri; - - [StrictTypeChecking] void setUri(DOMString uri); - [StrictTypeChecking, RaisesException] void setPaint(unsigned short paintType, DOMString uri, DOMString rgbColor, DOMString iccColor); -}; - diff --git a/Source/WebCore/svg/SVGParserUtilities.cpp b/Source/WebCore/svg/SVGParserUtilities.cpp index b7ae15051..7e2d313a3 100644 --- a/Source/WebCore/svg/SVGParserUtilities.cpp +++ b/Source/WebCore/svg/SVGParserUtilities.cpp @@ -21,16 +21,14 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGParserUtilities.h" #include "Document.h" #include "FloatRect.h" -#include "SVGPointList.h" - +#include "SVGPointListValues.h" #include <limits> #include <wtf/ASCIICType.h> +#include <wtf/text/StringView.h> namespace WebCore { @@ -64,13 +62,12 @@ template <typename CharacterType, typename FloatType> static bool genericParseNu sign = -1; } - if (ptr == end || ((*ptr < '0' || *ptr > '9') && *ptr != '.')) - // The first character of a number must be one of [0-9+-.] + if (ptr == end || (!isASCIIDigit(*ptr) && *ptr != '.')) return false; // read the integer part, build right-to-left const CharacterType* ptrStartIntPart = ptr; - while (ptr < end && *ptr >= '0' && *ptr <= '9') + while (ptr < end && isASCIIDigit(*ptr)) ++ptr; // Advance to first non-digit. if (ptr != ptrStartIntPart) { @@ -89,10 +86,10 @@ template <typename CharacterType, typename FloatType> static bool genericParseNu ptr++; // There must be a least one digit following the . - if (ptr >= end || *ptr < '0' || *ptr > '9') + if (ptr >= end || !isASCIIDigit(*ptr)) return false; - while (ptr < end && *ptr >= '0' && *ptr <= '9') + while (ptr < end && isASCIIDigit(*ptr)) decimal += (*(ptr++) - '0') * (frac *= static_cast<FloatType>(0.1)); } @@ -110,10 +107,10 @@ template <typename CharacterType, typename FloatType> static bool genericParseNu } // There must be an exponent - if (ptr >= end || *ptr < '0' || *ptr > '9') + if (ptr >= end || !isASCIIDigit(*ptr)) return false; - while (ptr < end && *ptr >= '0' && *ptr <= '9') { + while (ptr < end && isASCIIDigit(*ptr)) { exponent *= static_cast<FloatType>(10); exponent += *ptr - '0'; ptr++; @@ -166,7 +163,8 @@ bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip) bool parseNumberFromString(const String& string, float& number, bool skip) { - const UChar* ptr = string.deprecatedCharacters(); + auto upconvertedCharacters = StringView(string).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + string.length(); return genericParseNumber(ptr, end, number, skip) && ptr == end; } @@ -205,7 +203,9 @@ bool parseNumberOptionalNumber(const String& s, float& x, float& y) { if (s.isEmpty()) return false; - const UChar* cur = s.deprecatedCharacters(); + + auto upconvertedCharacters = StringView(s).upconvertedCharacters(); + const UChar* cur = upconvertedCharacters; const UChar* end = cur + s.length(); if (!parseNumber(cur, end, x)) @@ -221,7 +221,8 @@ bool parseNumberOptionalNumber(const String& s, float& x, float& y) bool parseRect(const String& string, FloatRect& rect) { - const UChar* ptr = string.deprecatedCharacters(); + auto upconvertedCharacters = StringView(string).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + string.length(); skipOptionalSVGSpaces(ptr, end); @@ -234,11 +235,12 @@ bool parseRect(const String& string, FloatRect& rect) return valid; } -bool pointsListFromSVGData(SVGPointList& pointsList, const String& points) +bool pointsListFromSVGData(SVGPointListValues& pointsList, const String& points) { if (points.isEmpty()) return true; - const UChar* cur = points.deprecatedCharacters(); + auto upconvertedCharacters = StringView(points).upconvertedCharacters(); + const UChar* cur = upconvertedCharacters; const UChar* end = cur + points.length(); skipOptionalSVGSpaces(cur, end); @@ -272,7 +274,8 @@ bool parseGlyphName(const String& input, HashSet<String>& values) // FIXME: Parsing error detection is missing. values.clear(); - const UChar* ptr = input.deprecatedCharacters(); + auto upconvertedCharacters = StringView(input).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + input.length(); skipOptionalSVGSpaces(ptr, end); @@ -369,7 +372,8 @@ static bool parseUnicodeRange(const UChar* characters, unsigned length, UnicodeR bool parseKerningUnicodeString(const String& input, UnicodeRanges& rangeList, HashSet<String>& stringList) { // FIXME: Parsing error detection is missing. - const UChar* ptr = input.deprecatedCharacters(); + auto upconvertedCharacters = StringView(input).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + input.length(); while (ptr < end) { @@ -396,7 +400,8 @@ Vector<String> parseDelimitedString(const String& input, const char seperator) { Vector<String> values; - const UChar* ptr = input.deprecatedCharacters(); + auto upconvertedCharacters = StringView(input).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + input.length(); skipOptionalSVGSpaces(ptr, end); @@ -482,5 +487,3 @@ template bool parseFloatPoint3(const LChar*& current, const LChar* end, FloatPoi template bool parseFloatPoint3(const UChar*& current, const UChar* end, FloatPoint& point1, FloatPoint& point2, FloatPoint& point3); } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGParserUtilities.h b/Source/WebCore/svg/SVGParserUtilities.h index 5797a1706..e1e5cce89 100644 --- a/Source/WebCore/svg/SVGParserUtilities.h +++ b/Source/WebCore/svg/SVGParserUtilities.h @@ -19,9 +19,7 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGParserUtilities_h -#define SVGParserUtilities_h -#if ENABLE(SVG) +#pragma once #include "ParserUtilities.h" #include <wtf/HashSet.h> @@ -33,7 +31,7 @@ namespace WebCore { class FloatPoint; class FloatRect; -class SVGPointList; +class SVGPointListValues; template <typename CharacterType> bool parseSVGNumber(CharacterType* ptr, size_t length, double& number); @@ -82,12 +80,9 @@ inline bool skipOptionalSVGSpacesOrDelimiter(const CharacterType*& ptr, const Ch return ptr < end; } -bool pointsListFromSVGData(SVGPointList& pointsList, const String& points); +bool pointsListFromSVGData(SVGPointListValues&, const String& points); Vector<String> parseDelimitedString(const String& input, const char seperator); bool parseKerningUnicodeString(const String& input, UnicodeRanges&, HashSet<String>& stringList); bool parseGlyphName(const String& input, HashSet<String>& values); } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGParserUtilities_h diff --git a/Source/WebCore/svg/SVGParsingError.h b/Source/WebCore/svg/SVGParsingError.h index 1624db87a..1b9a701b9 100644 --- a/Source/WebCore/svg/SVGParsingError.h +++ b/Source/WebCore/svg/SVGParsingError.h @@ -24,10 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGParsingError_h -#define SVGParsingError_h - -#if ENABLE(SVG) +#pragma once namespace WebCore { @@ -38,6 +35,3 @@ enum SVGParsingError { }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGParsingError_h diff --git a/Source/WebCore/svg/SVGPathBlender.cpp b/Source/WebCore/svg/SVGPathBlender.cpp index 877d39896..8d2f636cf 100644 --- a/Source/WebCore/svg/SVGPathBlender.cpp +++ b/Source/WebCore/svg/SVGPathBlender.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -18,24 +19,37 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathBlender.h" #include "AnimationUtilities.h" #include "SVGPathSeg.h" #include "SVGPathSource.h" -#include <wtf/TemporaryChange.h> +#include <wtf/SetForScope.h> namespace WebCore { -SVGPathBlender::SVGPathBlender() - : m_fromSource(0) - , m_toSource(0) - , m_consumer(0) - , m_progress(0) - , m_addTypesCount(0) - , m_isInFirstHalfOfAnimation(false) +bool SVGPathBlender::addAnimatedPath(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer& consumer, unsigned repeatCount) +{ + SVGPathBlender blender(fromSource, toSource, &consumer); + return blender.addAnimatedPath(repeatCount); +} + +bool SVGPathBlender::blendAnimatedPath(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer& consumer, float progress) +{ + SVGPathBlender blender(fromSource, toSource, &consumer); + return blender.blendAnimatedPath(progress); +} + +bool SVGPathBlender::canBlendPaths(SVGPathSource& fromSource, SVGPathSource& toSource) +{ + SVGPathBlender blender(fromSource, toSource); + return blender.canBlendPaths(); +} + +SVGPathBlender::SVGPathBlender(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer* consumer) + : m_fromSource(fromSource) + , m_toSource(toSource) + , m_consumer(consumer) { } @@ -45,7 +59,7 @@ static inline FloatPoint blendFloatPoint(const FloatPoint& a, const FloatPoint& return FloatPoint(blend(a.x(), b.x(), progress), blend(a.y(), b.y(), progress)); } -float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode blendMode) +float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode blendMode, float progress) { if (m_addTypesCount) { ASSERT(m_fromMode == m_toMode); @@ -53,33 +67,33 @@ float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBl } if (m_fromMode == m_toMode) - return blend(from, to, m_progress); + return blend(from, to, progress); float fromValue = blendMode == BlendHorizontal ? m_fromCurrentPoint.x() : m_fromCurrentPoint.y(); float toValue = blendMode == BlendHorizontal ? m_toCurrentPoint.x() : m_toCurrentPoint.y(); // Transform toY to the coordinate mode of fromY - float animValue = blend(from, m_fromMode == AbsoluteCoordinates ? to + toValue : to - toValue, m_progress); + float animValue = blend(from, m_fromMode == AbsoluteCoordinates ? to + toValue : to - toValue, progress); if (m_isInFirstHalfOfAnimation) return animValue; // Transform the animated point to the coordinate mode, needed for the current progress. - float currentValue = blend(fromValue, toValue, m_progress); + float currentValue = blend(fromValue, toValue, progress); return m_toMode == AbsoluteCoordinates ? animValue + currentValue : animValue - currentValue; } -FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint) +FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint, float progress) { if (m_addTypesCount) { ASSERT(m_fromMode == m_toMode); FloatPoint repeatedToPoint = toPoint; - repeatedToPoint.scale(m_addTypesCount, m_addTypesCount); + repeatedToPoint.scale(m_addTypesCount); return fromPoint + repeatedToPoint; } if (m_fromMode == m_toMode) - return blendFloatPoint(fromPoint, toPoint, m_progress); + return blendFloatPoint(fromPoint, toPoint, progress); // Transform toPoint to the coordinate mode of fromPoint FloatPoint animatedPoint = toPoint; @@ -88,13 +102,13 @@ FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, else animatedPoint.move(-m_toCurrentPoint.x(), -m_toCurrentPoint.y()); - animatedPoint = blendFloatPoint(fromPoint, animatedPoint, m_progress); + animatedPoint = blendFloatPoint(fromPoint, animatedPoint, progress); if (m_isInFirstHalfOfAnimation) return animatedPoint; // Transform the animated point to the coordinate mode, needed for the current progress. - FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoint, m_progress); + FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoint, progress); if (m_toMode == AbsoluteCoordinates) return animatedPoint + currentPoint; @@ -102,63 +116,75 @@ FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, return animatedPoint; } -bool SVGPathBlender::blendMoveToSegment() +bool SVGPathBlender::blendMoveToSegment(float progress) { FloatPoint fromTargetPoint; FloatPoint toTargetPoint; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseMoveToSegment(fromTargetPoint)) - || !m_toSource->parseMoveToSegment(toTargetPoint)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseMoveToSegment(fromTargetPoint)) + || !m_toSource.parseMoveToSegment(toTargetPoint)) return false; - m_consumer->moveTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), false, m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->moveTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), false, m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint; m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint; return true; } -bool SVGPathBlender::blendLineToSegment() +bool SVGPathBlender::blendLineToSegment(float progress) { FloatPoint fromTargetPoint; FloatPoint toTargetPoint; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseLineToSegment(fromTargetPoint)) - || !m_toSource->parseLineToSegment(toTargetPoint)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseLineToSegment(fromTargetPoint)) + || !m_toSource.parseLineToSegment(toTargetPoint)) return false; - m_consumer->lineTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->lineTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint; m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint; return true; } -bool SVGPathBlender::blendLineToHorizontalSegment() +bool SVGPathBlender::blendLineToHorizontalSegment(float progress) { float fromX = 0; float toX = 0; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseLineToHorizontalSegment(fromX)) - || !m_toSource->parseLineToHorizontalSegment(toX)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseLineToHorizontalSegment(fromX)) + || !m_toSource.parseLineToHorizontalSegment(toX)) return false; - m_consumer->lineToHorizontal(blendAnimatedDimensonalFloat(fromX, toX, BlendHorizontal), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->lineToHorizontal(blendAnimatedDimensonalFloat(fromX, toX, BlendHorizontal, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint.setX(m_fromMode == AbsoluteCoordinates ? fromX : m_fromCurrentPoint.x() + fromX); m_toCurrentPoint.setX(m_toMode == AbsoluteCoordinates ? toX : m_toCurrentPoint.x() + toX); return true; } -bool SVGPathBlender::blendLineToVerticalSegment() +bool SVGPathBlender::blendLineToVerticalSegment(float progress) { float fromY = 0; float toY = 0; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseLineToVerticalSegment(fromY)) - || !m_toSource->parseLineToVerticalSegment(toY)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseLineToVerticalSegment(fromY)) + || !m_toSource.parseLineToVerticalSegment(toY)) return false; - m_consumer->lineToVertical(blendAnimatedDimensonalFloat(fromY, toY, BlendVertical), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->lineToVertical(blendAnimatedDimensonalFloat(fromY, toY, BlendVertical, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint.setY(m_fromMode == AbsoluteCoordinates ? fromY : m_fromCurrentPoint.y() + fromY); m_toCurrentPoint.setY(m_toMode == AbsoluteCoordinates ? toY : m_toCurrentPoint.y() + toY); return true; } -bool SVGPathBlender::blendCurveToCubicSegment() +bool SVGPathBlender::blendCurveToCubicSegment(float progress) { FloatPoint fromTargetPoint; FloatPoint fromPoint1; @@ -166,70 +192,82 @@ bool SVGPathBlender::blendCurveToCubicSegment() FloatPoint toTargetPoint; FloatPoint toPoint1; FloatPoint toPoint2; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToCubicSegment(fromPoint1, fromPoint2, fromTargetPoint)) - || !m_toSource->parseCurveToCubicSegment(toPoint1, toPoint2, toTargetPoint)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToCubicSegment(fromPoint1, fromPoint2, fromTargetPoint)) + || !m_toSource.parseCurveToCubicSegment(toPoint1, toPoint2, toTargetPoint)) return false; - m_consumer->curveToCubic(blendAnimatedFloatPoint(fromPoint1, toPoint1), - blendAnimatedFloatPoint(fromPoint2, toPoint2), - blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), - m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->curveToCubic(blendAnimatedFloatPoint(fromPoint1, toPoint1, progress), + blendAnimatedFloatPoint(fromPoint2, toPoint2, progress), + blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), + m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint; m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint; return true; } -bool SVGPathBlender::blendCurveToCubicSmoothSegment() +bool SVGPathBlender::blendCurveToCubicSmoothSegment(float progress) { FloatPoint fromTargetPoint; FloatPoint fromPoint2; FloatPoint toTargetPoint; FloatPoint toPoint2; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToCubicSmoothSegment(fromPoint2, fromTargetPoint)) - || !m_toSource->parseCurveToCubicSmoothSegment(toPoint2, toTargetPoint)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToCubicSmoothSegment(fromPoint2, fromTargetPoint)) + || !m_toSource.parseCurveToCubicSmoothSegment(toPoint2, toTargetPoint)) return false; - m_consumer->curveToCubicSmooth(blendAnimatedFloatPoint(fromPoint2, toPoint2), - blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), - m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->curveToCubicSmooth(blendAnimatedFloatPoint(fromPoint2, toPoint2, progress), + blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), + m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint; m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint; return true; } -bool SVGPathBlender::blendCurveToQuadraticSegment() +bool SVGPathBlender::blendCurveToQuadraticSegment(float progress) { FloatPoint fromTargetPoint; FloatPoint fromPoint1; FloatPoint toTargetPoint; FloatPoint toPoint1; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToQuadraticSegment(fromPoint1, fromTargetPoint)) - || !m_toSource->parseCurveToQuadraticSegment(toPoint1, toTargetPoint)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToQuadraticSegment(fromPoint1, fromTargetPoint)) + || !m_toSource.parseCurveToQuadraticSegment(toPoint1, toTargetPoint)) return false; - m_consumer->curveToQuadratic(blendAnimatedFloatPoint(fromPoint1, toPoint1), - blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), - m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->curveToQuadratic(blendAnimatedFloatPoint(fromPoint1, toPoint1, progress), + blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), + m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint; m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint; return true; } -bool SVGPathBlender::blendCurveToQuadraticSmoothSegment() +bool SVGPathBlender::blendCurveToQuadraticSmoothSegment(float progress) { FloatPoint fromTargetPoint; FloatPoint toTargetPoint; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToQuadraticSmoothSegment(fromTargetPoint)) - || !m_toSource->parseCurveToQuadraticSmoothSegment(toTargetPoint)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToQuadraticSmoothSegment(fromTargetPoint)) + || !m_toSource.parseCurveToQuadraticSmoothSegment(toTargetPoint)) return false; - m_consumer->curveToQuadraticSmooth(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + if (!m_consumer) + return true; + + m_consumer->curveToQuadraticSmooth(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint; m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint; return true; } -bool SVGPathBlender::blendArcToSegment() +bool SVGPathBlender::blendArcToSegment(float progress) { float fromRx = 0; float fromRy = 0; @@ -243,29 +281,32 @@ bool SVGPathBlender::blendArcToSegment() bool toLargeArc = false; bool toSweep = false; FloatPoint toTargetPoint; - if ((m_fromSource->hasMoreData() && !m_fromSource->parseArcToSegment(fromRx, fromRy, fromAngle, fromLargeArc, fromSweep, fromTargetPoint)) - || !m_toSource->parseArcToSegment(toRx, toRy, toAngle, toLargeArc, toSweep, toTargetPoint)) + if ((m_fromSource.hasMoreData() && !m_fromSource.parseArcToSegment(fromRx, fromRy, fromAngle, fromLargeArc, fromSweep, fromTargetPoint)) + || !m_toSource.parseArcToSegment(toRx, toRy, toAngle, toLargeArc, toSweep, toTargetPoint)) return false; + if (!m_consumer) + return true; + if (m_addTypesCount) { ASSERT(m_fromMode == m_toMode); FloatPoint scaledToTargetPoint = toTargetPoint; - scaledToTargetPoint.scale(m_addTypesCount, m_addTypesCount); + scaledToTargetPoint.scale(m_addTypesCount); m_consumer->arcTo(fromRx + toRx * m_addTypesCount, - fromRy + toRy * m_addTypesCount, - fromAngle + toAngle * m_addTypesCount, - fromLargeArc || toLargeArc, - fromSweep || toSweep, - fromTargetPoint + scaledToTargetPoint, - m_fromMode); + fromRy + toRy * m_addTypesCount, + fromAngle + toAngle * m_addTypesCount, + fromLargeArc || toLargeArc, + fromSweep || toSweep, + fromTargetPoint + scaledToTargetPoint, + m_fromMode); } else { - m_consumer->arcTo(blend(fromRx, toRx, m_progress), - blend(fromRy, toRy, m_progress), - blend(fromAngle, toAngle, m_progress), - m_isInFirstHalfOfAnimation ? fromLargeArc : toLargeArc, - m_isInFirstHalfOfAnimation ? fromSweep : toSweep, - blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), - m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); + m_consumer->arcTo(blend(fromRx, toRx, progress), + blend(fromRy, toRy, progress), + blend(fromAngle, toAngle, progress), + m_isInFirstHalfOfAnimation ? fromLargeArc : toLargeArc, + m_isInFirstHalfOfAnimation ? fromSweep : toSweep, + blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), + m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode); } m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint; m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint; @@ -298,28 +339,20 @@ static inline bool isSegmentEqual(const SVGPathSegType& fromType, const SVGPathS return to == from - 1; } -bool SVGPathBlender::addAnimatedPath(SVGPathSource* fromSource, SVGPathSource* toSource, SVGPathConsumer* consumer, unsigned repeatCount) +bool SVGPathBlender::addAnimatedPath(unsigned repeatCount) { - TemporaryChange<unsigned> change(m_addTypesCount, repeatCount); - return blendAnimatedPath(0, fromSource, toSource, consumer); + SetForScope<unsigned> change(m_addTypesCount, repeatCount); + return blendAnimatedPath(0); } -bool SVGPathBlender::blendAnimatedPath(float progress, SVGPathSource* fromSource, SVGPathSource* toSource, SVGPathConsumer* consumer) +bool SVGPathBlender::canBlendPaths() { - ASSERT(fromSource); - ASSERT(toSource); - ASSERT(consumer); - m_fromSource = fromSource; - m_toSource = toSource; - m_consumer = consumer; - m_isInFirstHalfOfAnimation = progress < 0.5f; - m_progress = progress; - - bool fromSourceHadData = m_fromSource->hasMoreData(); - while (m_toSource->hasMoreData()) { + float progress = 0.5; + bool fromSourceHadData = m_fromSource.hasMoreData(); + while (m_toSource.hasMoreData()) { SVGPathSegType fromCommand; SVGPathSegType toCommand; - if ((fromSourceHadData && !m_fromSource->parseSVGSegmentType(fromCommand)) || !m_toSource->parseSVGSegmentType(toCommand)) + if ((fromSourceHadData && !m_fromSource.parseSVGSegmentType(fromCommand)) || !m_toSource.parseSVGSegmentType(toCommand)) return false; m_toMode = coordinateModeOfCommand(toCommand); @@ -333,50 +366,49 @@ bool SVGPathBlender::blendAnimatedPath(float progress, SVGPathSource* fromSource switch (toCommand) { case PathSegMoveToRel: case PathSegMoveToAbs: - if (!blendMoveToSegment()) + if (!blendMoveToSegment(progress)) return false; break; case PathSegLineToRel: case PathSegLineToAbs: - if (!blendLineToSegment()) + if (!blendLineToSegment(progress)) return false; break; case PathSegLineToHorizontalRel: case PathSegLineToHorizontalAbs: - if (!blendLineToHorizontalSegment()) + if (!blendLineToHorizontalSegment(progress)) return false; break; case PathSegLineToVerticalRel: case PathSegLineToVerticalAbs: - if (!blendLineToVerticalSegment()) + if (!blendLineToVerticalSegment(progress)) return false; break; case PathSegClosePath: - m_consumer->closePath(); break; case PathSegCurveToCubicRel: case PathSegCurveToCubicAbs: - if (!blendCurveToCubicSegment()) + if (!blendCurveToCubicSegment(progress)) return false; break; case PathSegCurveToCubicSmoothRel: case PathSegCurveToCubicSmoothAbs: - if (!blendCurveToCubicSmoothSegment()) + if (!blendCurveToCubicSmoothSegment(progress)) return false; break; case PathSegCurveToQuadraticRel: case PathSegCurveToQuadraticAbs: - if (!blendCurveToQuadraticSegment()) + if (!blendCurveToQuadraticSegment(progress)) return false; break; case PathSegCurveToQuadraticSmoothRel: case PathSegCurveToQuadraticSmoothAbs: - if (!blendCurveToQuadraticSmoothSegment()) + if (!blendCurveToQuadraticSmoothSegment(progress)) return false; break; case PathSegArcRel: case PathSegArcAbs: - if (!blendArcToSegment()) + if (!blendArcToSegment(progress)) return false; break; case PathSegUnknown: @@ -385,29 +417,96 @@ bool SVGPathBlender::blendAnimatedPath(float progress, SVGPathSource* fromSource if (!fromSourceHadData) continue; - if (m_fromSource->hasMoreData() != m_toSource->hasMoreData()) + if (m_fromSource.hasMoreData() != m_toSource.hasMoreData()) return false; - if (!m_fromSource->hasMoreData() || !m_toSource->hasMoreData()) + if (!m_fromSource.hasMoreData() || !m_toSource.hasMoreData()) return true; } return true; } -void SVGPathBlender::cleanup() +bool SVGPathBlender::blendAnimatedPath(float progress) { - ASSERT(m_toSource); - ASSERT(m_fromSource); - ASSERT(m_consumer); - - m_consumer->cleanup(); - m_toSource = 0; - m_fromSource = 0; - m_consumer = 0; - m_fromCurrentPoint = FloatPoint(); - m_toCurrentPoint = FloatPoint(); -} + m_isInFirstHalfOfAnimation = progress < 0.5f; + + bool fromSourceHadData = m_fromSource.hasMoreData(); + while (m_toSource.hasMoreData()) { + SVGPathSegType fromCommand; + SVGPathSegType toCommand; + if ((fromSourceHadData && !m_fromSource.parseSVGSegmentType(fromCommand)) || !m_toSource.parseSVGSegmentType(toCommand)) + return false; + m_toMode = coordinateModeOfCommand(toCommand); + m_fromMode = fromSourceHadData ? coordinateModeOfCommand(fromCommand) : m_toMode; + if (m_fromMode != m_toMode && m_addTypesCount) + return false; + + if (fromSourceHadData && !isSegmentEqual(fromCommand, toCommand, m_fromMode, m_toMode)) + return false; + + switch (toCommand) { + case PathSegMoveToRel: + case PathSegMoveToAbs: + if (!blendMoveToSegment(progress)) + return false; + break; + case PathSegLineToRel: + case PathSegLineToAbs: + if (!blendLineToSegment(progress)) + return false; + break; + case PathSegLineToHorizontalRel: + case PathSegLineToHorizontalAbs: + if (!blendLineToHorizontalSegment(progress)) + return false; + break; + case PathSegLineToVerticalRel: + case PathSegLineToVerticalAbs: + if (!blendLineToVerticalSegment(progress)) + return false; + break; + case PathSegClosePath: + m_consumer->closePath(); + break; + case PathSegCurveToCubicRel: + case PathSegCurveToCubicAbs: + if (!blendCurveToCubicSegment(progress)) + return false; + break; + case PathSegCurveToCubicSmoothRel: + case PathSegCurveToCubicSmoothAbs: + if (!blendCurveToCubicSmoothSegment(progress)) + return false; + break; + case PathSegCurveToQuadraticRel: + case PathSegCurveToQuadraticAbs: + if (!blendCurveToQuadraticSegment(progress)) + return false; + break; + case PathSegCurveToQuadraticSmoothRel: + case PathSegCurveToQuadraticSmoothAbs: + if (!blendCurveToQuadraticSmoothSegment(progress)) + return false; + break; + case PathSegArcRel: + case PathSegArcAbs: + if (!blendArcToSegment(progress)) + return false; + break; + case PathSegUnknown: + return false; + } + + if (!fromSourceHadData) + continue; + if (m_fromSource.hasMoreData() != m_toSource.hasMoreData()) + return false; + if (!m_fromSource.hasMoreData() || !m_toSource.hasMoreData()) + return true; + } + + return true; } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGPathBlender.h b/Source/WebCore/svg/SVGPathBlender.h index eee57bf96..9c0d746ff 100644 --- a/Source/WebCore/svg/SVGPathBlender.h +++ b/Source/WebCore/svg/SVGPathBlender.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -17,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathBlender_h -#define SVGPathBlender_h +#pragma once -#if ENABLE(SVG) #include "SVGPathConsumer.h" namespace WebCore { @@ -35,41 +34,44 @@ class SVGPathSource; class SVGPathBlender { WTF_MAKE_NONCOPYABLE(SVGPathBlender); WTF_MAKE_FAST_ALLOCATED; public: - SVGPathBlender(); - bool addAnimatedPath(SVGPathSource*, SVGPathSource*, SVGPathConsumer*, unsigned repeatCount); - bool blendAnimatedPath(float, SVGPathSource*, SVGPathSource*, SVGPathConsumer*); - void cleanup(); + static bool addAnimatedPath(SVGPathSource& from, SVGPathSource& to, SVGPathConsumer&, unsigned repeatCount); + static bool blendAnimatedPath(SVGPathSource& from, SVGPathSource& to, SVGPathConsumer&, float); + + static bool canBlendPaths(SVGPathSource& from, SVGPathSource& to); private: - bool blendMoveToSegment(); - bool blendLineToSegment(); - bool blendLineToHorizontalSegment(); - bool blendLineToVerticalSegment(); - bool blendCurveToCubicSegment(); - bool blendCurveToCubicSmoothSegment(); - bool blendCurveToQuadraticSegment(); - bool blendCurveToQuadraticSmoothSegment(); - bool blendArcToSegment(); - - float blendAnimatedDimensonalFloat(float, float, FloatBlendMode); - FloatPoint blendAnimatedFloatPoint(const FloatPoint& from, const FloatPoint& to); - - SVGPathSource* m_fromSource; - SVGPathSource* m_toSource; - SVGPathConsumer* m_consumer; + SVGPathBlender(SVGPathSource&, SVGPathSource&, SVGPathConsumer* = nullptr); + + bool canBlendPaths(); + + bool addAnimatedPath(unsigned repeatCount); + bool blendAnimatedPath(float progress); + + bool blendMoveToSegment(float progress); + bool blendLineToSegment(float progress); + bool blendLineToHorizontalSegment(float progress); + bool blendLineToVerticalSegment(float progress); + bool blendCurveToCubicSegment(float progress); + bool blendCurveToCubicSmoothSegment(float progress); + bool blendCurveToQuadraticSegment(float progress); + bool blendCurveToQuadraticSmoothSegment(float progress); + bool blendArcToSegment(float progress); + + float blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode, float progress); + FloatPoint blendAnimatedFloatPoint(const FloatPoint& from, const FloatPoint& to, float progress); + + SVGPathSource& m_fromSource; + SVGPathSource& m_toSource; + SVGPathConsumer* m_consumer; // A null consumer indicates that we're just checking blendability. FloatPoint m_fromCurrentPoint; FloatPoint m_toCurrentPoint; - PathCoordinateMode m_fromMode; - PathCoordinateMode m_toMode; - float m_progress; - unsigned m_addTypesCount; - bool m_isInFirstHalfOfAnimation; + PathCoordinateMode m_fromMode { AbsoluteCoordinates }; + PathCoordinateMode m_toMode { AbsoluteCoordinates }; + unsigned m_addTypesCount { 0 }; + bool m_isInFirstHalfOfAnimation { false }; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathBlender_h diff --git a/Source/WebCore/svg/SVGPathBuilder.cpp b/Source/WebCore/svg/SVGPathBuilder.cpp index 7632f14ce..d9e141cb6 100644 --- a/Source/WebCore/svg/SVGPathBuilder.cpp +++ b/Source/WebCore/svg/SVGPathBuilder.cpp @@ -2,7 +2,7 @@ * Copyright (C) 2002, 2003 The Karbon Developers * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -22,53 +22,45 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathBuilder.h" #include "Path.h" namespace WebCore { -SVGPathBuilder::SVGPathBuilder() - : m_path(0) +SVGPathBuilder::SVGPathBuilder(Path& path) + : m_path(path) { } void SVGPathBuilder::moveTo(const FloatPoint& targetPoint, bool closed, PathCoordinateMode mode) { - ASSERT(m_path); m_current = mode == AbsoluteCoordinates ? targetPoint : m_current + targetPoint; - if (closed && !m_path->isEmpty()) - m_path->closeSubpath(); - m_path->moveTo(m_current); + if (closed && !m_path.isEmpty()) + m_path.closeSubpath(); + m_path.moveTo(m_current); } void SVGPathBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_path); m_current = mode == AbsoluteCoordinates ? targetPoint : m_current + targetPoint; - m_path->addLineTo(m_current); + m_path.addLineTo(m_current); } void SVGPathBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_path); if (mode == RelativeCoordinates) { - m_path->addBezierCurveTo(m_current + point1, m_current + point2, m_current + targetPoint); + m_path.addBezierCurveTo(m_current + point1, m_current + point2, m_current + targetPoint); m_current += targetPoint; } else { m_current = targetPoint; - m_path->addBezierCurveTo(point1, point2, m_current); + m_path.addBezierCurveTo(point1, point2, m_current); } } void SVGPathBuilder::closePath() { - ASSERT(m_path); - m_path->closeSubpath(); + m_path.closeSubpath(); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathBuilder.h b/Source/WebCore/svg/SVGPathBuilder.h index 81dda7602..eb8fdac94 100644 --- a/Source/WebCore/svg/SVGPathBuilder.h +++ b/Source/WebCore/svg/SVGPathBuilder.h @@ -2,7 +2,7 @@ * Copyright (C) 2002, 2003 The Karbon Developers * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -21,10 +21,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathBuilder_h -#define SVGPathBuilder_h +#pragma once -#if ENABLE(SVG) #include "FloatPoint.h" #include "SVGPathConsumer.h" @@ -32,36 +30,30 @@ namespace WebCore { class Path; -class SVGPathBuilder : public SVGPathConsumer { +class SVGPathBuilder final : public SVGPathConsumer { public: - SVGPathBuilder(); - - void setCurrentPath(Path* path) { m_path = path; } + SVGPathBuilder(Path&); private: - virtual void incrementPathSegmentCount() override { } - virtual bool continueConsuming() override { return true; } - virtual void cleanup() override { m_path = 0; } + void incrementPathSegmentCount() final { } + bool continueConsuming() final { return true; } // Used in UnalteredParsing/NormalizedParsing modes. - virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override; - virtual void lineTo(const FloatPoint&, PathCoordinateMode) override; - virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void closePath() override; + void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) final; + void lineTo(const FloatPoint&, PathCoordinateMode) final; + void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void closePath() final; // Only used in UnalteredParsing mode. - virtual void lineToHorizontal(float, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void lineToVertical(float, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - - Path* m_path; + void lineToHorizontal(float, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void lineToVertical(float, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + + Path& m_path; FloatPoint m_current; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathBuilder_h diff --git a/Source/WebCore/svg/SVGPathByteStream.h b/Source/WebCore/svg/SVGPathByteStream.h index 715285b83..6dbcfb977 100644 --- a/Source/WebCore/svg/SVGPathByteStream.h +++ b/Source/WebCore/svg/SVGPathByteStream.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathByteStream_h -#define SVGPathByteStream_h +#pragma once -#if ENABLE(SVG) #include <wtf/Noncopyable.h> #include <wtf/Vector.h> @@ -50,19 +48,30 @@ public: SVGPathByteStream() { } SVGPathByteStream(const Data& data) : m_data(data) { } + + bool operator==(const SVGPathByteStream& other) const + { + return m_data == other.m_data; + } + + bool operator!=(const SVGPathByteStream& other) const + { + return !(*this == other); + } std::unique_ptr<SVGPathByteStream> copy() const { return std::make_unique<SVGPathByteStream>(m_data); } - DataIterator begin() { return m_data.begin(); } - DataIterator end() { return m_data.end(); } + DataIterator begin() const { return m_data.begin(); } + DataIterator end() const { return m_data.end(); } + void append(unsigned char byte) { m_data.append(byte); } - void append(SVGPathByteStream* other) + void append(const SVGPathByteStream& other) { - for (DataIterator it = other->begin(); it != other->end(); ++it) - append(*it); + for (auto stream : other) + append(stream); } void clear() { m_data.clear(); } bool isEmpty() const { return !m_data.size(); } @@ -76,6 +85,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathByteStream_h diff --git a/Source/WebCore/svg/SVGPathByteStreamBuilder.cpp b/Source/WebCore/svg/SVGPathByteStreamBuilder.cpp index eda2c26ec..d195c2875 100644 --- a/Source/WebCore/svg/SVGPathByteStreamBuilder.cpp +++ b/Source/WebCore/svg/SVGPathByteStreamBuilder.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -18,52 +19,44 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathByteStreamBuilder.h" -#include "SVGPathParser.h" #include "SVGPathSeg.h" #include "SVGPathStringSource.h" namespace WebCore { -SVGPathByteStreamBuilder::SVGPathByteStreamBuilder() - : m_byteStream(0) +SVGPathByteStreamBuilder::SVGPathByteStreamBuilder(SVGPathByteStream& byteStream) + : m_byteStream(byteStream) { } void SVGPathByteStreamBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegMoveToRel : PathSegMoveToAbs); writeFloatPoint(targetPoint); } void SVGPathByteStreamBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegLineToRel : PathSegLineToAbs); writeFloatPoint(targetPoint); } void SVGPathByteStreamBuilder::lineToHorizontal(float x, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegLineToHorizontalRel : PathSegLineToHorizontalAbs); writeFloat(x); } void SVGPathByteStreamBuilder::lineToVertical(float y, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegLineToVerticalRel : PathSegLineToVerticalAbs); writeFloat(y); } void SVGPathByteStreamBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicRel : PathSegCurveToCubicAbs); writeFloatPoint(point1); writeFloatPoint(point2); @@ -72,7 +65,6 @@ void SVGPathByteStreamBuilder::curveToCubic(const FloatPoint& point1, const Floa void SVGPathByteStreamBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicSmoothRel : PathSegCurveToCubicSmoothAbs); writeFloatPoint(point2); writeFloatPoint(targetPoint); @@ -80,7 +72,6 @@ void SVGPathByteStreamBuilder::curveToCubicSmooth(const FloatPoint& point2, cons void SVGPathByteStreamBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticRel : PathSegCurveToQuadraticAbs); writeFloatPoint(point1); writeFloatPoint(targetPoint); @@ -88,14 +79,12 @@ void SVGPathByteStreamBuilder::curveToQuadratic(const FloatPoint& point1, const void SVGPathByteStreamBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticSmoothRel : PathSegCurveToQuadraticSmoothAbs); writeFloatPoint(targetPoint); } void SVGPathByteStreamBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_byteStream); writeSegmentType(mode == RelativeCoordinates ? PathSegArcRel : PathSegArcAbs); writeFloat(r1); writeFloat(r2); @@ -107,10 +96,7 @@ void SVGPathByteStreamBuilder::arcTo(float r1, float r2, float angle, bool large void SVGPathByteStreamBuilder::closePath() { - ASSERT(m_byteStream); writeSegmentType(PathSegClosePath); } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathByteStreamBuilder.h b/Source/WebCore/svg/SVGPathByteStreamBuilder.h index 0f702380f..5021bfe37 100644 --- a/Source/WebCore/svg/SVGPathByteStreamBuilder.h +++ b/Source/WebCore/svg/SVGPathByteStreamBuilder.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -17,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathByteStreamBuilder_h -#define SVGPathByteStreamBuilder_h +#pragma once -#if ENABLE(SVG) #include "FloatPoint.h" #include "SVGPathByteStream.h" #include "SVGPathConsumer.h" @@ -28,37 +27,34 @@ namespace WebCore { -class SVGPathByteStreamBuilder : public SVGPathConsumer { +class SVGPathByteStreamBuilder final : public SVGPathConsumer { public: - SVGPathByteStreamBuilder(); - - void setCurrentByteStream(SVGPathByteStream* byteStream) { m_byteStream = byteStream; } + SVGPathByteStreamBuilder(SVGPathByteStream&); private: - virtual void incrementPathSegmentCount() override { } - virtual bool continueConsuming() override { return true; } - virtual void cleanup() override { m_byteStream = 0; } + void incrementPathSegmentCount() final { } + bool continueConsuming() final { return true; } // Used in UnalteredParsing/NormalizedParsing modes. - virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override; - virtual void lineTo(const FloatPoint&, PathCoordinateMode) override; - virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void closePath() override; + void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) final; + void lineTo(const FloatPoint&, PathCoordinateMode) final; + void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void closePath() final; // Only used in UnalteredParsing mode. - virtual void lineToHorizontal(float, PathCoordinateMode) override; - virtual void lineToVertical(float, PathCoordinateMode) override; - virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override; - virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) override; + void lineToHorizontal(float, PathCoordinateMode) final; + void lineToVertical(float, PathCoordinateMode) final; + void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) final; + void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) final; template<typename ByteType> void writeType(const ByteType& type) { size_t typeSize = sizeof(ByteType); for (size_t i = 0; i < typeSize; ++i) - m_byteStream->append(type.bytes[i]); + m_byteStream.append(type.bytes[i]); } void writeFlag(bool value) @@ -88,10 +84,7 @@ private: writeType(data); } - SVGPathByteStream* m_byteStream; + SVGPathByteStream& m_byteStream; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathByteStreamBuilder_h diff --git a/Source/WebCore/svg/SVGPathByteStreamSource.cpp b/Source/WebCore/svg/SVGPathByteStreamSource.cpp index 35f03faf3..fa43922f4 100644 --- a/Source/WebCore/svg/SVGPathByteStreamSource.cpp +++ b/Source/WebCore/svg/SVGPathByteStreamSource.cpp @@ -18,17 +18,14 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathByteStreamSource.h" namespace WebCore { -SVGPathByteStreamSource::SVGPathByteStreamSource(SVGPathByteStream* stream) +SVGPathByteStreamSource::SVGPathByteStreamSource(const SVGPathByteStream& stream) { - ASSERT(stream); - m_streamCurrent = stream->begin(); - m_streamEnd = stream->end(); + m_streamCurrent = stream.begin(); + m_streamEnd = stream.end(); } bool SVGPathByteStreamSource::hasMoreData() const @@ -111,5 +108,3 @@ bool SVGPathByteStreamSource::parseArcToSegment(float& rx, float& ry, float& ang } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathByteStreamSource.h b/Source/WebCore/svg/SVGPathByteStreamSource.h index 0d078f566..2e03c8cbf 100644 --- a/Source/WebCore/svg/SVGPathByteStreamSource.h +++ b/Source/WebCore/svg/SVGPathByteStreamSource.h @@ -17,35 +17,33 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathByteStreamSource_h -#define SVGPathByteStreamSource_h +#pragma once -#if ENABLE(SVG) #include "FloatPoint.h" #include "SVGPathByteStream.h" #include "SVGPathSource.h" namespace WebCore { -class SVGPathByteStreamSource : public SVGPathSource { +class SVGPathByteStreamSource final : public SVGPathSource { public: - explicit SVGPathByteStreamSource(SVGPathByteStream*); + explicit SVGPathByteStreamSource(const SVGPathByteStream&); private: - virtual bool hasMoreData() const override; - virtual bool moveToNextToken() override { return true; } - virtual bool parseSVGSegmentType(SVGPathSegType&) override; - virtual SVGPathSegType nextCommand(SVGPathSegType) override; - - virtual bool parseMoveToSegment(FloatPoint&) override; - virtual bool parseLineToSegment(FloatPoint&) override; - virtual bool parseLineToHorizontalSegment(float&) override; - virtual bool parseLineToVerticalSegment(float&) override; - virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&) override; - virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) override; + bool hasMoreData() const final; + bool moveToNextToken() final { return true; } + bool parseSVGSegmentType(SVGPathSegType&) final; + SVGPathSegType nextCommand(SVGPathSegType) final; + + bool parseMoveToSegment(FloatPoint&) final; + bool parseLineToSegment(FloatPoint&) final; + bool parseLineToHorizontalSegment(float&) final; + bool parseLineToVerticalSegment(float&) final; + bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) final; + bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) final; + bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) final; + bool parseCurveToQuadraticSmoothSegment(FloatPoint&) final; + bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) final; #if COMPILER(MSVC) #pragma warning(disable: 4701) @@ -92,6 +90,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathByteStreamSource_h diff --git a/Source/WebCore/svg/SVGPathConsumer.h b/Source/WebCore/svg/SVGPathConsumer.h index 18d3a45d1..9303031b6 100644 --- a/Source/WebCore/svg/SVGPathConsumer.h +++ b/Source/WebCore/svg/SVGPathConsumer.h @@ -2,7 +2,7 @@ * Copyright (C) 2002, 2003 The Karbon Developers * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -21,10 +21,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathConsumer_h -#define SVGPathConsumer_h +#pragma once -#if ENABLE(SVG) #include "FloatPoint.h" #include <wtf/FastMalloc.h> #include <wtf/Noncopyable.h> @@ -47,7 +45,6 @@ public: SVGPathConsumer() { } virtual void incrementPathSegmentCount() = 0; virtual bool continueConsuming() = 0; - virtual void cleanup() = 0; // Used in UnalteredParsing/NormalizedParsing modes. virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) = 0; @@ -68,6 +65,3 @@ protected: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathConsumer_h diff --git a/Source/WebCore/svg/SVGPathElement.cpp b/Source/WebCore/svg/SVGPathElement.cpp index 3f3a08f18..18d799d9f 100644 --- a/Source/WebCore/svg/SVGPathElement.cpp +++ b/Source/WebCore/svg/SVGPathElement.cpp @@ -19,14 +19,10 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathElement.h" -#include "Attribute.h" #include "RenderSVGPath.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGMPathElement.h" #include "SVGNames.h" #include "SVGPathSegArcAbs.h" @@ -47,19 +43,18 @@ #include "SVGPathSegLinetoVerticalAbs.h" #include "SVGPathSegLinetoVerticalRel.h" #include "SVGPathSegList.h" -#include "SVGPathSegListBuilder.h" -#include "SVGPathSegListPropertyTearOff.h" #include "SVGPathSegMovetoAbs.h" #include "SVGPathSegMovetoRel.h" #include "SVGPathUtilities.h" -#include "SVGSVGElement.h" +#include "SVGPoint.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { // Define custom animated property 'd'. const SVGPropertyInfo* SVGPathElement::dPropertyInfo() { - static const SVGPropertyInfo* s_propertyInfo = 0; + static const SVGPropertyInfo* s_propertyInfo = nullptr; if (!s_propertyInfo) { s_propertyInfo = new SVGPropertyInfo(AnimatedPath, PropertyIsReadWrite, @@ -84,173 +79,164 @@ END_REGISTER_ANIMATED_PROPERTIES inline SVGPathElement::SVGPathElement(const QualifiedName& tagName, Document& document) : SVGGraphicsElement(tagName, document) - , m_pathByteStream(std::make_unique<SVGPathByteStream>()) , m_pathSegList(PathSegUnalteredRole) + , m_weakPtrFactory(this) , m_isAnimValObserved(false) { ASSERT(hasTagName(SVGNames::pathTag)); registerAnimatedPropertiesForSVGPathElement(); } -PassRefPtr<SVGPathElement> SVGPathElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGPathElement> SVGPathElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGPathElement(tagName, document)); + return adoptRef(*new SVGPathElement(tagName, document)); } -float SVGPathElement::getTotalLength() +float SVGPathElement::getTotalLength() const { float totalLength = 0; getTotalLengthOfSVGPathByteStream(pathByteStream(), totalLength); return totalLength; } -SVGPoint SVGPathElement::getPointAtLength(float length) +Ref<SVGPoint> SVGPathElement::getPointAtLength(float length) const { - SVGPoint point; + FloatPoint point; getPointAtLengthOfSVGPathByteStream(pathByteStream(), length, point); - return point; + return SVGPoint::create(point); } -unsigned SVGPathElement::getPathSegAtLength(float length) +unsigned SVGPathElement::getPathSegAtLength(float length) const { unsigned pathSeg = 0; getSVGPathSegAtLengthFromSVGPathByteStream(pathByteStream(), length, pathSeg); return pathSeg; } -PassRefPtr<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath(SVGPathSegRole role) +Ref<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath(SVGPathSegRole role) { - return SVGPathSegClosePath::create(this, role); + return SVGPathSegClosePath::create(*this, role); } -PassRefPtr<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole role) +Ref<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole role) { - return SVGPathSegMovetoAbs::create(this, role, x, y); + return SVGPathSegMovetoAbs::create(*this, role, x, y); } -PassRefPtr<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole role) +Ref<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole role) { - return SVGPathSegMovetoRel::create(this, role, x, y); + return SVGPathSegMovetoRel::create(*this, role, x, y); } -PassRefPtr<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole role) +Ref<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole role) { - return SVGPathSegLinetoAbs::create(this, role, x, y); + return SVGPathSegLinetoAbs::create(*this, role, x, y); } -PassRefPtr<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole role) +Ref<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole role) { - return SVGPathSegLinetoRel::create(this, role, x, y); + return SVGPathSegLinetoRel::create(*this, role, x, y); } -PassRefPtr<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role) +Ref<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role) { - return SVGPathSegCurvetoCubicAbs::create(this, role, x, y, x1, y1, x2, y2); + return SVGPathSegCurvetoCubicAbs::create(*this, role, x, y, x1, y1, x2, y2); } -PassRefPtr<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role) +Ref<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role) { - return SVGPathSegCurvetoCubicRel::create(this, role, x, y, x1, y1, x2, y2); + return SVGPathSegCurvetoCubicRel::create(*this, role, x, y, x1, y1, x2, y2); } -PassRefPtr<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole role) +Ref<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole role) { - return SVGPathSegCurvetoQuadraticAbs::create(this, role, x, y, x1, y1); + return SVGPathSegCurvetoQuadraticAbs::create(*this, role, x, y, x1, y1); } -PassRefPtr<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole role) +Ref<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole role) { - return SVGPathSegCurvetoQuadraticRel::create(this, role, x, y, x1, y1); + return SVGPathSegCurvetoQuadraticRel::create(*this, role, x, y, x1, y1); } -PassRefPtr<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role) +Ref<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role) { - return SVGPathSegArcAbs::create(this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag); + return SVGPathSegArcAbs::create(*this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag); } -PassRefPtr<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role) +Ref<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role) { - return SVGPathSegArcRel::create(this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag); + return SVGPathSegArcRel::create(*this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag); } -PassRefPtr<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole role) +Ref<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole role) { - return SVGPathSegLinetoHorizontalAbs::create(this, role, x); + return SVGPathSegLinetoHorizontalAbs::create(*this, role, x); } -PassRefPtr<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole role) +Ref<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole role) { - return SVGPathSegLinetoHorizontalRel::create(this, role, x); + return SVGPathSegLinetoHorizontalRel::create(*this, role, x); } -PassRefPtr<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole role) +Ref<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole role) { - return SVGPathSegLinetoVerticalAbs::create(this, role, y); + return SVGPathSegLinetoVerticalAbs::create(*this, role, y); } -PassRefPtr<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole role) +Ref<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole role) { - return SVGPathSegLinetoVerticalRel::create(this, role, y); + return SVGPathSegLinetoVerticalRel::create(*this, role, y); } -PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole role) +Ref<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole role) { - return SVGPathSegCurvetoCubicSmoothAbs::create(this, role, x, y, x2, y2); + return SVGPathSegCurvetoCubicSmoothAbs::create(*this, role, x, y, x2, y2); } -PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole role) +Ref<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole role) { - return SVGPathSegCurvetoCubicSmoothRel::create(this, role, x, y, x2, y2); + return SVGPathSegCurvetoCubicSmoothRel::create(*this, role, x, y, x2, y2); } -PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole role) +Ref<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole role) { - return SVGPathSegCurvetoQuadraticSmoothAbs::create(this, role, x, y); + return SVGPathSegCurvetoQuadraticSmoothAbs::create(*this, role, x, y); } -PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole role) +Ref<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole role) { - return SVGPathSegCurvetoQuadraticSmoothRel::create(this, role, x, y); + return SVGPathSegCurvetoQuadraticSmoothRel::create(*this, role, x, y); } bool SVGPathElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::dAttr); - supportedAttributes.add(SVGNames::pathLengthAttr); + supportedAttributes.get().add(SVGNames::dAttr); + supportedAttributes.get().add(SVGNames::pathLengthAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGGraphicsElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::dAttr) { - if (!buildSVGPathByteStreamFromString(value, m_pathByteStream.get(), UnalteredParsing)) - document().accessSVGExtensions()->reportError("Problem parsing d=\"" + value + "\""); + if (!buildSVGPathByteStreamFromString(value, m_pathByteStream, UnalteredParsing)) + document().accessSVGExtensions().reportError("Problem parsing d=\"" + value + "\""); return; } if (name == SVGNames::pathLengthAttr) { setPathLengthBaseValue(value.toFloat()); if (pathLengthBaseValue() < 0) - document().accessSVGExtensions()->reportError("A negative value for path attribute <pathLength> is not allowed"); + document().accessSVGExtensions().reportError("A negative value for path attribute <pathLength> is not allowed"); return; } - if (SVGLangSpace::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName) @@ -260,14 +246,14 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); - RenderSVGPath* renderer = toRenderSVGPath(this->renderer()); + RenderSVGPath* renderer = downcast<RenderSVGPath>(this->renderer()); if (attrName == SVGNames::dAttr) { if (m_pathSegList.shouldSynchronize && !SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(this, dPropertyInfo())->isAnimating()) { - SVGPathSegList newList(PathSegUnalteredRole); - buildSVGPathSegListFromByteStream(m_pathByteStream.get(), this, newList, UnalteredParsing); + SVGPathSegListValues newList(PathSegUnalteredRole); + buildSVGPathSegListValuesFromByteStream(m_pathByteStream, *this, newList, UnalteredParsing); m_pathSegList.value = newList; } @@ -285,10 +271,10 @@ void SVGPathElement::invalidateMPathDependencies() { // <mpath> can only reference <path> but this dependency is not handled in // markForLayoutAndParentResourceInvalidation so we update any mpath dependencies manually. - if (HashSet<SVGElement*>* dependencies = document().accessSVGExtensions()->setOfElementsReferencingTarget(this)) { - for (auto element : *dependencies) { - if (element->hasTagName(SVGNames::mpathTag)) - toSVGMPathElement(element)->targetPathChanged(); + if (HashSet<SVGElement*>* dependencies = document().accessSVGExtensions().setOfElementsReferencingTarget(this)) { + for (auto* element : *dependencies) { + if (is<SVGMPathElement>(*element)) + downcast<SVGMPathElement>(*element).targetPathChanged(); } } } @@ -306,61 +292,82 @@ void SVGPathElement::removedFrom(ContainerNode& rootParent) invalidateMPathDependencies(); } -SVGPathByteStream* SVGPathElement::pathByteStream() const +const SVGPathByteStream& SVGPathElement::pathByteStream() const { - SVGAnimatedProperty* property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(this, dPropertyInfo()); + auto property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(this, dPropertyInfo()); if (!property || !property->isAnimating()) - return m_pathByteStream.get(); - return static_cast<SVGAnimatedPathSegListPropertyTearOff*>(property)->animatedPathByteStream(); + return m_pathByteStream; + + SVGPathByteStream* animatedPathByteStream = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(property.get())->animatedPathByteStream(); + if (!animatedPathByteStream) + return m_pathByteStream; + + return *animatedPathByteStream; } -PassRefPtr<SVGAnimatedProperty> SVGPathElement::lookupOrCreateDWrapper(SVGElement* contextElement) +Ref<SVGAnimatedProperty> SVGPathElement::lookupOrCreateDWrapper(SVGElement* contextElement) { ASSERT(contextElement); - SVGPathElement* ownerType = toSVGPathElement(contextElement); + SVGPathElement& ownerType = downcast<SVGPathElement>(*contextElement); - if (SVGAnimatedProperty* property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(ownerType, dPropertyInfo())) - return property; + if (auto property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(&ownerType, dPropertyInfo())) + return *property; - // Build initial SVGPathSegList. - buildSVGPathSegListFromByteStream(ownerType->m_pathByteStream.get(), ownerType, ownerType->m_pathSegList.value, UnalteredParsing); + if (ownerType.m_pathSegList.value.isEmpty()) + buildSVGPathSegListValuesFromByteStream(ownerType.m_pathByteStream, ownerType, ownerType.m_pathSegList.value, UnalteredParsing); - return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff, SVGPathSegList> - (ownerType, dPropertyInfo(), ownerType->m_pathSegList.value); + return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff, SVGPathSegListValues>(&ownerType, dPropertyInfo(), ownerType.m_pathSegList.value); } void SVGPathElement::synchronizeD(SVGElement* contextElement) { ASSERT(contextElement); - SVGPathElement* ownerType = toSVGPathElement(contextElement); - if (!ownerType->m_pathSegList.shouldSynchronize) + SVGPathElement& ownerType = downcast<SVGPathElement>(*contextElement); + if (!ownerType.m_pathSegList.shouldSynchronize) return; - ownerType->m_pathSegList.synchronize(ownerType, dPropertyInfo()->attributeName, ownerType->m_pathSegList.value.valueAsString()); + ownerType.m_pathSegList.synchronize(&ownerType, dPropertyInfo()->attributeName, ownerType.m_pathSegList.value.valueAsString()); +} + +void SVGPathElement::animatedPropertyWillBeDeleted() +{ + // m_pathSegList.shouldSynchronize is set to true when the 'd' wrapper for m_pathSegList + // is created and cached. We need to reset it back to false when this wrapper is deleted + // so we can be sure if shouldSynchronize is true, SVGAnimatedProperty::lookupWrapper() + // will return a valid cached 'd' wrapper for the m_pathSegList. + m_pathSegList.shouldSynchronize = false; } -SVGPathSegListPropertyTearOff* SVGPathElement::pathSegList() +Ref<SVGPathSegList> SVGPathElement::pathSegList() { m_pathSegList.shouldSynchronize = true; - return static_cast<SVGPathSegListPropertyTearOff*>(static_pointer_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->baseVal()); + return static_reference_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->baseVal(); } -SVGPathSegListPropertyTearOff* SVGPathElement::normalizedPathSegList() +RefPtr<SVGPathSegList> SVGPathElement::normalizedPathSegList() { // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists! - return 0; + return nullptr; } -SVGPathSegListPropertyTearOff* SVGPathElement::animatedPathSegList() +Ref<SVGPathSegList> SVGPathElement::animatedPathSegList() { m_pathSegList.shouldSynchronize = true; m_isAnimValObserved = true; - return static_cast<SVGPathSegListPropertyTearOff*>(static_pointer_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->animVal()); + return static_reference_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->animVal(); } -SVGPathSegListPropertyTearOff* SVGPathElement::animatedNormalizedPathSegList() +RefPtr<SVGPathSegList> SVGPathElement::animatedNormalizedPathSegList() { // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists! - return 0; + return nullptr; +} + +size_t SVGPathElement::approximateMemoryCost() const +{ + // This is an approximation for path memory cost since the path is parsed on demand. + size_t pathMemoryCost = (m_pathByteStream.size() / 10) * sizeof(FloatPoint); + // We need to account for the memory which is allocated by the RenderSVGPath::m_path. + return sizeof(*this) + (renderer() ? pathMemoryCost * 2 + sizeof(RenderSVGPath) : pathMemoryCost); } void SVGPathElement::pathSegListChanged(SVGPathSegRole role, ListModification listModification) @@ -372,9 +379,9 @@ void SVGPathElement::pathSegListChanged(SVGPathSegRole role, ListModification li case PathSegUnalteredRole: if (listModification == ListModificationAppend) { ASSERT(!m_pathSegList.value.isEmpty()); - appendSVGPathByteStreamFromSVGPathSeg(m_pathSegList.value.last(), m_pathByteStream.get(), UnalteredParsing); + appendSVGPathByteStreamFromSVGPathSeg(m_pathSegList.value.last().copyRef(), m_pathByteStream, UnalteredParsing); } else - buildSVGPathByteStreamFromSVGPathSegList(m_pathSegList.value, m_pathByteStream.get(), UnalteredParsing); + buildSVGPathByteStreamFromSVGPathSegListValues(m_pathSegList.value, m_pathByteStream, UnalteredParsing); break; case PathSegUndefinedRole: return; @@ -382,7 +389,7 @@ void SVGPathElement::pathSegListChanged(SVGPathSegRole role, ListModification li invalidateSVGAttributes(); - RenderSVGPath* renderer = toRenderSVGPath(this->renderer()); + RenderSVGPath* renderer = downcast<RenderSVGPath>(this->renderer()); if (!renderer) return; @@ -395,7 +402,7 @@ FloatRect SVGPathElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) if (styleUpdateStrategy == AllowStyleUpdate) document().updateLayoutIgnorePendingStylesheets(); - RenderSVGPath* renderer = toRenderSVGPath(this->renderer()); + RenderSVGPath* renderer = downcast<RenderSVGPath>(this->renderer()); // FIXME: Eventually we should support getBBox for detached elements. if (!renderer) @@ -404,12 +411,9 @@ FloatRect SVGPathElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) return renderer->path().boundingRect(); } -RenderPtr<RenderElement> SVGPathElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGPathElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - // By default, any subclass is expected to do path-based drawing - return createRenderer<RenderSVGPath>(*this, std::move(style)); + return createRenderer<RenderSVGPath>(*this, WTFMove(style)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathElement.h b/Source/WebCore/svg/SVGPathElement.h index bb66d01c1..3f47105b4 100644 --- a/Source/WebCore/svg/SVGPathElement.h +++ b/Source/WebCore/svg/SVGPathElement.h @@ -18,17 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathElement_h -#define SVGPathElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedNumber.h" #include "SVGExternalResourcesRequired.h" #include "SVGGraphicsElement.h" #include "SVGNames.h" #include "SVGPathByteStream.h" -#include "SVGPathSegList.h" +#include "SVGPathSegListValues.h" namespace WebCore { @@ -51,89 +49,91 @@ class SVGPathSegCurvetoCubicSmoothAbs; class SVGPathSegCurvetoCubicSmoothRel; class SVGPathSegCurvetoQuadraticSmoothAbs; class SVGPathSegCurvetoQuadraticSmoothRel; -class SVGPathSegListPropertyTearOff; +class SVGPathSegList; +class SVGPoint; class SVGPathElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGPathElement> create(const QualifiedName&, Document&); + static Ref<SVGPathElement> create(const QualifiedName&, Document&); - float getTotalLength(); - SVGPoint getPointAtLength(float distance); - unsigned getPathSegAtLength(float distance); - - PassRefPtr<SVGPathSegClosePath> createSVGPathSegClosePath(SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegMovetoAbs> createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegMovetoRel> createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegLinetoAbs> createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegLinetoRel> createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoCubicAbs> createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoCubicRel> createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoQuadraticAbs> createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoQuadraticRel> createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegArcAbs> createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegArcRel> createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegLinetoHorizontalAbs> createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegLinetoHorizontalRel> createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegLinetoVerticalAbs> createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegLinetoVerticalRel> createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole); - PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole); + float getTotalLength() const; + Ref<SVGPoint> getPointAtLength(float distance) const; + unsigned getPathSegAtLength(float distance) const; + + Ref<SVGPathSegClosePath> createSVGPathSegClosePath(SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegMovetoAbs> createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegMovetoRel> createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegLinetoAbs> createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegLinetoRel> createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoCubicAbs> createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoCubicRel> createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoQuadraticAbs> createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoQuadraticRel> createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegArcAbs> createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegArcRel> createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegLinetoHorizontalAbs> createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegLinetoHorizontalRel> createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegLinetoVerticalAbs> createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegLinetoVerticalRel> createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoCubicSmoothAbs> createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoCubicSmoothRel> createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoQuadraticSmoothAbs> createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole = PathSegUndefinedRole); + Ref<SVGPathSegCurvetoQuadraticSmoothRel> createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole = PathSegUndefinedRole); // Used in the bindings only. - SVGPathSegListPropertyTearOff* pathSegList(); - SVGPathSegListPropertyTearOff* animatedPathSegList(); - SVGPathSegListPropertyTearOff* normalizedPathSegList(); - SVGPathSegListPropertyTearOff* animatedNormalizedPathSegList(); + Ref<SVGPathSegList> pathSegList(); + Ref<SVGPathSegList> animatedPathSegList(); + RefPtr<SVGPathSegList> normalizedPathSegList(); + RefPtr<SVGPathSegList> animatedNormalizedPathSegList(); - SVGPathByteStream* pathByteStream() const; + const SVGPathByteStream& pathByteStream() const; void pathSegListChanged(SVGPathSegRole, ListModification = ListModificationUnknown); - virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) override; + FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) final; static const SVGPropertyInfo* dPropertyInfo(); bool isAnimValObserved() const { return m_isAnimValObserved; } + WeakPtr<SVGPathElement> createWeakPtr() const { return m_weakPtrFactory.createWeakPtr(); } + + void animatedPropertyWillBeDeleted(); + + size_t approximateMemoryCost() const final; + private: SVGPathElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual bool supportsMarkers() const override { return true; } + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; + bool supportsMarkers() const final { return true; } // Custom 'd' property static void synchronizeD(SVGElement* contextElement); - static PassRefPtr<SVGAnimatedProperty> lookupOrCreateDWrapper(SVGElement* contextElement); + static Ref<SVGAnimatedProperty> lookupOrCreateDWrapper(SVGElement* contextElement); BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPathElement) DECLARE_ANIMATED_NUMBER(PathLength, pathLength) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; - virtual Node::InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + Node::InsertionNotificationRequest insertedInto(ContainerNode&) final; + void removedFrom(ContainerNode&) final; void invalidateMPathDependencies(); private: - std::unique_ptr<SVGPathByteStream> m_pathByteStream; - mutable SVGSynchronizableAnimatedProperty<SVGPathSegList> m_pathSegList; + SVGPathByteStream m_pathByteStream; + mutable SVGSynchronizableAnimatedProperty<SVGPathSegListValues> m_pathSegList; + WeakPtrFactory<SVGPathElement> m_weakPtrFactory; bool m_isAnimValObserved; }; -NODE_TYPE_CASTS(SVGPathElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathElement.idl b/Source/WebCore/svg/SVGPathElement.idl index 4410533e1..b4df56377 100644 --- a/Source/WebCore/svg/SVGPathElement.idl +++ b/Source/WebCore/svg/SVGPathElement.idl @@ -24,83 +24,81 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGPathElement : SVGGraphicsElement { +interface SVGPathElement : SVGGraphicsElement { readonly attribute SVGAnimatedNumber pathLength; - float getTotalLength(); - SVGPoint getPointAtLength([Default=Undefined] optional float distance); - unsigned long getPathSegAtLength([Default=Undefined] optional float distance); + unrestricted float getTotalLength(); + [NewObject] SVGPoint getPointAtLength(optional unrestricted float distance = NaN); + unsigned long getPathSegAtLength(optional unrestricted float distance = NaN); SVGPathSegClosePath createSVGPathSegClosePath(); - SVGPathSegMovetoAbs createSVGPathSegMovetoAbs([Default=Undefined] optional float x, - [Default=Undefined] optional float y); - SVGPathSegMovetoRel createSVGPathSegMovetoRel([Default=Undefined] optional float x, - [Default=Undefined] optional float y); + SVGPathSegMovetoAbs createSVGPathSegMovetoAbs(optional unrestricted float x = NaN, + optional unrestricted float y = NaN); + SVGPathSegMovetoRel createSVGPathSegMovetoRel(optional unrestricted float x = NaN, + optional unrestricted float y = NaN); - SVGPathSegLinetoAbs createSVGPathSegLinetoAbs([Default=Undefined] optional float x, - [Default=Undefined] optional float y); - SVGPathSegLinetoRel createSVGPathSegLinetoRel([Default=Undefined] optional float x, - [Default=Undefined] optional float y); + SVGPathSegLinetoAbs createSVGPathSegLinetoAbs(optional unrestricted float x = NaN, + optional unrestricted float y = NaN); + SVGPathSegLinetoRel createSVGPathSegLinetoRel(optional unrestricted float x = NaN, + optional unrestricted float y = NaN); - SVGPathSegCurvetoCubicAbs createSVGPathSegCurvetoCubicAbs([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float x1, - [Default=Undefined] optional float y1, - [Default=Undefined] optional float x2, - [Default=Undefined] optional float y2); - SVGPathSegCurvetoCubicRel createSVGPathSegCurvetoCubicRel([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float x1, - [Default=Undefined] optional float y1, - [Default=Undefined] optional float x2, - [Default=Undefined] optional float y2); + SVGPathSegCurvetoCubicAbs createSVGPathSegCurvetoCubicAbs(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float x1 = NaN, + optional unrestricted float y1 = NaN, + optional unrestricted float x2 = NaN, + optional unrestricted float y2 = NaN); + SVGPathSegCurvetoCubicRel createSVGPathSegCurvetoCubicRel(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float x1 = NaN, + optional unrestricted float y1 = NaN, + optional unrestricted float x2 = NaN, + optional unrestricted float y2 = NaN); - SVGPathSegCurvetoQuadraticAbs createSVGPathSegCurvetoQuadraticAbs([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float x1, - [Default=Undefined] optional float y1); - SVGPathSegCurvetoQuadraticRel createSVGPathSegCurvetoQuadraticRel([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float x1, - [Default=Undefined] optional float y1); + SVGPathSegCurvetoQuadraticAbs createSVGPathSegCurvetoQuadraticAbs(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float x1 = NaN, + optional unrestricted float y1 = NaN); + SVGPathSegCurvetoQuadraticRel createSVGPathSegCurvetoQuadraticRel(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float x1 = NaN, + optional unrestricted float y1 = NaN); - SVGPathSegArcAbs createSVGPathSegArcAbs([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float r1, - [Default=Undefined] optional float r2, - [Default=Undefined] optional float angle, - [Default=Undefined] optional boolean largeArcFlag, - [Default=Undefined] optional boolean sweepFlag); - SVGPathSegArcRel createSVGPathSegArcRel([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float r1, - [Default=Undefined] optional float r2, - [Default=Undefined] optional float angle, - [Default=Undefined] optional boolean largeArcFlag, - [Default=Undefined] optional boolean sweepFlag); + SVGPathSegArcAbs createSVGPathSegArcAbs(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float r1 = NaN, + optional unrestricted float r2 = NaN, + optional unrestricted float angle = NaN, + optional boolean largeArcFlag = false, + optional boolean sweepFlag = false); + SVGPathSegArcRel createSVGPathSegArcRel(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float r1 = NaN, + optional unrestricted float r2 = NaN, + optional unrestricted float angle = NaN, + optional boolean largeArcFlag = false, + optional boolean sweepFlag = false); - SVGPathSegLinetoHorizontalAbs createSVGPathSegLinetoHorizontalAbs([Default=Undefined] optional float x); - SVGPathSegLinetoHorizontalRel createSVGPathSegLinetoHorizontalRel([Default=Undefined] optional float x); + SVGPathSegLinetoHorizontalAbs createSVGPathSegLinetoHorizontalAbs(optional unrestricted float x = NaN); + SVGPathSegLinetoHorizontalRel createSVGPathSegLinetoHorizontalRel(optional unrestricted float x = NaN); - SVGPathSegLinetoVerticalAbs createSVGPathSegLinetoVerticalAbs([Default=Undefined] optional float y); - SVGPathSegLinetoVerticalRel createSVGPathSegLinetoVerticalRel([Default=Undefined] optional float y); + SVGPathSegLinetoVerticalAbs createSVGPathSegLinetoVerticalAbs(optional unrestricted float y = NaN); + SVGPathSegLinetoVerticalRel createSVGPathSegLinetoVerticalRel(optional unrestricted float y = NaN); - SVGPathSegCurvetoCubicSmoothAbs createSVGPathSegCurvetoCubicSmoothAbs([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float x2, - [Default=Undefined] optional float y2); - SVGPathSegCurvetoCubicSmoothRel createSVGPathSegCurvetoCubicSmoothRel([Default=Undefined] optional float x, - [Default=Undefined] optional float y, - [Default=Undefined] optional float x2, - [Default=Undefined] optional float y2); + SVGPathSegCurvetoCubicSmoothAbs createSVGPathSegCurvetoCubicSmoothAbs(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float x2 = NaN, + optional unrestricted float y2 = NaN); + SVGPathSegCurvetoCubicSmoothRel createSVGPathSegCurvetoCubicSmoothRel(optional unrestricted float x = NaN, + optional unrestricted float y = NaN, + optional unrestricted float x2 = NaN, + optional unrestricted float y2 = NaN); - SVGPathSegCurvetoQuadraticSmoothAbs createSVGPathSegCurvetoQuadraticSmoothAbs([Default=Undefined] optional float x, - [Default=Undefined] optional float y); - SVGPathSegCurvetoQuadraticSmoothRel createSVGPathSegCurvetoQuadraticSmoothRel([Default=Undefined] optional float x, - [Default=Undefined] optional float y); + SVGPathSegCurvetoQuadraticSmoothAbs createSVGPathSegCurvetoQuadraticSmoothAbs(optional unrestricted float x = NaN, + optional unrestricted float y = NaN); + SVGPathSegCurvetoQuadraticSmoothRel createSVGPathSegCurvetoQuadraticSmoothRel(optional unrestricted float x = NaN, + optional unrestricted float y = NaN); readonly attribute SVGPathSegList pathSegList; readonly attribute SVGPathSegList normalizedPathSegList; diff --git a/Source/WebCore/svg/SVGPathParser.cpp b/Source/WebCore/svg/SVGPathParser.cpp index 9f465eeab..9997ee968 100644 --- a/Source/WebCore/svg/SVGPathParser.cpp +++ b/Source/WebCore/svg/SVGPathParser.cpp @@ -2,7 +2,7 @@ * Copyright (C) 2002, 2003 The Karbon Developers * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -22,20 +22,43 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathParser.h" #include "AffineTransform.h" +#include "SVGPathByteStreamBuilder.h" #include "SVGPathSource.h" +#include "SVGPathStringBuilder.h" #include <wtf/MathExtras.h> static const float gOneOverThree = 1 / 3.f; namespace WebCore { -SVGPathParser::SVGPathParser() - : m_consumer(0) +bool SVGPathParser::parse(SVGPathSource& source, SVGPathConsumer& consumer, PathParsingMode mode, bool checkForInitialMoveTo) +{ + SVGPathParser parser(consumer, source, mode); + return parser.parsePathData(checkForInitialMoveTo); +} + +bool SVGPathParser::parseToByteStream(SVGPathSource& source, SVGPathByteStream& byteStream, PathParsingMode mode, bool checkForInitialMoveTo) +{ + SVGPathByteStreamBuilder builder(byteStream); + return parse(source, builder, mode, checkForInitialMoveTo); +} + +bool SVGPathParser::parseToString(SVGPathSource& source, String& result, PathParsingMode mode, bool checkForInitialMoveTo) +{ + SVGPathStringBuilder builder; + SVGPathParser parser(builder, source, mode); + bool ok = parser.parsePathData(checkForInitialMoveTo); + result = builder.result(); + return ok; +} + +SVGPathParser::SVGPathParser(SVGPathConsumer& consumer, SVGPathSource& source, PathParsingMode parsingMode) + : m_source(source) + , m_consumer(consumer) + , m_pathParsingMode(parsingMode) { } @@ -45,13 +68,13 @@ void SVGPathParser::parseClosePathSegment() if (m_pathParsingMode == NormalizedParsing) m_currentPoint = m_subPathPoint; m_closePath = true; - m_consumer->closePath(); + m_consumer.closePath(); } bool SVGPathParser::parseMoveToSegment() { FloatPoint targetPoint; - if (!m_source->parseMoveToSegment(targetPoint)) + if (!m_source.parseMoveToSegment(targetPoint)) return false; if (m_pathParsingMode == NormalizedParsing) { @@ -60,9 +83,9 @@ bool SVGPathParser::parseMoveToSegment() else m_currentPoint = targetPoint; m_subPathPoint = m_currentPoint; - m_consumer->moveTo(m_currentPoint, m_closePath, AbsoluteCoordinates); + m_consumer.moveTo(m_currentPoint, m_closePath, AbsoluteCoordinates); } else - m_consumer->moveTo(targetPoint, m_closePath, m_mode); + m_consumer.moveTo(targetPoint, m_closePath, m_mode); m_closePath = false; return true; } @@ -70,7 +93,7 @@ bool SVGPathParser::parseMoveToSegment() bool SVGPathParser::parseLineToSegment() { FloatPoint targetPoint; - if (!m_source->parseLineToSegment(targetPoint)) + if (!m_source.parseLineToSegment(targetPoint)) return false; if (m_pathParsingMode == NormalizedParsing) { @@ -78,16 +101,16 @@ bool SVGPathParser::parseLineToSegment() m_currentPoint += targetPoint; else m_currentPoint = targetPoint; - m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates); + m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates); } else - m_consumer->lineTo(targetPoint, m_mode); + m_consumer.lineTo(targetPoint, m_mode); return true; } bool SVGPathParser::parseLineToHorizontalSegment() { float toX; - if (!m_source->parseLineToHorizontalSegment(toX)) + if (!m_source.parseLineToHorizontalSegment(toX)) return false; if (m_pathParsingMode == NormalizedParsing) { @@ -95,16 +118,16 @@ bool SVGPathParser::parseLineToHorizontalSegment() m_currentPoint.move(toX, 0); else m_currentPoint.setX(toX); - m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates); + m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates); } else - m_consumer->lineToHorizontal(toX, m_mode); + m_consumer.lineToHorizontal(toX, m_mode); return true; } bool SVGPathParser::parseLineToVerticalSegment() { float toY; - if (!m_source->parseLineToVerticalSegment(toY)) + if (!m_source.parseLineToVerticalSegment(toY)) return false; if (m_pathParsingMode == NormalizedParsing) { @@ -112,9 +135,9 @@ bool SVGPathParser::parseLineToVerticalSegment() m_currentPoint.move(0, toY); else m_currentPoint.setY(toY); - m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates); + m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates); } else - m_consumer->lineToVertical(toY, m_mode); + m_consumer.lineToVertical(toY, m_mode); return true; } @@ -123,7 +146,7 @@ bool SVGPathParser::parseCurveToCubicSegment() FloatPoint point1; FloatPoint point2; FloatPoint targetPoint; - if (!m_source->parseCurveToCubicSegment(point1, point2, targetPoint)) + if (!m_source.parseCurveToCubicSegment(point1, point2, targetPoint)) return false; if (m_pathParsingMode == NormalizedParsing) { @@ -132,12 +155,12 @@ bool SVGPathParser::parseCurveToCubicSegment() point2 += m_currentPoint; targetPoint += m_currentPoint; } - m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); + m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); m_controlPoint = point2; m_currentPoint = targetPoint; } else - m_consumer->curveToCubic(point1, point2, targetPoint, m_mode); + m_consumer.curveToCubic(point1, point2, targetPoint, m_mode); return true; } @@ -145,7 +168,7 @@ bool SVGPathParser::parseCurveToCubicSmoothSegment() { FloatPoint point2; FloatPoint targetPoint; - if (!m_source->parseCurveToCubicSmoothSegment(point2, targetPoint)) + if (!m_source.parseCurveToCubicSmoothSegment(point2, targetPoint)) return false; if (m_lastCommand != PathSegCurveToCubicAbs @@ -156,19 +179,19 @@ bool SVGPathParser::parseCurveToCubicSmoothSegment() if (m_pathParsingMode == NormalizedParsing) { FloatPoint point1 = m_currentPoint; - point1.scale(2, 2); + point1.scale(2); point1.move(-m_controlPoint.x(), -m_controlPoint.y()); if (m_mode == RelativeCoordinates) { point2 += m_currentPoint; targetPoint += m_currentPoint; } - m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); + m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); m_controlPoint = point2; m_currentPoint = targetPoint; } else - m_consumer->curveToCubicSmooth(point2, targetPoint, m_mode); + m_consumer.curveToCubicSmooth(point2, targetPoint, m_mode); return true; } @@ -176,7 +199,7 @@ bool SVGPathParser::parseCurveToQuadraticSegment() { FloatPoint point1; FloatPoint targetPoint; - if (!m_source->parseCurveToQuadraticSegment(point1, targetPoint)) + if (!m_source.parseCurveToQuadraticSegment(point1, targetPoint)) return false; if (m_pathParsingMode == NormalizedParsing) { @@ -189,23 +212,23 @@ bool SVGPathParser::parseCurveToQuadraticSegment() point2.move(3 * m_currentPoint.x(), 3 * m_currentPoint.y()); targetPoint += m_currentPoint; } - point1.scale(gOneOverThree, gOneOverThree); - point2.scale(gOneOverThree, gOneOverThree); + point1.scale(gOneOverThree); + point2.scale(gOneOverThree); - m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); + m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); if (m_mode == RelativeCoordinates) m_controlPoint += m_currentPoint; m_currentPoint = targetPoint; } else - m_consumer->curveToQuadratic(point1, targetPoint, m_mode); + m_consumer.curveToQuadratic(point1, targetPoint, m_mode); return true; } bool SVGPathParser::parseCurveToQuadraticSmoothSegment() { FloatPoint targetPoint; - if (!m_source->parseCurveToQuadraticSmoothSegment(targetPoint)) + if (!m_source.parseCurveToQuadraticSmoothSegment(targetPoint)) return false; if (m_lastCommand != PathSegCurveToQuadraticAbs @@ -216,7 +239,7 @@ bool SVGPathParser::parseCurveToQuadraticSmoothSegment() if (m_pathParsingMode == NormalizedParsing) { FloatPoint cubicPoint = m_currentPoint; - cubicPoint.scale(2, 2); + cubicPoint.scale(2); cubicPoint.move(-m_controlPoint.x(), -m_controlPoint.y()); FloatPoint point1(m_currentPoint.x() + 2 * cubicPoint.x(), m_currentPoint.y() + 2 * cubicPoint.y()); FloatPoint point2(targetPoint.x() + 2 * cubicPoint.x(), targetPoint.y() + 2 * cubicPoint.y()); @@ -224,15 +247,15 @@ bool SVGPathParser::parseCurveToQuadraticSmoothSegment() point2 += m_currentPoint; targetPoint += m_currentPoint; } - point1.scale(gOneOverThree, gOneOverThree); - point2.scale(gOneOverThree, gOneOverThree); + point1.scale(gOneOverThree); + point2.scale(gOneOverThree); - m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); + m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates); m_controlPoint = cubicPoint; m_currentPoint = targetPoint; } else - m_consumer->curveToQuadraticSmooth(targetPoint, m_mode); + m_consumer.curveToQuadraticSmooth(targetPoint, m_mode); return true; } @@ -244,7 +267,7 @@ bool SVGPathParser::parseArcToSegment() bool largeArc; bool sweep; FloatPoint targetPoint; - if (!m_source->parseArcToSegment(rx, ry, angle, largeArc, sweep, targetPoint)) + if (!m_source.parseArcToSegment(rx, ry, angle, largeArc, sweep, targetPoint)) return false; // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a "lineto") joining the endpoints. @@ -266,9 +289,9 @@ bool SVGPathParser::parseArcToSegment() m_currentPoint += targetPoint; else m_currentPoint = targetPoint; - m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates); + m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates); } else - m_consumer->lineTo(targetPoint, m_mode); + m_consumer.lineTo(targetPoint, m_mode); return true; } @@ -279,29 +302,18 @@ bool SVGPathParser::parseArcToSegment() m_currentPoint = targetPoint; return decomposeArcToCubic(angle, rx, ry, point1, targetPoint, largeArc, sweep); } - m_consumer->arcTo(rx, ry, angle, largeArc, sweep, targetPoint, m_mode); + m_consumer.arcTo(rx, ry, angle, largeArc, sweep, targetPoint, m_mode); return true; } -bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, bool checkForInitialMoveTo) +bool SVGPathParser::parsePathData(bool checkForInitialMoveTo) { - ASSERT(m_source); - ASSERT(m_consumer); - - m_pathParsingMode = pathParsingMode; - - m_controlPoint = FloatPoint(); - m_currentPoint = FloatPoint(); - m_subPathPoint = FloatPoint(); - m_closePath = true; - // Skip any leading spaces. - if (!m_source->moveToNextToken()) + if (!m_source.moveToNextToken()) return true; SVGPathSegType command; - m_source->parseSVGSegmentType(command); - m_lastCommand = PathSegUnknown; + m_source.parseSVGSegmentType(command); // Path must start with moveto. if (checkForInitialMoveTo && command != PathSegMoveToAbs && command != PathSegMoveToRel) @@ -309,7 +321,7 @@ bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo while (true) { // Skip spaces between command and first coordinate. - m_source->moveToNextToken(); + m_source.moveToNextToken(); m_mode = AbsoluteCoordinates; switch (command) { case PathSegMoveToRel: @@ -381,15 +393,15 @@ bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo default: return false; } - if (!m_consumer->continueConsuming()) + if (!m_consumer.continueConsuming()) return true; m_lastCommand = command; - if (!m_source->hasMoreData()) + if (!m_source.hasMoreData()) return true; - command = m_source->nextCommand(command); + command = m_source.nextCommand(command); if (m_lastCommand != PathSegCurveToCubicAbs && m_lastCommand != PathSegCurveToCubicRel @@ -401,22 +413,12 @@ bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo && m_lastCommand != PathSegCurveToQuadraticSmoothRel) m_controlPoint = m_currentPoint; - m_consumer->incrementPathSegmentCount(); + m_consumer.incrementPathSegmentCount(); } return false; } -void SVGPathParser::cleanup() -{ - ASSERT(m_source); - ASSERT(m_consumer); - - m_consumer->cleanup(); - m_source = 0; - m_consumer = 0; -} - // This works by converting the SVG arc to "simple" beziers. // Partly adapted from Niko's code in kdelibs/kdecore/svgicons. // See also SVG implementation notes: http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter @@ -459,7 +461,7 @@ bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, FloatPo delta.scale(scaleFactor); FloatPoint centerPoint = point1 + point2; - centerPoint.scale(0.5f, 0.5f); + centerPoint.scale(0.5f); centerPoint.move(-delta.height(), delta.width()); float theta1 = FloatPoint(point1 - centerPoint).slopeAngleRadians(); @@ -497,12 +499,10 @@ bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, FloatPo point2 = targetPoint; point2.move(t * sinEndTheta, -t * cosEndTheta); - m_consumer->curveToCubic(pointTransform.mapPoint(point1), pointTransform.mapPoint(point2), + m_consumer.curveToCubic(pointTransform.mapPoint(point1), pointTransform.mapPoint(point2), pointTransform.mapPoint(targetPoint), AbsoluteCoordinates); } return true; } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathParser.h b/Source/WebCore/svg/SVGPathParser.h index 65f4bd851..b28daf78b 100644 --- a/Source/WebCore/svg/SVGPathParser.h +++ b/Source/WebCore/svg/SVGPathParser.h @@ -2,7 +2,7 @@ * Copyright (C) 2002, 2003 The Karbon Developers * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -21,30 +21,29 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathParser_h -#define SVGPathParser_h +#pragma once -#if ENABLE(SVG) #include "SVGPathConsumer.h" #include "SVGPathSeg.h" #include <wtf/text/WTFString.h> namespace WebCore { +class SVGPathByteStream; class SVGPathSource; class SVGPathParser { - WTF_MAKE_NONCOPYABLE(SVGPathParser); WTF_MAKE_FAST_ALLOCATED; public: - SVGPathParser(); + static bool parse(SVGPathSource&, SVGPathConsumer&, PathParsingMode = NormalizedParsing, bool checkForInitialMoveTo = true); - bool parsePathDataFromSource(PathParsingMode, bool checkForInitialMoveTo = true); - void setCurrentConsumer(SVGPathConsumer* consumer) { m_consumer = consumer; } - void setCurrentSource(SVGPathSource* source) { m_source = source; } - void cleanup(); + static bool parseToByteStream(SVGPathSource&, SVGPathByteStream&, PathParsingMode = NormalizedParsing, bool checkForInitialMoveTo = true); + static bool parseToString(SVGPathSource&, String& result, PathParsingMode = NormalizedParsing, bool checkForInitialMoveTo = true); private: - bool decomposeArcToCubic(float, float, float, FloatPoint&, FloatPoint&, bool largeArcFlag, bool sweepFlag); + SVGPathParser(SVGPathConsumer&, SVGPathSource&, PathParsingMode); + bool parsePathData(bool checkForInitialMoveTo); + + bool decomposeArcToCubic(float angle, float rx, float ry, FloatPoint&, FloatPoint&, bool largeArcFlag, bool sweepFlag); void parseClosePathSegment(); bool parseMoveToSegment(); bool parseLineToSegment(); @@ -56,18 +55,15 @@ private: bool parseCurveToQuadraticSmoothSegment(); bool parseArcToSegment(); - SVGPathSource* m_source; - SVGPathConsumer* m_consumer; - PathCoordinateMode m_mode; - PathParsingMode m_pathParsingMode; - SVGPathSegType m_lastCommand; - bool m_closePath; + SVGPathSource& m_source; + SVGPathConsumer& m_consumer; FloatPoint m_controlPoint; FloatPoint m_currentPoint; FloatPoint m_subPathPoint; + PathCoordinateMode m_mode { AbsoluteCoordinates }; + const PathParsingMode m_pathParsingMode { NormalizedParsing }; + SVGPathSegType m_lastCommand { PathSegUnknown }; + bool m_closePath { true }; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathParser_h diff --git a/Source/WebCore/svg/SVGPathSeg.h b/Source/WebCore/svg/SVGPathSeg.h index 09f500c5b..dd02caa04 100644 --- a/Source/WebCore/svg/SVGPathSeg.h +++ b/Source/WebCore/svg/SVGPathSeg.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSeg_h -#define SVGPathSeg_h +#pragma once -#if ENABLE(SVG) #include <wtf/RefCounted.h> #include <wtf/text/WTFString.h> @@ -90,6 +88,3 @@ public: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSeg.idl b/Source/WebCore/svg/SVGPathSeg.idl index e277b37a5..2d909417d 100644 --- a/Source/WebCore/svg/SVGPathSeg.idl +++ b/Source/WebCore/svg/SVGPathSeg.idl @@ -25,12 +25,9 @@ */ [ - Conditional=SVG, CustomToJSObject, - ObjCPolymorphic, ImplementationLacksVTable ] interface SVGPathSeg { - // Path Segment Types const unsigned short PATHSEG_UNKNOWN = 0; const unsigned short PATHSEG_CLOSEPATH = 1; const unsigned short PATHSEG_MOVETO_ABS = 2; @@ -55,4 +52,3 @@ readonly attribute unsigned short pathSegType; readonly attribute DOMString pathSegTypeAsLetter; }; - diff --git a/Source/WebCore/svg/SVGPathSegArc.h b/Source/WebCore/svg/SVGPathSegArc.h index f21812996..a99b2a800 100644 --- a/Source/WebCore/svg/SVGPathSegArc.h +++ b/Source/WebCore/svg/SVGPathSegArc.h @@ -18,17 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegArc_h -#define SVGPathSegArc_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { class SVGPathSegArc : public SVGPathSegWithContext { public: - SVGPathSegArc(SVGPathElement* element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + SVGPathSegArc(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) : SVGPathSegWithContext(element, role) , m_x(x) , m_y(y) @@ -101,6 +99,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegArcAbs.h b/Source/WebCore/svg/SVGPathSegArcAbs.h index a7d5aed32..a3f755ece 100644 --- a/Source/WebCore/svg/SVGPathSegArcAbs.h +++ b/Source/WebCore/svg/SVGPathSegArcAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegArcAbs_h -#define SVGPathSegArcAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegArc.h" namespace WebCore { -class SVGPathSegArcAbs : public SVGPathSegArc { +class SVGPathSegArcAbs final : public SVGPathSegArc { public: - static PassRefPtr<SVGPathSegArcAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + static Ref<SVGPathSegArcAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) { - return adoptRef(new SVGPathSegArcAbs(element, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag)); + return adoptRef(*new SVGPathSegArcAbs(element, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag)); } private: - SVGPathSegArcAbs(SVGPathElement* element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + SVGPathSegArcAbs(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) : SVGPathSegArc(element, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { } - virtual unsigned short pathSegType() const override { return PATHSEG_ARC_ABS; } - virtual String pathSegTypeAsLetter() const override { return "A"; } + unsigned short pathSegType() const final { return PATHSEG_ARC_ABS; } + String pathSegTypeAsLetter() const final { return "A"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegArcAbs.idl b/Source/WebCore/svg/SVGPathSegArcAbs.idl index fe8fb52ae..784678d67 100644 --- a/Source/WebCore/svg/SVGPathSegArcAbs.idl +++ b/Source/WebCore/svg/SVGPathSegArcAbs.idl @@ -24,15 +24,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegArcAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float r1; - [StrictTypeChecking] attribute float r2; - [StrictTypeChecking] attribute float angle; - [StrictTypeChecking] attribute boolean largeArcFlag; - [StrictTypeChecking] attribute boolean sweepFlag; +interface SVGPathSegArcAbs : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float r1; + attribute unrestricted float r2; + attribute unrestricted float angle; + attribute boolean largeArcFlag; + attribute boolean sweepFlag; }; diff --git a/Source/WebCore/svg/SVGPathSegArcRel.h b/Source/WebCore/svg/SVGPathSegArcRel.h index 82bb0922b..5feec6799 100644 --- a/Source/WebCore/svg/SVGPathSegArcRel.h +++ b/Source/WebCore/svg/SVGPathSegArcRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegArcRel_h -#define SVGPathSegArcRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegArc.h" namespace WebCore { -class SVGPathSegArcRel : public SVGPathSegArc { +class SVGPathSegArcRel final : public SVGPathSegArc { public: - static PassRefPtr<SVGPathSegArcRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + static Ref<SVGPathSegArcRel> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) { - return adoptRef(new SVGPathSegArcRel(element, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag)); + return adoptRef(*new SVGPathSegArcRel(element, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag)); } private: - SVGPathSegArcRel(SVGPathElement* element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + SVGPathSegArcRel(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) : SVGPathSegArc(element, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag) { } - virtual unsigned short pathSegType() const override { return PATHSEG_ARC_REL; } - virtual String pathSegTypeAsLetter() const override { return "a"; } + unsigned short pathSegType() const final { return PATHSEG_ARC_REL; } + String pathSegTypeAsLetter() const final { return "a"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegArcRel.idl b/Source/WebCore/svg/SVGPathSegArcRel.idl index 3946d8d6e..86fd3b2e8 100644 --- a/Source/WebCore/svg/SVGPathSegArcRel.idl +++ b/Source/WebCore/svg/SVGPathSegArcRel.idl @@ -24,15 +24,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegArcRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float r1; - [StrictTypeChecking] attribute float r2; - [StrictTypeChecking] attribute float angle; - [StrictTypeChecking] attribute boolean largeArcFlag; - [StrictTypeChecking] attribute boolean sweepFlag; +interface SVGPathSegArcRel : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float r1; + attribute unrestricted float r2; + attribute unrestricted float angle; + attribute boolean largeArcFlag; + attribute boolean sweepFlag; }; diff --git a/Source/WebCore/svg/SVGPathSegClosePath.h b/Source/WebCore/svg/SVGPathSegClosePath.h index 347b019f8..917d72b68 100644 --- a/Source/WebCore/svg/SVGPathSegClosePath.h +++ b/Source/WebCore/svg/SVGPathSegClosePath.h @@ -18,32 +18,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegClosePath_h -#define SVGPathSegClosePath_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { -class SVGPathSegClosePath : public SVGPathSegWithContext { +class SVGPathSegClosePath final : public SVGPathSegWithContext { public: - static PassRefPtr<SVGPathSegClosePath> create(SVGPathElement* element, SVGPathSegRole role) + static Ref<SVGPathSegClosePath> create(const SVGPathElement& element, SVGPathSegRole role) { - return adoptRef(new SVGPathSegClosePath(element, role)); + return adoptRef(*new SVGPathSegClosePath(element, role)); } private: - SVGPathSegClosePath(SVGPathElement* element, SVGPathSegRole role) + SVGPathSegClosePath(const SVGPathElement& element, SVGPathSegRole role) : SVGPathSegWithContext(element, role) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CLOSEPATH; } - virtual String pathSegTypeAsLetter() const override { return "Z"; } + unsigned short pathSegType() const final { return PATHSEG_CLOSEPATH; } + String pathSegTypeAsLetter() const final { return "Z"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegClosePath.idl b/Source/WebCore/svg/SVGPathSegClosePath.idl index 3f0969a4d..f3eff1e8d 100644 --- a/Source/WebCore/svg/SVGPathSegClosePath.idl +++ b/Source/WebCore/svg/SVGPathSegClosePath.idl @@ -24,8 +24,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegClosePath : SVGPathSeg { +interface SVGPathSegClosePath : SVGPathSeg { }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubic.h b/Source/WebCore/svg/SVGPathSegCurvetoCubic.h index bf8a40c22..d6b853cf2 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubic.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubic.h @@ -18,17 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoCubic_h -#define SVGPathSegCurvetoCubic_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { class SVGPathSegCurvetoCubic : public SVGPathSegWithContext { public: - SVGPathSegCurvetoCubic(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) + SVGPathSegCurvetoCubic(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) : SVGPathSegWithContext(element, role) , m_x(x) , m_y(y) @@ -91,6 +89,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.h b/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.h index a1de02b36..d4ff54c12 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoCubicAbs_h -#define SVGPathSegCurvetoCubicAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegCurvetoCubic.h" namespace WebCore { -class SVGPathSegCurvetoCubicAbs : public SVGPathSegCurvetoCubic { +class SVGPathSegCurvetoCubicAbs final : public SVGPathSegCurvetoCubic { public: - static PassRefPtr<SVGPathSegCurvetoCubicAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) + static Ref<SVGPathSegCurvetoCubicAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) { - return adoptRef(new SVGPathSegCurvetoCubicAbs(element, role, x, y, x1, y1, x2, y2)); + return adoptRef(*new SVGPathSegCurvetoCubicAbs(element, role, x, y, x1, y1, x2, y2)); } private: - SVGPathSegCurvetoCubicAbs(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) + SVGPathSegCurvetoCubicAbs(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) : SVGPathSegCurvetoCubic(element, role, x, y, x1, y1, x2, y2) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_CUBIC_ABS; } - virtual String pathSegTypeAsLetter() const override { return "C"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_CUBIC_ABS; } + String pathSegTypeAsLetter() const final { return "C"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.idl b/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.idl index c8c7c82e9..26dbea528 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicAbs.idl @@ -24,14 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoCubicAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float x1; - [StrictTypeChecking] attribute float y1; - [StrictTypeChecking] attribute float x2; - [StrictTypeChecking] attribute float y2; +interface SVGPathSegCurvetoCubicAbs : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float x1; + attribute unrestricted float y1; + attribute unrestricted float x2; + attribute unrestricted float y2; }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.h b/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.h index 042b172a9..78a2d4129 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoCubicRel_h -#define SVGPathSegCurvetoCubicRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegCurvetoCubic.h" namespace WebCore { -class SVGPathSegCurvetoCubicRel : public SVGPathSegCurvetoCubic { +class SVGPathSegCurvetoCubicRel final : public SVGPathSegCurvetoCubic { public: - static PassRefPtr<SVGPathSegCurvetoCubicRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) + static Ref<SVGPathSegCurvetoCubicRel> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) { - return adoptRef(new SVGPathSegCurvetoCubicRel(element, role, x, y, x1, y1, x2, y2)); + return adoptRef(*new SVGPathSegCurvetoCubicRel(element, role, x, y, x1, y1, x2, y2)); } private: - SVGPathSegCurvetoCubicRel(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) + SVGPathSegCurvetoCubicRel(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2) : SVGPathSegCurvetoCubic(element, role, x, y, x1, y1, x2, y2) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_CUBIC_REL; } - virtual String pathSegTypeAsLetter() const override { return "c"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_CUBIC_REL; } + String pathSegTypeAsLetter() const final { return "c"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.idl b/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.idl index f4336b2be..7eb0414bf 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicRel.idl @@ -24,14 +24,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoCubicRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float x1; - [StrictTypeChecking] attribute float y1; - [StrictTypeChecking] attribute float x2; - [StrictTypeChecking] attribute float y2; +interface SVGPathSegCurvetoCubicRel : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float x1; + attribute unrestricted float y1; + attribute unrestricted float x2; + attribute unrestricted float y2; }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h index 8a67a5de1..4e6053280 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h @@ -18,17 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoCubicSmooth_h -#define SVGPathSegCurvetoCubicSmooth_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { class SVGPathSegCurvetoCubicSmooth : public SVGPathSegWithContext { public: - SVGPathSegCurvetoCubicSmooth(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x2, float y2) + SVGPathSegCurvetoCubicSmooth(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x2, float y2) : SVGPathSegWithContext(element, role) , m_x(x) , m_y(y) @@ -73,6 +71,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.h b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.h index 9bcb2e5e7..98dd74c34 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoCubicSmoothAbs_h -#define SVGPathSegCurvetoCubicSmoothAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegCurvetoCubicSmooth.h" namespace WebCore { -class SVGPathSegCurvetoCubicSmoothAbs : public SVGPathSegCurvetoCubicSmooth { +class SVGPathSegCurvetoCubicSmoothAbs final : public SVGPathSegCurvetoCubicSmooth { public: - static PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x2, float y2) + static Ref<SVGPathSegCurvetoCubicSmoothAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x2, float y2) { - return adoptRef(new SVGPathSegCurvetoCubicSmoothAbs(element, role, x, y, x2, y2)); + return adoptRef(*new SVGPathSegCurvetoCubicSmoothAbs(element, role, x, y, x2, y2)); } private: - SVGPathSegCurvetoCubicSmoothAbs(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x2, float y2) + SVGPathSegCurvetoCubicSmoothAbs(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x2, float y2) : SVGPathSegCurvetoCubicSmooth(element, role, x, y, x2, y2) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; } - virtual String pathSegTypeAsLetter() const override { return "S"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; } + String pathSegTypeAsLetter() const final { return "S"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.idl b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.idl index aa9d3f0fa..f5622ee46 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothAbs.idl @@ -24,12 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoCubicSmoothAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float x2; - [StrictTypeChecking] attribute float y2; +interface SVGPathSegCurvetoCubicSmoothAbs : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float x2; + attribute unrestricted float y2; }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.h b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.h index 76d473008..1b5d08861 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoCubicSmoothRel_h -#define SVGPathSegCurvetoCubicSmoothRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegCurvetoCubicSmooth.h" namespace WebCore { -class SVGPathSegCurvetoCubicSmoothRel : public SVGPathSegCurvetoCubicSmooth { +class SVGPathSegCurvetoCubicSmoothRel final : public SVGPathSegCurvetoCubicSmooth { public: - static PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x2, float y2) + static Ref<SVGPathSegCurvetoCubicSmoothRel> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x2, float y2) { - return adoptRef(new SVGPathSegCurvetoCubicSmoothRel(element, role, x, y, x2, y2)); + return adoptRef(*new SVGPathSegCurvetoCubicSmoothRel(element, role, x, y, x2, y2)); } private: - SVGPathSegCurvetoCubicSmoothRel(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x2, float y2) + SVGPathSegCurvetoCubicSmoothRel(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x2, float y2) : SVGPathSegCurvetoCubicSmooth(element, role, x, y, x2, y2) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_CUBIC_SMOOTH_REL; } - virtual String pathSegTypeAsLetter() const override { return "s"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_CUBIC_SMOOTH_REL; } + String pathSegTypeAsLetter() const final { return "s"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.idl b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.idl index c80156840..9fea6965f 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoCubicSmoothRel.idl @@ -24,12 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoCubicSmoothRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float x2; - [StrictTypeChecking] attribute float y2; +interface SVGPathSegCurvetoCubicSmoothRel : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float x2; + attribute unrestricted float y2; }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadratic.h b/Source/WebCore/svg/SVGPathSegCurvetoQuadratic.h index 6f8d06fdb..99435e0a9 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadratic.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadratic.h @@ -18,17 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoQuadratic_h -#define SVGPathSegCurvetoQuadratic_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { class SVGPathSegCurvetoQuadratic : public SVGPathSegWithContext { public: - SVGPathSegCurvetoQuadratic(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1) + SVGPathSegCurvetoQuadratic(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1) : SVGPathSegWithContext(element, role) , m_x(x) , m_y(y) @@ -73,6 +71,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.h b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.h index 0a8252e0e..dec36dbd0 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoQuadraticAbs_h -#define SVGPathSegCurvetoQuadraticAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegCurvetoQuadratic.h" namespace WebCore { -class SVGPathSegCurvetoQuadraticAbs : public SVGPathSegCurvetoQuadratic { +class SVGPathSegCurvetoQuadraticAbs final : public SVGPathSegCurvetoQuadratic { public: - static PassRefPtr<SVGPathSegCurvetoQuadraticAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1) + static Ref<SVGPathSegCurvetoQuadraticAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1) { - return adoptRef(new SVGPathSegCurvetoQuadraticAbs(element, role, x, y, x1, y1)); + return adoptRef(*new SVGPathSegCurvetoQuadraticAbs(element, role, x, y, x1, y1)); } private: - SVGPathSegCurvetoQuadraticAbs(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1) + SVGPathSegCurvetoQuadraticAbs(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1) : SVGPathSegCurvetoQuadratic(element, role, x, y, x1, y1) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_QUADRATIC_ABS; } - virtual String pathSegTypeAsLetter() const override { return "Q"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_QUADRATIC_ABS; } + String pathSegTypeAsLetter() const final { return "Q"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.idl b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.idl index 46fb5b699..72876330a 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticAbs.idl @@ -24,12 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoQuadraticAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float x1; - [StrictTypeChecking] attribute float y1; +interface SVGPathSegCurvetoQuadraticAbs : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float x1; + attribute unrestricted float y1; }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.h b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.h index a8db6a081..7a0ca059d 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoQuadraticRel_h -#define SVGPathSegCurvetoQuadraticRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegCurvetoQuadratic.h" namespace WebCore { -class SVGPathSegCurvetoQuadraticRel : public SVGPathSegCurvetoQuadratic { +class SVGPathSegCurvetoQuadraticRel final : public SVGPathSegCurvetoQuadratic { public: - static PassRefPtr<SVGPathSegCurvetoQuadraticRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1) + static Ref<SVGPathSegCurvetoQuadraticRel> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1) { - return adoptRef(new SVGPathSegCurvetoQuadraticRel(element, role, x, y, x1, y1)); + return adoptRef(*new SVGPathSegCurvetoQuadraticRel(element, role, x, y, x1, y1)); } private: - SVGPathSegCurvetoQuadraticRel(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1) + SVGPathSegCurvetoQuadraticRel(const SVGPathElement& element, SVGPathSegRole role, float x, float y, float x1, float y1) : SVGPathSegCurvetoQuadratic(element, role, x, y, x1, y1) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_QUADRATIC_REL; } - virtual String pathSegTypeAsLetter() const override { return "q"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_QUADRATIC_REL; } + String pathSegTypeAsLetter() const final { return "q"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.idl b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.idl index 39f8016ab..67dd541fe 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticRel.idl @@ -24,12 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoQuadraticRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float x1; - [StrictTypeChecking] attribute float y1; +interface SVGPathSegCurvetoQuadraticRel : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; + attribute unrestricted float x1; + attribute unrestricted float y1; }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h index a5318b60b..898fabb19 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoQuadraticSmoothAbs_h -#define SVGPathSegCurvetoQuadraticSmoothAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { -class SVGPathSegCurvetoQuadraticSmoothAbs : public SVGPathSegSingleCoordinate { +class SVGPathSegCurvetoQuadraticSmoothAbs final : public SVGPathSegSingleCoordinate { public: - static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y) + static Ref<SVGPathSegCurvetoQuadraticSmoothAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y) { - return adoptRef(new SVGPathSegCurvetoQuadraticSmoothAbs(element, role, x, y)); + return adoptRef(*new SVGPathSegCurvetoQuadraticSmoothAbs(element, role, x, y)); } private: - SVGPathSegCurvetoQuadraticSmoothAbs(SVGPathElement* element, SVGPathSegRole role, float x, float y) + SVGPathSegCurvetoQuadraticSmoothAbs(const SVGPathElement& element, SVGPathSegRole role, float x, float y) : SVGPathSegSingleCoordinate(element, role, x, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; } - virtual String pathSegTypeAsLetter() const override { return "T"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; } + String pathSegTypeAsLetter() const final { return "T"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl index 0850e3137..149edd96f 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl @@ -24,10 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoQuadraticSmoothAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; +interface SVGPathSegCurvetoQuadraticSmoothAbs : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.h b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.h index f7603df23..e97a10d2b 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.h +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegCurvetoQuadraticSmoothRel_h -#define SVGPathSegCurvetoQuadraticSmoothRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { -class SVGPathSegCurvetoQuadraticSmoothRel : public SVGPathSegSingleCoordinate { +class SVGPathSegCurvetoQuadraticSmoothRel final : public SVGPathSegSingleCoordinate { public: - static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y) + static Ref<SVGPathSegCurvetoQuadraticSmoothRel> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y) { - return adoptRef(new SVGPathSegCurvetoQuadraticSmoothRel(element, role, x, y)); + return adoptRef(*new SVGPathSegCurvetoQuadraticSmoothRel(element, role, x, y)); } private: - SVGPathSegCurvetoQuadraticSmoothRel(SVGPathElement* element, SVGPathSegRole role, float x, float y) + SVGPathSegCurvetoQuadraticSmoothRel(const SVGPathElement& element, SVGPathSegRole role, float x, float y) : SVGPathSegSingleCoordinate(element, role, x, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; } - virtual String pathSegTypeAsLetter() const override { return "t"; } + unsigned short pathSegType() const final { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; } + String pathSegTypeAsLetter() const final { return "t"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl index 6743a1c53..857ee307c 100644 --- a/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl +++ b/Source/WebCore/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl @@ -24,10 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegCurvetoQuadraticSmoothRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; +interface SVGPathSegCurvetoQuadraticSmoothRel : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegLinetoAbs.h b/Source/WebCore/svg/SVGPathSegLinetoAbs.h index 00c832a13..2addfaaff 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoAbs.h +++ b/Source/WebCore/svg/SVGPathSegLinetoAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoAbs_h -#define SVGPathSegLinetoAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { -class SVGPathSegLinetoAbs : public SVGPathSegSingleCoordinate { +class SVGPathSegLinetoAbs final : public SVGPathSegSingleCoordinate { public: - static PassRefPtr<SVGPathSegLinetoAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y) + static Ref<SVGPathSegLinetoAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y) { - return adoptRef(new SVGPathSegLinetoAbs(element, role, x, y)); + return adoptRef(*new SVGPathSegLinetoAbs(element, role, x, y)); } private: - SVGPathSegLinetoAbs(SVGPathElement* element, SVGPathSegRole role, float x, float y) + SVGPathSegLinetoAbs(const SVGPathElement& element, SVGPathSegRole role, float x, float y) : SVGPathSegSingleCoordinate(element, role, x, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_LINETO_ABS; } - virtual String pathSegTypeAsLetter() const override { return "L"; } + unsigned short pathSegType() const final { return PATHSEG_LINETO_ABS; } + String pathSegTypeAsLetter() const final { return "L"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoAbs.idl b/Source/WebCore/svg/SVGPathSegLinetoAbs.idl index 0b4c74535..112a5df4d 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoAbs.idl +++ b/Source/WebCore/svg/SVGPathSegLinetoAbs.idl @@ -24,10 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegLinetoAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; +interface SVGPathSegLinetoAbs : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegLinetoHorizontal.h b/Source/WebCore/svg/SVGPathSegLinetoHorizontal.h index 56a11e419..479845d5d 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoHorizontal.h +++ b/Source/WebCore/svg/SVGPathSegLinetoHorizontal.h @@ -18,17 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoHorizontal_h -#define SVGPathSegLinetoHorizontal_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { class SVGPathSegLinetoHorizontal : public SVGPathSegWithContext { public: - SVGPathSegLinetoHorizontal(SVGPathElement* element, SVGPathSegRole role, float x) + SVGPathSegLinetoHorizontal(const SVGPathElement& element, SVGPathSegRole role, float x) : SVGPathSegWithContext(element, role) , m_x(x) { @@ -46,6 +44,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.h b/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.h index 5607338c9..f0457c11f 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.h +++ b/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoHorizontalAbs_h -#define SVGPathSegLinetoHorizontalAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegLinetoHorizontal.h" namespace WebCore { -class SVGPathSegLinetoHorizontalAbs : public SVGPathSegLinetoHorizontal { +class SVGPathSegLinetoHorizontalAbs final : public SVGPathSegLinetoHorizontal { public: - static PassRefPtr<SVGPathSegLinetoHorizontalAbs> create(SVGPathElement* element, SVGPathSegRole role, float x) + static Ref<SVGPathSegLinetoHorizontalAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x) { - return adoptRef(new SVGPathSegLinetoHorizontalAbs(element, role, x)); + return adoptRef(*new SVGPathSegLinetoHorizontalAbs(element, role, x)); } private: - SVGPathSegLinetoHorizontalAbs(SVGPathElement* element, SVGPathSegRole role, float x) + SVGPathSegLinetoHorizontalAbs(const SVGPathElement& element, SVGPathSegRole role, float x) : SVGPathSegLinetoHorizontal(element, role, x) { } - virtual unsigned short pathSegType() const override { return PATHSEG_LINETO_HORIZONTAL_ABS; } - virtual String pathSegTypeAsLetter() const override { return "H"; } + unsigned short pathSegType() const final { return PATHSEG_LINETO_HORIZONTAL_ABS; } + String pathSegTypeAsLetter() const final { return "H"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.idl b/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.idl index 9252acf5b..0d09380d0 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.idl +++ b/Source/WebCore/svg/SVGPathSegLinetoHorizontalAbs.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegLinetoHorizontalAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; +interface SVGPathSegLinetoHorizontalAbs : SVGPathSeg { + attribute unrestricted float x; }; diff --git a/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.h b/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.h index 70ece65be..c0622ac03 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.h +++ b/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoHorizontalRel_h -#define SVGPathSegLinetoHorizontalRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegLinetoHorizontal.h" namespace WebCore { -class SVGPathSegLinetoHorizontalRel : public SVGPathSegLinetoHorizontal { +class SVGPathSegLinetoHorizontalRel final : public SVGPathSegLinetoHorizontal { public: - static PassRefPtr<SVGPathSegLinetoHorizontalRel> create(SVGPathElement* element, SVGPathSegRole role, float x) + static Ref<SVGPathSegLinetoHorizontalRel> create(const SVGPathElement& element, SVGPathSegRole role, float x) { - return adoptRef(new SVGPathSegLinetoHorizontalRel(element, role, x)); + return adoptRef(*new SVGPathSegLinetoHorizontalRel(element, role, x)); } private: - SVGPathSegLinetoHorizontalRel(SVGPathElement* element, SVGPathSegRole role, float x) + SVGPathSegLinetoHorizontalRel(const SVGPathElement& element, SVGPathSegRole role, float x) : SVGPathSegLinetoHorizontal(element, role, x) { } - virtual unsigned short pathSegType() const override { return PATHSEG_LINETO_HORIZONTAL_REL; } - virtual String pathSegTypeAsLetter() const override { return "h"; } + unsigned short pathSegType() const final { return PATHSEG_LINETO_HORIZONTAL_REL; } + String pathSegTypeAsLetter() const final { return "h"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.idl b/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.idl index a0a65c40b..5060955e9 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.idl +++ b/Source/WebCore/svg/SVGPathSegLinetoHorizontalRel.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegLinetoHorizontalRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; +interface SVGPathSegLinetoHorizontalRel : SVGPathSeg { + attribute unrestricted float x; }; diff --git a/Source/WebCore/svg/SVGPathSegLinetoRel.h b/Source/WebCore/svg/SVGPathSegLinetoRel.h index ef0e05b83..dcdf4838a 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoRel.h +++ b/Source/WebCore/svg/SVGPathSegLinetoRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoRel_h -#define SVGPathSegLinetoRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { -class SVGPathSegLinetoRel : public SVGPathSegSingleCoordinate { +class SVGPathSegLinetoRel final : public SVGPathSegSingleCoordinate { public: - static PassRefPtr<SVGPathSegLinetoRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y) + static Ref<SVGPathSegLinetoRel> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y) { - return adoptRef(new SVGPathSegLinetoRel(element, role, x, y)); + return adoptRef(*new SVGPathSegLinetoRel(element, role, x, y)); } private: - SVGPathSegLinetoRel(SVGPathElement* element, SVGPathSegRole role, float x, float y) + SVGPathSegLinetoRel(const SVGPathElement& element, SVGPathSegRole role, float x, float y) : SVGPathSegSingleCoordinate(element, role, x, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_LINETO_REL; } - virtual String pathSegTypeAsLetter() const override { return "l"; } + unsigned short pathSegType() const final { return PATHSEG_LINETO_REL; } + String pathSegTypeAsLetter() const final { return "l"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoRel.idl b/Source/WebCore/svg/SVGPathSegLinetoRel.idl index 089aae269..08aa2d0c1 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoRel.idl +++ b/Source/WebCore/svg/SVGPathSegLinetoRel.idl @@ -24,10 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegLinetoRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; +interface SVGPathSegLinetoRel : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegLinetoVertical.h b/Source/WebCore/svg/SVGPathSegLinetoVertical.h index d130daf7e..9d24d77df 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoVertical.h +++ b/Source/WebCore/svg/SVGPathSegLinetoVertical.h @@ -18,17 +18,15 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoVertical_h -#define SVGPathSegLinetoVertical_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { class SVGPathSegLinetoVertical : public SVGPathSegWithContext { public: - SVGPathSegLinetoVertical(SVGPathElement* element, SVGPathSegRole role, float y) + SVGPathSegLinetoVertical(const SVGPathElement& element, SVGPathSegRole role, float y) : SVGPathSegWithContext(element, role) , m_y(y) { @@ -46,6 +44,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.h b/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.h index a3d09253e..d859a51ed 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.h +++ b/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoVerticalAbs_h -#define SVGPathSegLinetoVerticalAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegLinetoVertical.h" namespace WebCore { -class SVGPathSegLinetoVerticalAbs : public SVGPathSegLinetoVertical { +class SVGPathSegLinetoVerticalAbs final : public SVGPathSegLinetoVertical { public: - static PassRefPtr<SVGPathSegLinetoVerticalAbs> create(SVGPathElement* element, SVGPathSegRole role, float y) + static Ref<SVGPathSegLinetoVerticalAbs> create(const SVGPathElement& element, SVGPathSegRole role, float y) { - return adoptRef(new SVGPathSegLinetoVerticalAbs(element, role, y)); + return adoptRef(*new SVGPathSegLinetoVerticalAbs(element, role, y)); } private: - SVGPathSegLinetoVerticalAbs(SVGPathElement* element, SVGPathSegRole role, float y) + SVGPathSegLinetoVerticalAbs(const SVGPathElement& element, SVGPathSegRole role, float y) : SVGPathSegLinetoVertical(element, role, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_LINETO_VERTICAL_ABS; } - virtual String pathSegTypeAsLetter() const override { return "V"; } + unsigned short pathSegType() const final { return PATHSEG_LINETO_VERTICAL_ABS; } + String pathSegTypeAsLetter() const final { return "V"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.idl b/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.idl index 15c66dadd..4d2f804bc 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.idl +++ b/Source/WebCore/svg/SVGPathSegLinetoVerticalAbs.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegLinetoVerticalAbs : SVGPathSeg { - [StrictTypeChecking] attribute float y; +interface SVGPathSegLinetoVerticalAbs : SVGPathSeg { + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.h b/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.h index 08c499f8d..c180c7eda 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.h +++ b/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegLinetoVerticalRel_h -#define SVGPathSegLinetoVerticalRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegLinetoVertical.h" namespace WebCore { -class SVGPathSegLinetoVerticalRel : public SVGPathSegLinetoVertical { +class SVGPathSegLinetoVerticalRel final : public SVGPathSegLinetoVertical { public: - static PassRefPtr<SVGPathSegLinetoVerticalRel> create(SVGPathElement* element, SVGPathSegRole role, float y) + static Ref<SVGPathSegLinetoVerticalRel> create(const SVGPathElement& element, SVGPathSegRole role, float y) { - return adoptRef(new SVGPathSegLinetoVerticalRel(element, role, y)); + return adoptRef(*new SVGPathSegLinetoVerticalRel(element, role, y)); } private: - SVGPathSegLinetoVerticalRel(SVGPathElement* element, SVGPathSegRole role, float y) + SVGPathSegLinetoVerticalRel(const SVGPathElement& element, SVGPathSegRole role, float y) : SVGPathSegLinetoVertical(element, role, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_LINETO_VERTICAL_REL; } - virtual String pathSegTypeAsLetter() const override { return "v"; } + unsigned short pathSegType() const final { return PATHSEG_LINETO_VERTICAL_REL; } + String pathSegTypeAsLetter() const final { return "v"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.idl b/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.idl index 632ec6975..72064914d 100644 --- a/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.idl +++ b/Source/WebCore/svg/SVGPathSegLinetoVerticalRel.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegLinetoVerticalRel : SVGPathSeg { - [StrictTypeChecking] attribute float y; +interface SVGPathSegLinetoVerticalRel : SVGPathSeg { + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegList.cpp b/Source/WebCore/svg/SVGPathSegList.cpp index 705c968c0..403ce33a6 100644 --- a/Source/WebCore/svg/SVGPathSegList.cpp +++ b/Source/WebCore/svg/SVGPathSegList.cpp @@ -1,7 +1,4 @@ /* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> - * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -21,29 +18,110 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathSegList.h" -#include "SVGNames.h" +#include "SVGAnimatedPathSegListPropertyTearOff.h" #include "SVGPathElement.h" -#include "SVGPathUtilities.h" +#include "SVGPathSegWithContext.h" namespace WebCore { -String SVGPathSegList::valueAsString() const +void SVGPathSegList::clearContextAndRoles() +{ + ASSERT(m_values); + for (auto& item : *m_values) + static_cast<SVGPathSegWithContext*>(item.get())->setContextAndRole(nullptr, PathSegUndefinedRole); +} + +ExceptionOr<void> SVGPathSegList::clear() +{ + ASSERT(m_values); + if (m_values->isEmpty()) + return { }; + + clearContextAndRoles(); + return Base::clearValues(); +} + +ExceptionOr<SVGPathSegList::PtrListItemType> SVGPathSegList::getItem(unsigned index) { - String pathString; - buildStringFromSVGPathSegList(*this, pathString, UnalteredParsing); - return pathString; + return Base::getItemValues(index); } -void SVGPathSegList::commitChange(SVGElement* contextElement, ListModification listModification) +ExceptionOr<SVGPathSegList::PtrListItemType> SVGPathSegList::replaceItem(PtrListItemType newItem, unsigned index) { + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!newItem) + return Exception { SVGException::SVG_WRONG_TYPE_ERR }; + + if (index < m_values->size()) { + ListItemType replacedItem = m_values->at(index); + ASSERT(replacedItem); + static_cast<SVGPathSegWithContext*>(replacedItem.get())->setContextAndRole(nullptr, PathSegUndefinedRole); + } + + return Base::replaceItemValues(newItem, index); +} + +ExceptionOr<SVGPathSegList::PtrListItemType> SVGPathSegList::removeItem(unsigned index) +{ + auto result = Base::removeItemValues(index); + if (result.hasException()) + return result; + auto removedItem = result.releaseReturnValue(); + if (removedItem) + static_cast<SVGPathSegWithContext&>(*removedItem).setContextAndRole(nullptr, PathSegUndefinedRole); + return WTFMove(removedItem); +} + +SVGPathElement* SVGPathSegList::contextElement() const +{ + SVGElement* contextElement = m_animatedProperty->contextElement(); ASSERT(contextElement); - toSVGPathElement(contextElement)->pathSegListChanged(m_role, listModification); + return downcast<SVGPathElement>(contextElement); } +bool SVGPathSegList::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) +{ + SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get()); + RefPtr<SVGAnimatedProperty> animatedPropertyOfItem = newItemWithContext->animatedProperty(); + + // Alter the role, after calling animatedProperty(), as that may influence the returned animated property. + newItemWithContext->setContextAndRole(contextElement(), m_pathSegRole); + + if (!animatedPropertyOfItem) + return true; + + // newItem belongs to a SVGPathElement, but its associated SVGAnimatedProperty is not an animated list tear off. + // (for example: "pathElement.pathSegList.appendItem(pathElement.createSVGPathSegClosepath())") + if (!animatedPropertyOfItem->isAnimatedListTearOff()) + return true; + + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. + // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. + bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; + RefPtr<SVGAnimatedPathSegListPropertyTearOff> propertyTearOff = static_pointer_cast<SVGAnimatedPathSegListPropertyTearOff>(animatedPropertyOfItem); + int indexToRemove = propertyTearOff->findItem(newItem.get()); + ASSERT(indexToRemove != -1); + + // Do not remove newItem if already in this list at the target index. + if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify) + return false; + + propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); + + if (!indexToModify) + return true; + + // If the item lived in our list, adjust the insertion index. + if (!livesInOtherList) { + unsigned& index = *indexToModify; + // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item. + if (static_cast<unsigned>(indexToRemove) < index) + --index; + } + + return true; } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGPathSegList.h b/Source/WebCore/svg/SVGPathSegList.h index 553ea115e..48ba6a3f5 100644 --- a/Source/WebCore/svg/SVGPathSegList.h +++ b/Source/WebCore/svg/SVGPathSegList.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Eric Seidel <eric@webkit.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 @@ -17,44 +17,145 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegList_h -#define SVGPathSegList_h +#pragma once -#if ENABLE(SVG) -#include "SVGListProperty.h" -#include "SVGPathSeg.h" -#include "SVGPropertyTraits.h" - -#include <wtf/Vector.h> -#include <wtf/text/WTFString.h> +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGPathSegListValues.h" namespace WebCore { -class SVGElement; +class SVGPathElement; -class SVGPathSegList : public Vector<RefPtr<SVGPathSeg>> { +class SVGPathSegList final : public SVGListProperty<SVGPathSegListValues> { public: - SVGPathSegList(SVGPathSegRole role) - : m_role(role) + using Base = SVGListProperty<SVGPathSegListValues>; + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<SVGPathSegListValues>; + using ListItemType = SVGPropertyTraits<SVGPathSegListValues>::ListItemType; + using PtrListItemType = RefPtr<SVGPathSeg>; + + static Ref<SVGPathSegList> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegListValues& values, ListWrapperCache& wrappers) + { + return adoptRef(*new SVGPathSegList(animatedProperty, role, pathSegRole, values, wrappers)); + } + + static Ref<SVGPathSegList> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGPathSegListValues& values, ListWrapperCache& wrappers) + { + ASSERT_NOT_REACHED(); + return adoptRef(*new SVGPathSegList(animatedProperty, role, PathSegUndefinedRole, values, wrappers)); + } + + int findItem(const ListItemType& item) const + { + ASSERT(m_values); + + unsigned size = m_values->size(); + for (size_t i = 0; i < size; ++i) { + if (item == m_values->at(i)) + return i; + } + + return -1; + } + + void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) { + ASSERT(m_values); + ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_values->size()); + + m_values->remove(itemIndex); + + if (shouldSynchronizeWrappers) + commitChange(); + } + + // SVGList API + ExceptionOr<void> clear(); + + ExceptionOr<PtrListItemType> initialize(PtrListItemType newItem) + { + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!newItem) + return Exception { SVGException::SVG_WRONG_TYPE_ERR }; + + clearContextAndRoles(); + return Base::initializeValues(newItem); } - String valueAsString() const; + ExceptionOr<PtrListItemType> getItem(unsigned index); + + ExceptionOr<PtrListItemType> insertItemBefore(PtrListItemType newItem, unsigned index) + { + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!newItem) + return Exception { SVGException::SVG_WRONG_TYPE_ERR }; + + return Base::insertItemBeforeValues(newItem, index); + } + + ExceptionOr<PtrListItemType> replaceItem(PtrListItemType, unsigned index); + + ExceptionOr<PtrListItemType> removeItem(unsigned index); - // Only used by SVGPathSegListPropertyTearOff. - void commitChange(SVGElement* contextElement, ListModification); + ExceptionOr<PtrListItemType> appendItem(PtrListItemType newItem) + { + // Not specified, but FF/Opera do it this way, and it's just sane. + if (!newItem) + return Exception { SVGException::SVG_WRONG_TYPE_ERR }; + + return Base::appendItemValues(newItem); + } private: - SVGPathSegRole m_role; -}; + SVGPathSegList(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegListValues& values, ListWrapperCache& wrappers) + : SVGListProperty<SVGPathSegListValues>(role, values, &wrappers) + , m_animatedProperty(&animatedProperty) + , m_pathSegRole(pathSegRole) + { + } + + virtual ~SVGPathSegList() + { + if (m_animatedProperty) + m_animatedProperty->propertyWillBeDeleted(*this); + } + + SVGPathElement* contextElement() const; + + void clearContextAndRoles(); + + using Base::m_role; + + bool isReadOnly() const final + { + if (m_role == AnimValRole) + return true; + if (m_animatedProperty && m_animatedProperty->isReadOnly()) + return true; + return false; + } -template<> -struct SVGPropertyTraits<SVGPathSegList> { - static SVGPathSegList initialValue() { return SVGPathSegList(PathSegUndefinedRole); } - typedef RefPtr<SVGPathSeg> ListItemType; + void commitChange() final + { + ASSERT(m_values); + m_values->commitChange(*m_animatedProperty->contextElement(), ListModificationUnknown); + } + + void commitChange(ListModification listModification) final + { + ASSERT(m_values); + m_values->commitChange(*m_animatedProperty->contextElement(), listModification); + } + + bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) final; + bool processIncomingListItemWrapper(Ref<ListItemTearOff>&, unsigned*) final + { + ASSERT_NOT_REACHED(); + return true; + } + +private: + RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; + SVGPathSegRole m_pathSegRole; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegList.idl b/Source/WebCore/svg/SVGPathSegList.idl index e6c5af53f..3a0005d1e 100644 --- a/Source/WebCore/svg/SVGPathSegList.idl +++ b/Source/WebCore/svg/SVGPathSegList.idl @@ -24,17 +24,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGPathSegList { +interface SVGPathSegList { readonly attribute unsigned long numberOfItems; - [RaisesException] void clear(); - [StrictTypeChecking, RaisesException] SVGPathSeg initialize(SVGPathSeg newItem); - [StrictTypeChecking, RaisesException] SVGPathSeg getItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGPathSeg insertItemBefore(SVGPathSeg newItem, unsigned long index); - [StrictTypeChecking, RaisesException] SVGPathSeg replaceItem(SVGPathSeg newItem, unsigned long index); - [StrictTypeChecking, RaisesException] SVGPathSeg removeItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGPathSeg appendItem(SVGPathSeg newItem); + [MayThrowException] void clear(); + [MayThrowException] SVGPathSeg initialize(SVGPathSeg? newItem); // FIXME: Should not be nullable. + [MayThrowException] SVGPathSeg getItem(unsigned long index); + [MayThrowException] SVGPathSeg insertItemBefore(SVGPathSeg? newItem, unsigned long index); // FIXME: Should not be nullable. + [MayThrowException] SVGPathSeg replaceItem(SVGPathSeg? newItem, unsigned long index); // FIXME: Should not be nullable. + [MayThrowException] SVGPathSeg removeItem(unsigned long index); + [MayThrowException] SVGPathSeg appendItem(SVGPathSeg? newItem); // FIXME: Should not be nullable. }; - diff --git a/Source/WebCore/svg/SVGPathSegListBuilder.cpp b/Source/WebCore/svg/SVGPathSegListBuilder.cpp index d5346afbc..1558f808a 100644 --- a/Source/WebCore/svg/SVGPathSegListBuilder.cpp +++ b/Source/WebCore/svg/SVGPathSegListBuilder.cpp @@ -2,7 +2,7 @@ * Copyright (C) 2002, 2003 The Karbon Developers * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -22,11 +22,8 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathSegListBuilder.h" -#include "ExceptionCode.h" #include "SVGPathElement.h" #include "SVGPathSegArcAbs.h" #include "SVGPathSegArcRel.h" @@ -45,116 +42,94 @@ #include "SVGPathSegLinetoRel.h" #include "SVGPathSegLinetoVerticalAbs.h" #include "SVGPathSegLinetoVerticalRel.h" -#include "SVGPathSegList.h" +#include "SVGPathSegListValues.h" #include "SVGPathSegMovetoAbs.h" #include "SVGPathSegMovetoRel.h" namespace WebCore { -SVGPathSegListBuilder::SVGPathSegListBuilder() - : m_pathElement(0) - , m_pathSegList(0) - , m_pathSegRole(PathSegUndefinedRole) +SVGPathSegListBuilder::SVGPathSegListBuilder(SVGPathElement& pathElement, SVGPathSegListValues& pathSegList, SVGPathSegRole role) + : m_pathElement(pathElement) + , m_pathSegList(pathSegList) + , m_pathSegRole(role) { } void SVGPathSegListBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegMovetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegMovetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegMovetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegMovetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole)); } void SVGPathSegListBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegLinetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegLinetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegLinetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegLinetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole)); } void SVGPathSegListBuilder::lineToHorizontal(float x, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalAbs(x, m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegLinetoHorizontalAbs(x, m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalRel(x, m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegLinetoHorizontalRel(x, m_pathSegRole)); } void SVGPathSegListBuilder::lineToVertical(float y, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalAbs(y, m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegLinetoVerticalAbs(y, m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalRel(y, m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegLinetoVerticalRel(y, m_pathSegRole)); } void SVGPathSegListBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole)); } void SVGPathSegListBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothAbs(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicSmoothAbs(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothRel(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicSmoothRel(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole)); } void SVGPathSegListBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole)); } void SVGPathSegListBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticSmoothAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothRel(targetPoint.x(), targetPoint.y(), m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticSmoothRel(targetPoint.x(), targetPoint.y(), m_pathSegRole)); } void SVGPathSegListBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode) { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); if (mode == AbsoluteCoordinates) - m_pathSegList->append(m_pathElement->createSVGPathSegArcAbs(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegArcAbs(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole)); else - m_pathSegList->append(m_pathElement->createSVGPathSegArcRel(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegArcRel(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole)); } void SVGPathSegListBuilder::closePath() { - ASSERT(m_pathElement); - ASSERT(m_pathSegList); - m_pathSegList->append(m_pathElement->createSVGPathSegClosePath(m_pathSegRole)); + m_pathSegList.append(m_pathElement.createSVGPathSegClosePath(m_pathSegRole)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathSegListBuilder.h b/Source/WebCore/svg/SVGPathSegListBuilder.h index 565c5664b..eb1ab8b18 100644 --- a/Source/WebCore/svg/SVGPathSegListBuilder.h +++ b/Source/WebCore/svg/SVGPathSegListBuilder.h @@ -2,7 +2,7 @@ * Copyright (C) 2002, 2003 The Karbon Developers * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -21,56 +21,41 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegListBuilder_h -#define SVGPathSegListBuilder_h +#pragma once -#if ENABLE(SVG) #include "FloatPoint.h" #include "SVGPathConsumer.h" -#include "SVGPathSegList.h" +#include "SVGPathSegListValues.h" namespace WebCore { class SVGPathElement; -class SVGPathSegListBuilder : public SVGPathConsumer { +class SVGPathSegListBuilder final : public SVGPathConsumer { public: - SVGPathSegListBuilder(); - - void setCurrentSVGPathElement(SVGPathElement* pathElement) { m_pathElement = pathElement; } - void setCurrentSVGPathSegList(SVGPathSegList& pathSegList) { m_pathSegList = &pathSegList; } - void setCurrentSVGPathSegRole(SVGPathSegRole pathSegRole) { m_pathSegRole = pathSegRole; } + SVGPathSegListBuilder(SVGPathElement&, SVGPathSegListValues&, SVGPathSegRole); private: - virtual void incrementPathSegmentCount() override { } - virtual bool continueConsuming() override { return true; } - virtual void cleanup() override - { - m_pathElement = 0; - m_pathSegList = 0; - m_pathSegRole = PathSegUndefinedRole; - } + void incrementPathSegmentCount() final { } + bool continueConsuming() final { return true; } // Used in UnalteredParsing/NormalizedParsing modes. - virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override; - virtual void lineTo(const FloatPoint&, PathCoordinateMode) override; - virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void closePath() override; + void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) final; + void lineTo(const FloatPoint&, PathCoordinateMode) final; + void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void closePath() final; // Only used in UnalteredParsing mode. - virtual void lineToHorizontal(float, PathCoordinateMode) override; - virtual void lineToVertical(float, PathCoordinateMode) override; - virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override; - virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) override; - - SVGPathElement* m_pathElement; - SVGPathSegList* m_pathSegList; - SVGPathSegRole m_pathSegRole; + void lineToHorizontal(float, PathCoordinateMode) final; + void lineToVertical(float, PathCoordinateMode) final; + void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) final; + void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) final; + + SVGPathElement& m_pathElement; + SVGPathSegListValues& m_pathSegList; + SVGPathSegRole m_pathSegRole { PathSegUndefinedRole }; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathSegListBuilder_h diff --git a/Source/WebCore/svg/SVGPathSegListSource.cpp b/Source/WebCore/svg/SVGPathSegListSource.cpp index 5526cd650..0cdd8afed 100644 --- a/Source/WebCore/svg/SVGPathSegListSource.cpp +++ b/Source/WebCore/svg/SVGPathSegListSource.cpp @@ -18,8 +18,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathSegListSource.h" #include "SVGPathSegArc.h" @@ -31,7 +29,7 @@ namespace WebCore { -SVGPathSegListSource::SVGPathSegListSource(const SVGPathSegList& pathSegList) +SVGPathSegListSource::SVGPathSegListSource(const SVGPathSegListValues& pathSegList) : m_pathSegList(pathSegList) { m_itemCurrent = 0; @@ -150,5 +148,3 @@ bool SVGPathSegListSource::parseArcToSegment(float& rx, float& ry, float& angle, } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathSegListSource.h b/Source/WebCore/svg/SVGPathSegListSource.h index fa0996213..506e7c044 100644 --- a/Source/WebCore/svg/SVGPathSegListSource.h +++ b/Source/WebCore/svg/SVGPathSegListSource.h @@ -17,45 +17,40 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegListSource_h -#define SVGPathSegListSource_h +#pragma once -#if ENABLE(SVG) #include "FloatPoint.h" #include "SVGPathSeg.h" -#include "SVGPathSegList.h" +#include "SVGPathSegListValues.h" #include "SVGPathSource.h" #include <wtf/RefPtr.h> namespace WebCore { -class SVGPathSegListSource : public SVGPathSource { +class SVGPathSegListSource final : public SVGPathSource { public: - explicit SVGPathSegListSource(const SVGPathSegList&); + explicit SVGPathSegListSource(const SVGPathSegListValues&); private: - virtual bool hasMoreData() const override; - virtual bool moveToNextToken() override { return true; } - virtual bool parseSVGSegmentType(SVGPathSegType&) override; - virtual SVGPathSegType nextCommand(SVGPathSegType) override; - - virtual bool parseMoveToSegment(FloatPoint&) override; - virtual bool parseLineToSegment(FloatPoint&) override; - virtual bool parseLineToHorizontalSegment(float&) override; - virtual bool parseLineToVerticalSegment(float&) override; - virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&) override; - virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) override; - - const SVGPathSegList& m_pathSegList; + bool hasMoreData() const final; + bool moveToNextToken() final { return true; } + bool parseSVGSegmentType(SVGPathSegType&) final; + SVGPathSegType nextCommand(SVGPathSegType) final; + + bool parseMoveToSegment(FloatPoint&) final; + bool parseLineToSegment(FloatPoint&) final; + bool parseLineToHorizontalSegment(float&) final; + bool parseLineToVerticalSegment(float&) final; + bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) final; + bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) final; + bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) final; + bool parseCurveToQuadraticSmoothSegment(FloatPoint&) final; + bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) final; + + const SVGPathSegListValues& m_pathSegList; RefPtr<SVGPathSeg> m_segment; int m_itemCurrent; int m_itemEnd; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathSegListSource_h diff --git a/Source/WebCore/svg/ColorDistance.h b/Source/WebCore/svg/SVGPathSegListValues.cpp index 9e6dd9444..b6f64a9dc 100644 --- a/Source/WebCore/svg/ColorDistance.h +++ b/Source/WebCore/svg/SVGPathSegListValues.cpp @@ -1,5 +1,8 @@ /* + * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> * Copyright (C) 2007 Eric Seidel <eric@webkit.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 @@ -17,36 +20,24 @@ * Boston, MA 02110-1301, USA. */ -#ifndef ColorDistance_h -#define ColorDistance_h -#if ENABLE(SVG) +#include "config.h" +#include "SVGPathSegListValues.h" -namespace WebCore { - -class Color; - -class ColorDistance { -public: - ColorDistance(); - ColorDistance(const Color& fromColor, const Color& toColor); - ColorDistance(int redDiff, int blueDiff, int greenDiff); +#include "SVGPathElement.h" +#include "SVGPathUtilities.h" - ColorDistance scaledDistance(float scaleFactor) const; - Color addToColor(const Color&) const; - - static Color addColors(const Color&, const Color&); - static Color clampColor(int red, int green, int blue, int alpha); +namespace WebCore { - bool isZero() const; +String SVGPathSegListValues::valueAsString() const +{ + String pathString; + buildStringFromSVGPathSegListValues(*this, pathString, UnalteredParsing); + return pathString; +} - float distance() const; - -private: - int m_redDiff; - int m_greenDiff; - int m_blueDiff; -}; +void SVGPathSegListValues::commitChange(SVGElement& contextElement, ListModification listModification) +{ + downcast<SVGPathElement>(contextElement).pathSegListChanged(m_role, listModification); } -#endif // ENABLE(SVG) -#endif // ColorDistance_h +} diff --git a/Source/WebCore/svg/SVGPathSegListValues.h b/Source/WebCore/svg/SVGPathSegListValues.h new file mode 100644 index 000000000..b2ed1dd5a --- /dev/null +++ b/Source/WebCore/svg/SVGPathSegListValues.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007 Eric Seidel <eric@webkit.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. + */ + +#pragma once + +#include "SVGListProperty.h" +#include "SVGPathSeg.h" +#include "SVGPropertyTraits.h" +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class SVGElement; +class SVGPathSegList; + +template<typename T> +class SVGPropertyTearOff; + +class SVGPathSegListValues : public Vector<RefPtr<SVGPathSeg>> { +public: + explicit SVGPathSegListValues(SVGPathSegRole role) + : m_role(role) + { + } + + String valueAsString() const; + + void commitChange(SVGElement& contextElement, ListModification); + +private: + SVGPathSegRole m_role; +}; + +template<> struct SVGPropertyTraits<SVGPathSegListValues> { + static SVGPathSegListValues initialValue() { return SVGPathSegListValues(PathSegUndefinedRole); } + + using ListItemType = RefPtr<SVGPathSeg>; + using ListItemTearOff = SVGPropertyTearOff<RefPtr<SVGPathSeg>>; + using ListPropertyTearOff = SVGPathSegList; +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGPathSegMovetoAbs.h b/Source/WebCore/svg/SVGPathSegMovetoAbs.h index 66866afdc..3db2e3dda 100644 --- a/Source/WebCore/svg/SVGPathSegMovetoAbs.h +++ b/Source/WebCore/svg/SVGPathSegMovetoAbs.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegMovetoAbs_h -#define SVGPathSegMovetoAbs_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { -class SVGPathSegMovetoAbs : public SVGPathSegSingleCoordinate { +class SVGPathSegMovetoAbs final : public SVGPathSegSingleCoordinate { public: - static PassRefPtr<SVGPathSegMovetoAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y) + static Ref<SVGPathSegMovetoAbs> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y) { - return adoptRef(new SVGPathSegMovetoAbs(element, role, x, y)); + return adoptRef(*new SVGPathSegMovetoAbs(element, role, x, y)); } private: - SVGPathSegMovetoAbs(SVGPathElement* element, SVGPathSegRole role, float x, float y) + SVGPathSegMovetoAbs(const SVGPathElement& element, SVGPathSegRole role, float x, float y) : SVGPathSegSingleCoordinate(element, role, x, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_MOVETO_ABS; } - virtual String pathSegTypeAsLetter() const override { return "M"; } + unsigned short pathSegType() const final { return PATHSEG_MOVETO_ABS; } + String pathSegTypeAsLetter() const final { return "M"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegMovetoAbs.idl b/Source/WebCore/svg/SVGPathSegMovetoAbs.idl index 255f77ec7..091dadb17 100644 --- a/Source/WebCore/svg/SVGPathSegMovetoAbs.idl +++ b/Source/WebCore/svg/SVGPathSegMovetoAbs.idl @@ -24,10 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegMovetoAbs : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; +interface SVGPathSegMovetoAbs : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegMovetoRel.h b/Source/WebCore/svg/SVGPathSegMovetoRel.h index b8a167d2c..b74825709 100644 --- a/Source/WebCore/svg/SVGPathSegMovetoRel.h +++ b/Source/WebCore/svg/SVGPathSegMovetoRel.h @@ -19,32 +19,27 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegMovetoRel_h -#define SVGPathSegMovetoRel_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSegWithContext.h" namespace WebCore { -class SVGPathSegMovetoRel : public SVGPathSegSingleCoordinate { +class SVGPathSegMovetoRel final : public SVGPathSegSingleCoordinate { public: - static PassRefPtr<SVGPathSegMovetoRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y) + static Ref<SVGPathSegMovetoRel> create(const SVGPathElement& element, SVGPathSegRole role, float x, float y) { - return adoptRef(new SVGPathSegMovetoRel(element, role, x, y)); + return adoptRef(*new SVGPathSegMovetoRel(element, role, x, y)); } private: - SVGPathSegMovetoRel(SVGPathElement* element, SVGPathSegRole role, float x, float y) + SVGPathSegMovetoRel(const SVGPathElement& element, SVGPathSegRole role, float x, float y) : SVGPathSegSingleCoordinate(element, role, x, y) { } - virtual unsigned short pathSegType() const override { return PATHSEG_MOVETO_REL; } - virtual String pathSegTypeAsLetter() const override { return "m"; } + unsigned short pathSegType() const final { return PATHSEG_MOVETO_REL; } + String pathSegTypeAsLetter() const final { return "m"; } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSegMovetoRel.idl b/Source/WebCore/svg/SVGPathSegMovetoRel.idl index 38edb6b4b..217912dde 100644 --- a/Source/WebCore/svg/SVGPathSegMovetoRel.idl +++ b/Source/WebCore/svg/SVGPathSegMovetoRel.idl @@ -24,10 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPathSegMovetoRel : SVGPathSeg { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; +interface SVGPathSegMovetoRel : SVGPathSeg { + attribute unrestricted float x; + attribute unrestricted float y; }; diff --git a/Source/WebCore/svg/SVGPathSegWithContext.h b/Source/WebCore/svg/SVGPathSegWithContext.h index 701067227..60f392582 100644 --- a/Source/WebCore/svg/SVGPathSegWithContext.h +++ b/Source/WebCore/svg/SVGPathSegWithContext.h @@ -17,35 +17,36 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSegWithContext_h -#define SVGPathSegWithContext_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPathSegListPropertyTearOff.h" namespace WebCore { class SVGPathSegWithContext : public SVGPathSeg { public: - SVGPathSegWithContext(SVGPathElement* element, SVGPathSegRole role) + SVGPathSegWithContext(const SVGPathElement& element, SVGPathSegRole role) : m_role(role) - , m_element(element) + , m_element(element.createWeakPtr()) { } - SVGAnimatedProperty* animatedProperty() const + RefPtr<SVGAnimatedProperty> animatedProperty() const { + if (!m_element) + return nullptr; + switch (m_role) { case PathSegUndefinedRole: - return 0; + return nullptr; case PathSegUnalteredRole: return SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(m_element.get(), SVGPathElement::dPropertyInfo()); case PathSegNormalizedRole: // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists! - return 0; + return nullptr; }; - return 0; + return nullptr; } SVGPathElement* contextElement() const { return m_element.get(); } @@ -54,24 +55,20 @@ public: void setContextAndRole(SVGPathElement* element, SVGPathSegRole role) { m_role = role; - m_element = element; + m_element = element ? element->createWeakPtr() : WeakPtr<SVGPathElement>(); } protected: void commitChange() { - if (!m_element) { - ASSERT(m_role == PathSegUndefinedRole); + if (!m_element || m_role == PathSegUndefinedRole) return; - } - - ASSERT(m_role != PathSegUndefinedRole); m_element->pathSegListChanged(m_role); } private: SVGPathSegRole m_role; - RefPtr<SVGPathElement> m_element; + WeakPtr<SVGPathElement> m_element; }; class SVGPathSegSingleCoordinate : public SVGPathSegWithContext { @@ -91,7 +88,7 @@ public: } protected: - SVGPathSegSingleCoordinate(SVGPathElement* element, SVGPathSegRole role, float x, float y) + SVGPathSegSingleCoordinate(const SVGPathElement& element, SVGPathSegRole role, float x, float y) : SVGPathSegWithContext(element, role) , m_x(x) , m_y(y) @@ -104,6 +101,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPathSource.h b/Source/WebCore/svg/SVGPathSource.h index 836d3f0db..23e5bd25b 100644 --- a/Source/WebCore/svg/SVGPathSource.h +++ b/Source/WebCore/svg/SVGPathSource.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathSource_h -#define SVGPathSource_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSeg.h" namespace WebCore { @@ -50,6 +48,3 @@ public: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathSource_h diff --git a/Source/WebCore/svg/SVGPathStringBuilder.cpp b/Source/WebCore/svg/SVGPathStringBuilder.cpp index 3e16eef32..e2a245b54 100644 --- a/Source/WebCore/svg/SVGPathStringBuilder.cpp +++ b/Source/WebCore/svg/SVGPathStringBuilder.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -18,9 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathStringBuilder.h" + #include <wtf/text/WTFString.h> namespace WebCore { @@ -44,11 +44,6 @@ String SVGPathStringBuilder::result() return m_stringBuilder.toString(); } -void SVGPathStringBuilder::cleanup() -{ - m_stringBuilder.clear(); -} - void SVGPathStringBuilder::incrementPathSegmentCount() { } @@ -183,5 +178,3 @@ void SVGPathStringBuilder::closePath() } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathStringBuilder.h b/Source/WebCore/svg/SVGPathStringBuilder.h index 14e89b91f..df44f74be 100644 --- a/Source/WebCore/svg/SVGPathStringBuilder.h +++ b/Source/WebCore/svg/SVGPathStringBuilder.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -17,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathStringBuilder_h -#define SVGPathStringBuilder_h +#pragma once -#if ENABLE(SVG) #include "SVGPathConsumer.h" #include <wtf/text/StringBuilder.h> @@ -28,34 +27,30 @@ namespace WebCore { class SVGPathStringBuilder final : public SVGPathConsumer { public: - SVGPathStringBuilder(); - ~SVGPathStringBuilder(); + WEBCORE_EXPORT SVGPathStringBuilder(); + WEBCORE_EXPORT virtual ~SVGPathStringBuilder(); - String result(); + WEBCORE_EXPORT String result(); -private: - virtual void cleanup() override; - virtual void incrementPathSegmentCount() override; - virtual bool continueConsuming() override; + void incrementPathSegmentCount() final; + bool continueConsuming() final; // Used in UnalteredParsing/NormalizedParsing modes. - virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override; - virtual void lineTo(const FloatPoint&, PathCoordinateMode) override; - virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void closePath() override; + WEBCORE_EXPORT void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) final; + WEBCORE_EXPORT void lineTo(const FloatPoint&, PathCoordinateMode) final; + WEBCORE_EXPORT void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + WEBCORE_EXPORT void closePath() final; // Only used in UnalteredParsing mode. - virtual void lineToHorizontal(float, PathCoordinateMode) override; - virtual void lineToVertical(float, PathCoordinateMode) override; - virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override; - virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) override; + void lineToHorizontal(float, PathCoordinateMode) final; + void lineToVertical(float, PathCoordinateMode) final; + void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + WEBCORE_EXPORT void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) final; + void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) final; +private: StringBuilder m_stringBuilder; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathStringBuilder_h diff --git a/Source/WebCore/svg/SVGPathStringSource.cpp b/Source/WebCore/svg/SVGPathStringSource.cpp index 6cec31659..21776b5fe 100644 --- a/Source/WebCore/svg/SVGPathStringSource.cpp +++ b/Source/WebCore/svg/SVGPathStringSource.cpp @@ -19,8 +19,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathStringSource.h" #include "FloatPoint.h" @@ -136,7 +134,7 @@ template <typename CharacterType> static bool nextCommandHelper(const CharacterType*& current, SVGPathSegType previousCommand, SVGPathSegType& nextCommand) { // Check for remaining coordinates in the current command. - if ((*current == '+' || *current == '-' || *current == '.' || (*current >= '0' && *current <= '9')) + if ((*current == '+' || *current == '-' || *current == '.' || isASCIIDigit(*current)) && previousCommand != PathSegClosePath) { if (previousCommand == PathSegMoveToAbs) { nextCommand = PathSegLineToAbs; @@ -249,5 +247,3 @@ bool SVGPathStringSource::parseArcToSegment(float& rx, float& ry, float& angle, } } // namespace WebKit - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathStringSource.h b/Source/WebCore/svg/SVGPathStringSource.h index 9c2499d7c..e14b159e1 100644 --- a/Source/WebCore/svg/SVGPathStringSource.h +++ b/Source/WebCore/svg/SVGPathStringSource.h @@ -18,34 +18,32 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathStringSource_h -#define SVGPathStringSource_h +#pragma once -#if ENABLE(SVG) #include "SVGPathSource.h" #include <wtf/text/WTFString.h> namespace WebCore { -class SVGPathStringSource : public SVGPathSource { +class SVGPathStringSource final : public SVGPathSource { public: explicit SVGPathStringSource(const String&); private: - virtual bool hasMoreData() const override; - virtual bool moveToNextToken() override; - virtual bool parseSVGSegmentType(SVGPathSegType&) override; - virtual SVGPathSegType nextCommand(SVGPathSegType previousCommand) override; - - virtual bool parseMoveToSegment(FloatPoint&) override; - virtual bool parseLineToSegment(FloatPoint&) override; - virtual bool parseLineToHorizontalSegment(float&) override; - virtual bool parseLineToVerticalSegment(float&) override; - virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) override; - virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&) override; - virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) override; + bool hasMoreData() const final; + bool moveToNextToken() final; + bool parseSVGSegmentType(SVGPathSegType&) final; + SVGPathSegType nextCommand(SVGPathSegType previousCommand) final; + + bool parseMoveToSegment(FloatPoint&) final; + bool parseLineToSegment(FloatPoint&) final; + bool parseLineToHorizontalSegment(float&) final; + bool parseLineToVerticalSegment(float&) final; + bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) final; + bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) final; + bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) final; + bool parseCurveToQuadraticSmoothSegment(FloatPoint&) final; + bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) final; String m_string; bool m_is8BitSource; @@ -61,6 +59,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathStringSource_h diff --git a/Source/WebCore/svg/SVGPathTraversalStateBuilder.cpp b/Source/WebCore/svg/SVGPathTraversalStateBuilder.cpp index b5f53f909..de1a0cac9 100644 --- a/Source/WebCore/svg/SVGPathTraversalStateBuilder.cpp +++ b/Source/WebCore/svg/SVGPathTraversalStateBuilder.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> * Copyright (C) 2007 Eric Seidel <eric@webkit.org> + * Copyright (C) 2015 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -21,80 +22,53 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathTraversalStateBuilder.h" #include "PathTraversalState.h" namespace WebCore { -SVGPathTraversalStateBuilder::SVGPathTraversalStateBuilder() - : m_traversalState(0) +SVGPathTraversalStateBuilder::SVGPathTraversalStateBuilder(PathTraversalState& state, float desiredLength) + : m_traversalState(state) { + m_traversalState.setDesiredLength(desiredLength); } void SVGPathTraversalStateBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode) { - ASSERT(m_traversalState); - m_traversalState->m_totalLength += m_traversalState->moveTo(targetPoint); + m_traversalState.processPathElement(PathElementMoveToPoint, &targetPoint); } void SVGPathTraversalStateBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode) { - ASSERT(m_traversalState); - m_traversalState->m_totalLength += m_traversalState->lineTo(targetPoint); + m_traversalState.processPathElement(PathElementAddLineToPoint, &targetPoint); } void SVGPathTraversalStateBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode) { - ASSERT(m_traversalState); - m_traversalState->m_totalLength += m_traversalState->cubicBezierTo(point1, point2, targetPoint); -} + FloatPoint points[] = { point1, point2, targetPoint }; -void SVGPathTraversalStateBuilder::closePath() -{ - ASSERT(m_traversalState); - m_traversalState->m_totalLength += m_traversalState->closeSubpath(); + m_traversalState.processPathElement(PathElementAddCurveToPoint, points); } -void SVGPathTraversalStateBuilder::setDesiredLength(float desiredLength) +void SVGPathTraversalStateBuilder::closePath() { - ASSERT(m_traversalState); - m_traversalState->m_desiredLength = desiredLength; + m_traversalState.processPathElement(PathElementCloseSubpath, nullptr); } bool SVGPathTraversalStateBuilder::continueConsuming() { - ASSERT(m_traversalState); - m_traversalState->processSegment(); - return !m_traversalState->m_success; -} - -void SVGPathTraversalStateBuilder::incrementPathSegmentCount() -{ - ASSERT(m_traversalState); - ++m_traversalState->m_segmentIndex; -} - -unsigned SVGPathTraversalStateBuilder::pathSegmentIndex() -{ - ASSERT(m_traversalState); - return m_traversalState->m_segmentIndex; + return !m_traversalState.success(); } -float SVGPathTraversalStateBuilder::totalLength() +float SVGPathTraversalStateBuilder::totalLength() const { - ASSERT(m_traversalState); - return m_traversalState->m_totalLength; + return m_traversalState.totalLength(); } -SVGPoint SVGPathTraversalStateBuilder::currentPoint() +FloatPoint SVGPathTraversalStateBuilder::currentPoint() const { - ASSERT(m_traversalState); - return m_traversalState->m_current; + return m_traversalState.current(); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPathTraversalStateBuilder.h b/Source/WebCore/svg/SVGPathTraversalStateBuilder.h index 744e33b4d..6bd24d5d7 100644 --- a/Source/WebCore/svg/SVGPathTraversalStateBuilder.h +++ b/Source/WebCore/svg/SVGPathTraversalStateBuilder.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -18,51 +19,44 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathTraversalStateBuilder_h -#define SVGPathTraversalStateBuilder_h +#pragma once -#if ENABLE(SVG) #include "SVGPathConsumer.h" -#include "SVGPoint.h" namespace WebCore { +class FloatPoint; class PathTraversalState; -class SVGPathTraversalStateBuilder : public SVGPathConsumer { +class SVGPathTraversalStateBuilder final : public SVGPathConsumer { public: - SVGPathTraversalStateBuilder(); + SVGPathTraversalStateBuilder(PathTraversalState&, float desiredLength = 0); - unsigned pathSegmentIndex(); - float totalLength(); - SVGPoint currentPoint(); + unsigned pathSegmentIndex() const { return m_segmentIndex; } + float totalLength() const; + FloatPoint currentPoint() const; - void setCurrentTraversalState(PathTraversalState* traversalState) { m_traversalState = traversalState; } - void setDesiredLength(float); - virtual void incrementPathSegmentCount() override; - virtual bool continueConsuming() override; - virtual void cleanup() override { m_traversalState = 0; } + void incrementPathSegmentCount() final { ++m_segmentIndex; } + bool continueConsuming() final; private: // Used in UnalteredParsing/NormalizedParsing modes. - virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override; - virtual void lineTo(const FloatPoint&, PathCoordinateMode) override; - virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) override; - virtual void closePath() override; + void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) final; + void lineTo(const FloatPoint&, PathCoordinateMode) final; + void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) final; + void closePath() final; private: // Not used for PathTraversalState. - virtual void lineToHorizontal(float, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void lineToVertical(float, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); } - - PathTraversalState* m_traversalState; + void lineToHorizontal(float, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void lineToVertical(float, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + + PathTraversalState& m_traversalState; + unsigned m_segmentIndex { 0 }; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPathTraversalStateBuilder_h diff --git a/Source/WebCore/svg/SVGPathUtilities.cpp b/Source/WebCore/svg/SVGPathUtilities.cpp index 1c7ce1629..3e900e41b 100644 --- a/Source/WebCore/svg/SVGPathUtilities.cpp +++ b/Source/WebCore/svg/SVGPathUtilities.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -18,16 +19,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPathUtilities.h" +#include "FloatPoint.h" #include "Path.h" #include "PathTraversalState.h" #include "SVGPathBlender.h" #include "SVGPathBuilder.h" #include "SVGPathByteStreamBuilder.h" #include "SVGPathByteStreamSource.h" +#include "SVGPathConsumer.h" #include "SVGPathElement.h" #include "SVGPathParser.h" #include "SVGPathSegListBuilder.h" @@ -38,300 +39,173 @@ namespace WebCore { -static SVGPathBuilder* globalSVGPathBuilder(Path& result) -{ - static SVGPathBuilder* s_builder = 0; - if (!s_builder) - s_builder = new SVGPathBuilder; - - s_builder->setCurrentPath(&result); - return s_builder; -} - -static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result) -{ - static SVGPathSegListBuilder* s_builder = 0; - if (!s_builder) - s_builder = new SVGPathSegListBuilder; - - s_builder->setCurrentSVGPathElement(element); - s_builder->setCurrentSVGPathSegList(result); - s_builder->setCurrentSVGPathSegRole(role); - return s_builder; -} - -static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result) -{ - static SVGPathByteStreamBuilder* s_builder = 0; - if (!s_builder) - s_builder = new SVGPathByteStreamBuilder; - - s_builder->setCurrentByteStream(result); - return s_builder; -} - -static SVGPathStringBuilder* globalSVGPathStringBuilder() -{ - static SVGPathStringBuilder* s_builder = 0; - if (!s_builder) - s_builder = new SVGPathStringBuilder; - - return s_builder; -} - -static SVGPathTraversalStateBuilder* globalSVGPathTraversalStateBuilder(PathTraversalState& traversalState, float length) -{ - static SVGPathTraversalStateBuilder* s_builder = 0; - if (!s_builder) - s_builder = new SVGPathTraversalStateBuilder; - - s_builder->setCurrentTraversalState(&traversalState); - s_builder->setDesiredLength(length); - return s_builder; -} - -static SVGPathParser* globalSVGPathParser(SVGPathSource* source, SVGPathConsumer* consumer) -{ - static SVGPathParser* s_parser = 0; - if (!s_parser) - s_parser = new SVGPathParser; - - s_parser->setCurrentSource(source); - s_parser->setCurrentConsumer(consumer); - return s_parser; -} - -static SVGPathBlender* globalSVGPathBlender() -{ - static SVGPathBlender* s_blender = 0; - if (!s_blender) - s_blender = new SVGPathBlender; - - return s_blender; -} - bool buildPathFromString(const String& d, Path& result) { if (d.isEmpty()) return true; - SVGPathBuilder* builder = globalSVGPathBuilder(result); - - auto source = std::make_unique<SVGPathStringSource>(d); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(NormalizedParsing); - parser->cleanup(); - return ok; + SVGPathBuilder builder(result); + SVGPathStringSource source(d); + return SVGPathParser::parse(source, builder); } -bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream* result, PathParsingMode parsingMode) +bool buildSVGPathByteStreamFromSVGPathSegListValues(const SVGPathSegListValues& list, SVGPathByteStream& result, PathParsingMode parsingMode) { - ASSERT(result); - result->clear(); + result.clear(); if (list.isEmpty()) return true; - SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result); - - auto source = std::make_unique<SVGPathSegListSource>(list); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(parsingMode); - parser->cleanup(); - return ok; + SVGPathSegListSource source(list); + return SVGPathParser::parseToByteStream(source, result, parsingMode); } -bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg> pathSeg, SVGPathByteStream* result, PathParsingMode parsingMode) +bool appendSVGPathByteStreamFromSVGPathSeg(RefPtr<SVGPathSeg>&& pathSeg, SVGPathByteStream& result, PathParsingMode parsingMode) { - ASSERT(result); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists! ASSERT(parsingMode == UnalteredParsing); - SVGPathSegList appendedItemList(PathSegUnalteredRole); - appendedItemList.append(pathSeg); - auto appendedByteStream = std::make_unique<SVGPathByteStream>(); + SVGPathSegListValues appendedItemList(PathSegUnalteredRole); + appendedItemList.append(WTFMove(pathSeg)); - SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(appendedByteStream.get()); - auto source = std::make_unique<SVGPathSegListSource>(appendedItemList); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(parsingMode, false); - parser->cleanup(); + SVGPathByteStream appendedByteStream; + SVGPathSegListSource source(appendedItemList); + bool ok = SVGPathParser::parseToByteStream(source, result, parsingMode, false); if (ok) - result->append(appendedByteStream.get()); + result.append(appendedByteStream); return ok; } -bool buildPathFromByteStream(SVGPathByteStream* stream, Path& result) +bool buildPathFromByteStream(const SVGPathByteStream& stream, Path& result) { - ASSERT(stream); - if (stream->isEmpty()) + if (stream.isEmpty()) return true; - SVGPathBuilder* builder = globalSVGPathBuilder(result); - - auto source = std::make_unique<SVGPathByteStreamSource>(stream); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(NormalizedParsing); - parser->cleanup(); - return ok; + SVGPathBuilder builder(result); + SVGPathByteStreamSource source(stream); + return SVGPathParser::parse(source, builder); } -bool buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode) +bool buildSVGPathSegListValuesFromByteStream(const SVGPathByteStream& stream, SVGPathElement& element, SVGPathSegListValues& result, PathParsingMode parsingMode) { - ASSERT(stream); - if (stream->isEmpty()) + if (stream.isEmpty()) return true; - SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result); - - auto source = std::make_unique<SVGPathByteStreamSource>(stream); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(parsingMode); - parser->cleanup(); - return ok; + SVGPathSegListBuilder builder(element, result, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole); + SVGPathByteStreamSource source(stream); + return SVGPathParser::parse(source, builder, parsingMode); } -bool buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode) +bool buildStringFromByteStream(const SVGPathByteStream& stream, String& result, PathParsingMode parsingMode) { - ASSERT(stream); - if (stream->isEmpty()) + if (stream.isEmpty()) return true; - SVGPathStringBuilder* builder = globalSVGPathStringBuilder(); - - auto source = std::make_unique<SVGPathByteStreamSource>(stream); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(parsingMode); - result = builder->result(); - parser->cleanup(); - return ok; + SVGPathByteStreamSource source(stream); + return SVGPathParser::parseToString(source, result, parsingMode); } -bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode) +bool buildStringFromSVGPathSegListValues(const SVGPathSegListValues& list, String& result, PathParsingMode parsingMode) { result = String(); if (list.isEmpty()) return true; - SVGPathStringBuilder* builder = globalSVGPathStringBuilder(); - - auto source = std::make_unique<SVGPathSegListSource>(list); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(parsingMode); - result = builder->result(); - parser->cleanup(); - return ok; + SVGPathSegListSource source(list); + return SVGPathParser::parseToString(source, result, parsingMode); } -bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream* result, PathParsingMode parsingMode) +bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream& result, PathParsingMode parsingMode) { - ASSERT(result); - result->clear(); + result.clear(); if (d.isEmpty()) return true; - SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result); - - auto source = std::make_unique<SVGPathStringSource>(d); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(parsingMode); - parser->cleanup(); - return ok; + SVGPathStringSource source(d); + return SVGPathParser::parseToByteStream(source, result, parsingMode); } -bool buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, SVGPathByteStream* result, float progress) +bool canBlendSVGPathByteStreams(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream) { - ASSERT(fromStream); - ASSERT(toStream); - ASSERT(result); - ASSERT(toStream != result); + SVGPathByteStreamSource fromSource(fromStream); + SVGPathByteStreamSource toSource(toStream); + return SVGPathBlender::canBlendPaths(fromSource, toSource); +} - result->clear(); - if (toStream->isEmpty()) +bool buildAnimatedSVGPathByteStream(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream, SVGPathByteStream& result, float progress) +{ + ASSERT(&toStream != &result); + result.clear(); + if (toStream.isEmpty()) return true; - SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result); + SVGPathByteStreamBuilder builder(result); - auto fromSource = std::make_unique<SVGPathByteStreamSource>(fromStream); - auto toSource = std::make_unique<SVGPathByteStreamSource>(toStream); - SVGPathBlender* blender = globalSVGPathBlender(); - bool ok = blender->blendAnimatedPath(progress, fromSource.get(), toSource.get(), builder); - blender->cleanup(); - return ok; + SVGPathByteStreamSource fromSource(fromStream); + SVGPathByteStreamSource toSource(toStream); + return SVGPathBlender::blendAnimatedPath(fromSource, toSource, builder, progress); } -bool addToSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* byStream, unsigned repeatCount) +bool addToSVGPathByteStream(SVGPathByteStream& streamToAppendTo, const SVGPathByteStream& byStream, unsigned repeatCount) { - ASSERT(fromStream); - ASSERT(byStream); - if (fromStream->isEmpty() || byStream->isEmpty()) + // Why return when streamToAppendTo is empty? Don't we still need to append? + if (streamToAppendTo.isEmpty() || byStream.isEmpty()) return true; - SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(fromStream); + // Is it OK to make the SVGPathByteStreamBuilder from a stream, and then clear that stream? + SVGPathByteStreamBuilder builder(streamToAppendTo); - auto fromStreamCopy = fromStream->copy(); - fromStream->clear(); + SVGPathByteStream fromStreamCopy = streamToAppendTo; + streamToAppendTo.clear(); - auto fromSource = std::make_unique<SVGPathByteStreamSource>(fromStreamCopy.get()); - auto bySource = std::make_unique<SVGPathByteStreamSource>(byStream); - SVGPathBlender* blender = globalSVGPathBlender(); - bool ok = blender->addAnimatedPath(fromSource.get(), bySource.get(), builder, repeatCount); - blender->cleanup(); - return ok; + SVGPathByteStreamSource fromSource(fromStreamCopy); + SVGPathByteStreamSource bySource(byStream); + return SVGPathBlender::addAnimatedPath(fromSource, bySource, builder, repeatCount); } -bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg) +bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream, float length, unsigned& pathSeg) { - ASSERT(stream); - if (stream->isEmpty()) + if (stream.isEmpty()) return false; - PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength); - SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length); + PathTraversalState traversalState(PathTraversalState::Action::SegmentAtLength); + SVGPathTraversalStateBuilder builder(traversalState, length); - auto source = std::make_unique<SVGPathByteStreamSource>(stream); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(NormalizedParsing); - pathSeg = builder->pathSegmentIndex(); - parser->cleanup(); + SVGPathByteStreamSource source(stream); + bool ok = SVGPathParser::parse(source, builder); + pathSeg = builder.pathSegmentIndex(); return ok; } -bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength) +bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float& totalLength) { - ASSERT(stream); - if (stream->isEmpty()) + if (stream.isEmpty()) return false; - PathTraversalState traversalState(PathTraversalState::TraversalTotalLength); - SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0); + PathTraversalState traversalState(PathTraversalState::Action::TotalLength); - auto source = std::make_unique<SVGPathByteStreamSource>(stream); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(NormalizedParsing); - totalLength = builder->totalLength(); - parser->cleanup(); + SVGPathTraversalStateBuilder builder(traversalState); + + SVGPathByteStreamSource source(stream); + bool ok = SVGPathParser::parse(source, builder); + totalLength = builder.totalLength(); return ok; } -bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, SVGPoint& point) +bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float length, FloatPoint& point) { - ASSERT(stream); - if (stream->isEmpty()) + if (stream.isEmpty()) return false; - PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength); - SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length); + PathTraversalState traversalState(PathTraversalState::Action::VectorAtLength); + + SVGPathTraversalStateBuilder builder(traversalState, length); - auto source = std::make_unique<SVGPathByteStreamSource>(stream); - SVGPathParser* parser = globalSVGPathParser(source.get(), builder); - bool ok = parser->parsePathDataFromSource(NormalizedParsing); - point = builder->currentPoint(); - parser->cleanup(); + SVGPathByteStreamSource source(stream); + bool ok = SVGPathParser::parse(source, builder); + point = builder.currentPoint(); return ok; } } - -#endif diff --git a/Source/WebCore/svg/SVGPathUtilities.h b/Source/WebCore/svg/SVGPathUtilities.h index 7157a98ae..79e7d729e 100644 --- a/Source/WebCore/svg/SVGPathUtilities.h +++ b/Source/WebCore/svg/SVGPathUtilities.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -17,46 +18,43 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPathUtilities_h -#define SVGPathUtilities_h +#pragma once -#if ENABLE(SVG) #include "SVGPathConsumer.h" -#include "SVGPoint.h" #include <wtf/text/WTFString.h> namespace WebCore { +class FloatPoint; class Path; class SVGPathByteStream; class SVGPathElement; class SVGPathSeg; -class SVGPathSegList; +class SVGPathSegListValues; // String/SVGPathByteStream -> Path bool buildPathFromString(const String&, Path&); -bool buildPathFromByteStream(SVGPathByteStream*, Path&); +bool buildPathFromByteStream(const SVGPathByteStream&, Path&); -// SVGPathSegList/String -> SVGPathByteStream -bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList&, SVGPathByteStream*, PathParsingMode); -bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg>, SVGPathByteStream*, PathParsingMode); -bool buildSVGPathByteStreamFromString(const String&, SVGPathByteStream*, PathParsingMode); +// SVGPathSegListValues/String -> SVGPathByteStream +bool buildSVGPathByteStreamFromSVGPathSegListValues(const SVGPathSegListValues&, SVGPathByteStream& result, PathParsingMode); +bool appendSVGPathByteStreamFromSVGPathSeg(RefPtr<SVGPathSeg>&&, SVGPathByteStream&, PathParsingMode); +bool buildSVGPathByteStreamFromString(const String&, SVGPathByteStream&, PathParsingMode); -// SVGPathByteStream/SVGPathSegList -> String -bool buildStringFromByteStream(SVGPathByteStream*, String&, PathParsingMode); -bool buildStringFromSVGPathSegList(const SVGPathSegList&, String&, PathParsingMode); +// SVGPathByteStream/SVGPathSegListValues -> String +bool buildStringFromByteStream(const SVGPathByteStream&, String&, PathParsingMode); +bool buildStringFromSVGPathSegListValues(const SVGPathSegListValues&, String&, PathParsingMode); -// SVGPathByteStream -> SVGPathSegList -bool buildSVGPathSegListFromByteStream(SVGPathByteStream*, SVGPathElement*, SVGPathSegList&, PathParsingMode); +// SVGPathByteStream -> SVGPathSegListValues +bool buildSVGPathSegListValuesFromByteStream(const SVGPathByteStream&, SVGPathElement&, SVGPathSegListValues&, PathParsingMode); -bool buildAnimatedSVGPathByteStream(SVGPathByteStream*, SVGPathByteStream*, SVGPathByteStream*, float); -bool addToSVGPathByteStream(SVGPathByteStream*, SVGPathByteStream*, unsigned repeatCount = 1); +bool canBlendSVGPathByteStreams(const SVGPathByteStream& from, const SVGPathByteStream& to); -bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream*, float length, unsigned& pathSeg); -bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream*, float& totalLength); -bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream*, float length, SVGPoint&); +bool buildAnimatedSVGPathByteStream(const SVGPathByteStream& from, const SVGPathByteStream& to, SVGPathByteStream& result, float progress); +bool addToSVGPathByteStream(SVGPathByteStream& streamToAppendTo, const SVGPathByteStream& from, unsigned repeatCount = 1); -} // namespace WebCore +bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream&, float length, unsigned& pathSeg); +bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream&, float& totalLength); +bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream&, float length, FloatPoint&); -#endif // ENABLE(SVG) -#endif // SVGPathUtilities_h +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGPatternElement.cpp b/Source/WebCore/svg/SVGPatternElement.cpp index ec4c0ba6f..b136b4fca 100644 --- a/Source/WebCore/svg/SVGPatternElement.cpp +++ b/Source/WebCore/svg/SVGPatternElement.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -20,12 +21,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPatternElement.h" #include "AffineTransform.h" -#include "Attribute.h" #include "Document.h" #include "FloatConversion.h" #include "GraphicsContext.h" @@ -33,14 +31,14 @@ #include "PatternAttributes.h" #include "RenderSVGContainer.h" #include "RenderSVGResourcePattern.h" -#include "SVGElementInstance.h" #include "SVGFitToViewBox.h" #include "SVGGraphicsElement.h" #include "SVGNames.h" #include "SVGRenderSupport.h" -#include "SVGSVGElement.h" +#include "SVGStringList.h" #include "SVGTransformable.h" #include "XLinkNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -86,70 +84,71 @@ inline SVGPatternElement::SVGPatternElement(const QualifiedName& tagName, Docume registerAnimatedPropertiesForSVGPatternElement(); } -PassRefPtr<SVGPatternElement> SVGPatternElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGPatternElement> SVGPatternElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGPatternElement(tagName, document)); + return adoptRef(*new SVGPatternElement(tagName, document)); } bool SVGPatternElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGURIReference::addSupportedAttributes(supportedAttributes); SVGTests::addSupportedAttributes(supportedAttributes); SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); SVGFitToViewBox::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::patternUnitsAttr); - supportedAttributes.add(SVGNames::patternContentUnitsAttr); - supportedAttributes.add(SVGNames::patternTransformAttr); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); + supportedAttributes.get().add(SVGNames::patternUnitsAttr); + supportedAttributes.get().add(SVGNames::patternContentUnitsAttr); + supportedAttributes.get().add(SVGNames::patternTransformAttr); + supportedAttributes.get().add(SVGNames::xAttr); + supportedAttributes.get().add(SVGNames::yAttr); + supportedAttributes.get().add(SVGNames::widthAttr); + supportedAttributes.get().add(SVGNames::heightAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGPatternElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - SVGParsingError parseError = NoError; - - if (!isSupportedAttribute(name)) - SVGElement::parseAttribute(name, value); - else if (name == SVGNames::patternUnitsAttr) { - SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); + if (name == SVGNames::patternUnitsAttr) { + auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); if (propertyValue > 0) setPatternUnitsBaseValue(propertyValue); return; - } else if (name == SVGNames::patternContentUnitsAttr) { - SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); + } + if (name == SVGNames::patternContentUnitsAttr) { + auto propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); if (propertyValue > 0) setPatternContentUnitsBaseValue(propertyValue); return; - } else if (name == SVGNames::patternTransformAttr) { - SVGTransformList newList; + } + if (name == SVGNames::patternTransformAttr) { + SVGTransformListValues newList; newList.parse(value); detachAnimatedPatternTransformListWrappers(newList.size()); setPatternTransformBaseValue(newList); return; - } else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + } + + SVGParsingError parseError = NoError; + + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); - else if (SVGURIReference::parseAttribute(name, value) - || SVGTests::parseAttribute(name, value) - || SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value) - || SVGFitToViewBox::parseAttribute(this, name, value)) { - } else - ASSERT_NOT_REACHED(); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); reportAttributeParsingError(parseError, name, value); + + SVGElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); + SVGTests::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGFitToViewBox::parseAttribute(this, name, value); } void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName) @@ -159,13 +158,15 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - + InstanceInvalidationGuard guard(*this); + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr - || attrName == SVGNames::heightAttr) - updateRelativeLengthsInformation(); + || attrName == SVGNames::heightAttr) { + invalidateSVGPresentationAttributeStyle(); + return; + } if (RenderObject* object = renderer()) object->setNeedsLayout(); @@ -182,68 +183,45 @@ void SVGPatternElement::childrenChanged(const ChildChange& change) object->setNeedsLayout(); } -RenderPtr<RenderElement> SVGPatternElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGPatternElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourcePattern>(*this, std::move(style)); + return createRenderer<RenderSVGResourcePattern>(*this, WTFMove(style)); } -static void setPatternAttributes(const SVGPatternElement& element, PatternAttributes& attributes) +void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes) const { - if (!attributes.hasX() && element.hasAttribute(SVGNames::xAttr)) - attributes.setX(element.x()); + if (!attributes.hasX() && hasAttribute(SVGNames::xAttr)) + attributes.setX(x()); - if (!attributes.hasY() && element.hasAttribute(SVGNames::yAttr)) - attributes.setY(element.y()); + if (!attributes.hasY() && hasAttribute(SVGNames::yAttr)) + attributes.setY(y()); - if (!attributes.hasWidth() && element.hasAttribute(SVGNames::widthAttr)) - attributes.setWidth(element.width()); + if (!attributes.hasWidth() && hasAttribute(SVGNames::widthAttr)) + attributes.setWidth(width()); - if (!attributes.hasHeight() && element.hasAttribute(SVGNames::heightAttr)) - attributes.setHeight(element.height()); + if (!attributes.hasHeight() && hasAttribute(SVGNames::heightAttr)) + attributes.setHeight(height()); - if (!attributes.hasViewBox() && element.hasAttribute(SVGNames::viewBoxAttr) && element.viewBoxIsValid()) - attributes.setViewBox(element.viewBox()); + if (!attributes.hasViewBox() && hasAttribute(SVGNames::viewBoxAttr) && viewBoxIsValid()) + attributes.setViewBox(viewBox()); - if (!attributes.hasPreserveAspectRatio() && element.hasAttribute(SVGNames::preserveAspectRatioAttr)) - attributes.setPreserveAspectRatio(element.preserveAspectRatio()); + if (!attributes.hasPreserveAspectRatio() && hasAttribute(SVGNames::preserveAspectRatioAttr)) + attributes.setPreserveAspectRatio(preserveAspectRatio()); - if (!attributes.hasPatternUnits() && element.hasAttribute(SVGNames::patternUnitsAttr)) - attributes.setPatternUnits(element.patternUnits()); + if (!attributes.hasPatternUnits() && hasAttribute(SVGNames::patternUnitsAttr)) + attributes.setPatternUnits(patternUnits()); - if (!attributes.hasPatternContentUnits() && element.hasAttribute(SVGNames::patternContentUnitsAttr)) - attributes.setPatternContentUnits(element.patternContentUnits()); + if (!attributes.hasPatternContentUnits() && hasAttribute(SVGNames::patternContentUnitsAttr)) + attributes.setPatternContentUnits(patternContentUnits()); - if (!attributes.hasPatternTransform() && element.hasAttribute(SVGNames::patternTransformAttr)) { + if (!attributes.hasPatternTransform() && hasAttribute(SVGNames::patternTransformAttr)) { AffineTransform transform; - element.patternTransform().concatenate(transform); + patternTransform().concatenate(transform); attributes.setPatternTransform(transform); } - if (!attributes.hasPatternContentElement() && element.childElementCount()) - attributes.setPatternContentElement(&element); -} - -void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes) const -{ - HashSet<const SVGPatternElement*> processedPatterns; - const SVGPatternElement* current = this; - - while (true) { - setPatternAttributes(*current, attributes); - processedPatterns.add(current); - - // Respect xlink:href, take attributes from referenced element - Element* refElement = SVGURIReference::targetElementFromIRIString(current->href(), document()); - if (refElement && isSVGPatternElement(refElement)) { - current = toSVGPatternElement(refElement); - - // Cycle detection - if (processedPatterns.contains(current)) - return; - } else - return; - } - ASSERT_NOT_REACHED(); + if (!attributes.hasPatternContentElement() && childElementCount()) + attributes.setPatternContentElement(this); } AffineTransform SVGPatternElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope) const @@ -253,14 +231,19 @@ AffineTransform SVGPatternElement::localCoordinateSpaceTransform(SVGLocatable::C return matrix; } -bool SVGPatternElement::selfHasRelativeLengths() const +Ref<SVGStringList> SVGPatternElement::requiredFeatures() { - return x().isRelative() - || y().isRelative() - || width().isRelative() - || height().isRelative(); + return SVGTests::requiredFeatures(*this); } +Ref<SVGStringList> SVGPatternElement::requiredExtensions() +{ + return SVGTests::requiredExtensions(*this); } -#endif // ENABLE(SVG) +Ref<SVGStringList> SVGPatternElement::systemLanguage() +{ + return SVGTests::systemLanguage(*this); +} + +} diff --git a/Source/WebCore/svg/SVGPatternElement.h b/Source/WebCore/svg/SVGPatternElement.h index eb71ea32e..7e7e9779f 100644 --- a/Source/WebCore/svg/SVGPatternElement.h +++ b/Source/WebCore/svg/SVGPatternElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPatternElement_h -#define SVGPatternElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedLength.h" @@ -40,32 +38,33 @@ namespace WebCore { struct PatternAttributes; -class SVGPatternElement final : public SVGElement, - public SVGURIReference, - public SVGTests, - public SVGExternalResourcesRequired, - public SVGFitToViewBox { +class SVGPatternElement final : public SVGElement, public SVGURIReference, public SVGTests, public SVGExternalResourcesRequired, public SVGFitToViewBox { public: - static PassRefPtr<SVGPatternElement> create(const QualifiedName&, Document&); + static Ref<SVGPatternElement> create(const QualifiedName&, Document&); void collectPatternAttributes(PatternAttributes&) const; - virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const override; + AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const final; + + // SVGTests + Ref<SVGStringList> requiredFeatures(); + Ref<SVGStringList> requiredExtensions(); + Ref<SVGStringList> systemLanguage(); private: SVGPatternElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool needsPendingResourceHandling() const override { return false; } + bool isValid() const final { return SVGTests::isValid(); } + bool needsPendingResourceHandling() const final { return false; } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual void childrenChanged(const ChildChange&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; + void childrenChanged(const ChildChange&) final; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final { return true; } BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPatternElement) DECLARE_ANIMATED_LENGTH(X, x) @@ -75,21 +74,16 @@ private: DECLARE_ANIMATED_ENUMERATION(PatternUnits, patternUnits, SVGUnitTypes::SVGUnitType) DECLARE_ANIMATED_ENUMERATION(PatternContentUnits, patternContentUnits, SVGUnitTypes::SVGUnitType) DECLARE_ANIMATED_TRANSFORM_LIST(PatternTransform, patternTransform) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) DECLARE_ANIMATED_RECT(ViewBox, viewBox) DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) END_DECLARE_ANIMATED_PROPERTIES // SVGTests - virtual void synchronizeRequiredFeatures() override { SVGTests::synchronizeRequiredFeatures(this); } - virtual void synchronizeRequiredExtensions() override { SVGTests::synchronizeRequiredExtensions(this); } - virtual void synchronizeSystemLanguage() override { SVGTests::synchronizeSystemLanguage(this); } + void synchronizeRequiredFeatures() final { SVGTests::synchronizeRequiredFeatures(*this); } + void synchronizeRequiredExtensions() final { SVGTests::synchronizeRequiredExtensions(*this); } + void synchronizeSystemLanguage() final { SVGTests::synchronizeSystemLanguage(*this); } }; -NODE_TYPE_CASTS(SVGPatternElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPatternElement.idl b/Source/WebCore/svg/SVGPatternElement.idl index 2f67cae33..5fecc654c 100644 --- a/Source/WebCore/svg/SVGPatternElement.idl +++ b/Source/WebCore/svg/SVGPatternElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGPatternElement : SVGElement { +interface SVGPatternElement : SVGElement { readonly attribute SVGAnimatedEnumeration patternUnits; readonly attribute SVGAnimatedEnumeration patternContentUnits; readonly attribute SVGAnimatedTransformList patternTransform; diff --git a/Source/WebCore/svg/SVGPoint.h b/Source/WebCore/svg/SVGPoint.h index 32c1537d7..e9c6dc917 100644 --- a/Source/WebCore/svg/SVGPoint.h +++ b/Source/WebCore/svg/SVGPoint.h @@ -23,19 +23,102 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGPoint_h -#define SVGPoint_h - -#if ENABLE(SVG) +#pragma once +#include "ExceptionCode.h" #include "FloatPoint.h" +#include "SVGMatrix.h" +#include "SVGPropertyTearOff.h" namespace WebCore { -typedef FloatPoint SVGPoint; +class SVGPoint : public SVGPropertyTearOff<FloatPoint> { +public: + static Ref<SVGPoint> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, FloatPoint& value) + { + return adoptRef(*new SVGPoint(animatedProperty, role, value)); + } -} // namespace WebCore + static Ref<SVGPoint> create(const FloatPoint& initialValue = { }) + { + return adoptRef(*new SVGPoint(initialValue)); + } + + static Ref<SVGPoint> create(const FloatPoint* initialValue) + { + return adoptRef(*new SVGPoint(initialValue)); + } + + template<typename T> static ExceptionOr<Ref<SVGPoint>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } + + float x() + { + return propertyReference().x(); + } + + ExceptionOr<void> setX(float xValue) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setX(xValue); + commitChange(); + + return { }; + } + + float y() + { + return propertyReference().y(); + } + + ExceptionOr<void> setY(float xValue) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; -#endif // ENABLE(SVG) + propertyReference().setY(xValue); + commitChange(); -#endif // SVGPoint_h + return { }; + } + + ExceptionOr<Ref<SVGPoint>> matrixTransform(SVGMatrix& matrix) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto newPoint = propertyReference().matrixTransform(matrix.propertyReference()); + commitChange(); + + return SVGPoint::create(newPoint); + } + +protected: + SVGPoint(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, FloatPoint& value) + : SVGPropertyTearOff<FloatPoint>(&animatedProperty, role, value) + { + } + + SVGPoint(SVGPropertyRole role, FloatPoint& value) + : SVGPropertyTearOff<FloatPoint>(nullptr, role, value) + { + } + + explicit SVGPoint(const FloatPoint& initialValue) + : SVGPropertyTearOff<FloatPoint>(initialValue) + { + } + + explicit SVGPoint(const FloatPoint* initialValue) + : SVGPropertyTearOff<FloatPoint>(initialValue) + { + } +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGPoint.idl b/Source/WebCore/svg/SVGPoint.idl index 48e6756f5..b4ced4d41 100644 --- a/Source/WebCore/svg/SVGPoint.idl +++ b/Source/WebCore/svg/SVGPoint.idl @@ -21,11 +21,11 @@ */ [ - Conditional=SVG, + SkipVTableValidation ] interface SVGPoint { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; + [SetterMayThrowException] attribute unrestricted float x; + [SetterMayThrowException] attribute unrestricted float y; - [StrictTypeChecking] SVGPoint matrixTransform(SVGMatrix matrix); + [MayThrowException, NewObject] SVGPoint matrixTransform(SVGMatrix matrix); }; diff --git a/Source/WebCore/svg/SVGPointList.h b/Source/WebCore/svg/SVGPointList.h index 39cfbea1b..b0c2a1031 100644 --- a/Source/WebCore/svg/SVGPointList.h +++ b/Source/WebCore/svg/SVGPointList.h @@ -1,47 +1,52 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGPointList_h -#define SVGPointList_h +#pragma once -#if ENABLE(SVG) +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGListPropertyTearOff.h" #include "SVGPoint.h" -#include "SVGPropertyTraits.h" -#include <wtf/Vector.h> +#include "SVGPointListValues.h" namespace WebCore { -class SVGPointList : public Vector<SVGPoint> { +class SVGPointList : public SVGListPropertyTearOff<SVGPointListValues> { public: - SVGPointList() { } - - String valueAsString() const; -}; - -template<> -struct SVGPropertyTraits<SVGPointList> { - static SVGPointList initialValue() { return SVGPointList(); } - typedef SVGPoint ListItemType; + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<SVGPointListValues>; + using ListWrapperCache = AnimatedListPropertyTearOff::ListWrapperCache; + + static Ref<SVGPointList> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGPointListValues& values, ListWrapperCache& wrappers) + { + return adoptRef(*new SVGPointList(animatedProperty, role, values, wrappers)); + } + +private: + SVGPointList(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGPointListValues& values, ListWrapperCache& wrappers) + : SVGListPropertyTearOff<SVGPointListValues>(animatedProperty, role, values, wrappers) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPointList.idl b/Source/WebCore/svg/SVGPointList.idl index ff89c53f6..0e1597fb5 100644 --- a/Source/WebCore/svg/SVGPointList.idl +++ b/Source/WebCore/svg/SVGPointList.idl @@ -23,17 +23,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGPointList { +interface SVGPointList { readonly attribute unsigned long numberOfItems; - [RaisesException] void clear(); - [StrictTypeChecking, RaisesException] SVGPoint initialize(SVGPoint item); - [StrictTypeChecking, RaisesException] SVGPoint getItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGPoint insertItemBefore(SVGPoint item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGPoint replaceItem(SVGPoint item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGPoint removeItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGPoint appendItem(SVGPoint item); + [MayThrowException] void clear(); + [MayThrowException] SVGPoint initialize(SVGPoint item); + [MayThrowException] SVGPoint getItem(unsigned long index); + [MayThrowException] SVGPoint insertItemBefore(SVGPoint item, unsigned long index); + [MayThrowException] SVGPoint replaceItem(SVGPoint item, unsigned long index); + [MayThrowException] SVGPoint removeItem(unsigned long index); + [MayThrowException] SVGPoint appendItem(SVGPoint item); }; - diff --git a/Source/WebCore/svg/SVGPointList.cpp b/Source/WebCore/svg/SVGPointListValues.cpp index 9cedf8e46..d81e6a237 100644 --- a/Source/WebCore/svg/SVGPointList.cpp +++ b/Source/WebCore/svg/SVGPointListValues.cpp @@ -19,16 +19,14 @@ */ #include "config.h" - -#if ENABLE(SVG) -#include "SVGPointList.h" +#include "SVGPointListValues.h" #include <wtf/text/StringBuilder.h> #include <wtf/text/WTFString.h> namespace WebCore { -String SVGPointList::valueAsString() const +String SVGPointListValues::valueAsString() const { StringBuilder builder; @@ -37,7 +35,7 @@ String SVGPointList::valueAsString() const if (i > 0) builder.append(' '); // FIXME: Shouldn't we use commas to seperate? - const SVGPoint& point = at(i); + const auto& point = at(i); builder.appendNumber(point.x()); builder.append(' '); builder.appendNumber(point.y()); @@ -47,5 +45,3 @@ String SVGPointList::valueAsString() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPointListValues.h b/Source/WebCore/svg/SVGPointListValues.h new file mode 100644 index 000000000..abab82204 --- /dev/null +++ b/Source/WebCore/svg/SVGPointListValues.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005 Rob Buis <buis@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. + */ + +#pragma once + +#include "FloatPoint.h" +#include "SVGPropertyTraits.h" +#include <wtf/Vector.h> + +namespace WebCore { + +class SVGPoint; +class SVGPointList; + +class SVGPointListValues final : public Vector<FloatPoint> { +public: + String valueAsString() const; +}; + +template<> struct SVGPropertyTraits<SVGPointListValues> { + static SVGPointListValues initialValue() { return { }; } + + using ListItemType = FloatPoint; + using ListItemTearOff = SVGPoint; + using ListPropertyTearOff = SVGPointList; +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGPolyElement.cpp b/Source/WebCore/svg/SVGPolyElement.cpp index 56c90d9c8..7951a189f 100644 --- a/Source/WebCore/svg/SVGPolyElement.cpp +++ b/Source/WebCore/svg/SVGPolyElement.cpp @@ -19,26 +19,23 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPolyElement.h" -#include "Attribute.h" #include "Document.h" -#include "FloatPoint.h" #include "RenderSVGPath.h" #include "RenderSVGResource.h" #include "SVGAnimatedPointList.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGParserUtilities.h" +#include "SVGPoint.h" +#include "SVGPointList.h" namespace WebCore { // Define custom animated property 'points'. const SVGPropertyInfo* SVGPolyElement::pointsPropertyInfo() { - static const SVGPropertyInfo* s_propertyInfo = 0; + static const SVGPropertyInfo* s_propertyInfo = nullptr; if (!s_propertyInfo) { s_propertyInfo = new SVGPropertyInfo(AnimatedPoints, PropertyIsReadWrite, @@ -65,105 +62,79 @@ SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document& document) registerAnimatedPropertiesForSVGPolyElement(); } -bool SVGPolyElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::pointsAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGPolyElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGGraphicsElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::pointsAttr) { - SVGPointList newList; + SVGPointListValues newList; if (!pointsListFromSVGData(newList, value)) - document().accessSVGExtensions()->reportError("Problem parsing points=\"" + value + "\""); + document().accessSVGExtensions().reportError("Problem parsing points=\"" + value + "\""); - if (SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGPolyElement, SVGAnimatedPointList>(this, pointsPropertyInfo())) - static_cast<SVGAnimatedPointList*>(wrapper)->detachListWrappers(newList.size()); + if (auto wrapper = SVGAnimatedProperty::lookupWrapper<SVGPolyElement, SVGAnimatedPointList>(this, pointsPropertyInfo())) + static_pointer_cast<SVGAnimatedPointList>(wrapper)->detachListWrappers(newList.size()); m_points.value = newList; return; } - if (SVGLangSpace::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGGraphicsElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - RenderSVGShape* renderer = toRenderSVGShape(this->renderer()); - if (!renderer) - return; - if (attrName == SVGNames::pointsAttr) { - renderer->setNeedsShapeUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + if (auto* renderer = downcast<RenderSVGPath>(this->renderer())) { + InstanceInvalidationGuard guard(*this); + renderer->setNeedsShapeUpdate(); + RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } return; } if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + if (auto* renderer = downcast<RenderSVGPath>(this->renderer())) { + InstanceInvalidationGuard guard(*this); + RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } return; } - ASSERT_NOT_REACHED(); + SVGGraphicsElement::svgAttributeChanged(attrName); } void SVGPolyElement::synchronizePoints(SVGElement* contextElement) { ASSERT(contextElement); - SVGPolyElement* ownerType = toSVGPolyElement(contextElement); - if (!ownerType->m_points.shouldSynchronize) + SVGPolyElement& ownerType = downcast<SVGPolyElement>(*contextElement); + if (!ownerType.m_points.shouldSynchronize) return; - ownerType->m_points.synchronize(ownerType, pointsPropertyInfo()->attributeName, ownerType->m_points.value.valueAsString()); + ownerType.m_points.synchronize(&ownerType, pointsPropertyInfo()->attributeName, ownerType.m_points.value.valueAsString()); } -PassRefPtr<SVGAnimatedProperty> SVGPolyElement::lookupOrCreatePointsWrapper(SVGElement* contextElement) +Ref<SVGAnimatedProperty> SVGPolyElement::lookupOrCreatePointsWrapper(SVGElement* contextElement) { ASSERT(contextElement); - SVGPolyElement* ownerType = toSVGPolyElement(contextElement); - return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPolyElement, SVGAnimatedPointList, SVGPointList> - (ownerType, pointsPropertyInfo(), ownerType->m_points.value); + SVGPolyElement& ownerType = downcast<SVGPolyElement>(*contextElement); + return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPolyElement, SVGAnimatedPointList, SVGPointListValues>(&ownerType, pointsPropertyInfo(), ownerType.m_points.value); } -SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::points() +Ref<SVGPointList> SVGPolyElement::points() { m_points.shouldSynchronize = true; - return static_cast<SVGListPropertyTearOff<SVGPointList>*>(static_pointer_cast<SVGAnimatedPointList>(lookupOrCreatePointsWrapper(this))->baseVal()); + return static_reference_cast<SVGAnimatedPointList>(lookupOrCreatePointsWrapper(this))->baseVal(); } -SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::animatedPoints() +Ref<SVGPointList> SVGPolyElement::animatedPoints() { m_points.shouldSynchronize = true; - return static_cast<SVGListPropertyTearOff<SVGPointList>*>(static_pointer_cast<SVGAnimatedPointList>(lookupOrCreatePointsWrapper(this))->animVal()); + return static_reference_cast<SVGAnimatedPointList>(lookupOrCreatePointsWrapper(this))->animVal(); } -bool isSVGPolyElement(const Node& node) +size_t SVGPolyElement::approximateMemoryCost() const { - return node.hasTagName(SVGNames::polygonTag) || node.hasTagName(SVGNames::polylineTag); + size_t pointsCost = pointList().size() * sizeof(FloatPoint); + // We need to account for the memory which is allocated by the RenderSVGPath::m_path. + return sizeof(*this) + (renderer() ? pointsCost * 2 + sizeof(RenderSVGPath) : pointsCost); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPolyElement.h b/Source/WebCore/svg/SVGPolyElement.h index 7415c5d20..b3e24a247 100644 --- a/Source/WebCore/svg/SVGPolyElement.h +++ b/Source/WebCore/svg/SVGPolyElement.h @@ -18,59 +18,53 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPolyElement_h -#define SVGPolyElement_h - -#if ENABLE(SVG) +#pragma once #include "SVGAnimatedBoolean.h" #include "SVGExternalResourcesRequired.h" #include "SVGGraphicsElement.h" #include "SVGNames.h" -#include "SVGPointList.h" +#include "SVGPointListValues.h" namespace WebCore { class SVGPolyElement : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - SVGListPropertyTearOff<SVGPointList>* points(); - SVGListPropertyTearOff<SVGPointList>* animatedPoints(); + Ref<SVGPointList> points(); + Ref<SVGPointList> animatedPoints(); - SVGPointList& pointList() const { return m_points.value; } + SVGPointListValues& pointList() const { return m_points.value; } static const SVGPropertyInfo* pointsPropertyInfo(); + size_t approximateMemoryCost() const override; + protected: SVGPolyElement(const QualifiedName&, Document&); private: - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const override { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; - virtual bool supportsMarkers() const override { return true; } + bool supportsMarkers() const override { return true; } // Custom 'points' property static void synchronizePoints(SVGElement* contextElement); - static PassRefPtr<SVGAnimatedProperty> lookupOrCreatePointsWrapper(SVGElement* contextElement); + static Ref<SVGAnimatedProperty> lookupOrCreatePointsWrapper(SVGElement* contextElement); BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPolyElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES protected: - mutable SVGSynchronizableAnimatedProperty<SVGPointList> m_points; + mutable SVGSynchronizableAnimatedProperty<SVGPointListValues> m_points; }; -void isSVGPolyElement(const SVGPolyElement&); // Catch unnecessary runtime check of type known at compile time. -bool isSVGPolyElement(const Node&); -NODE_TYPE_CASTS(SVGPolyElement) - } // namespace WebCore -#endif // ENABLE(SVG) - -#endif +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGPolyElement) + static bool isType(const WebCore::SVGElement& element) { return element.hasTagName(WebCore::SVGNames::polygonTag) || element.hasTagName(WebCore::SVGNames::polylineTag); } + static bool isType(const WebCore::Node& node) { return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/SVGPolygonElement.cpp b/Source/WebCore/svg/SVGPolygonElement.cpp index 2540bedb0..5833e438b 100644 --- a/Source/WebCore/svg/SVGPolygonElement.cpp +++ b/Source/WebCore/svg/SVGPolygonElement.cpp @@ -19,9 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPolygonElement.h" + #include "SVGNames.h" namespace WebCore { @@ -32,11 +31,9 @@ inline SVGPolygonElement::SVGPolygonElement(const QualifiedName& tagName, Docume ASSERT(hasTagName(SVGNames::polygonTag)); } -PassRefPtr<SVGPolygonElement> SVGPolygonElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGPolygonElement> SVGPolygonElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGPolygonElement(tagName, document)); + return adoptRef(*new SVGPolygonElement(tagName, document)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPolygonElement.h b/Source/WebCore/svg/SVGPolygonElement.h index 11b50f60c..52d669172 100644 --- a/Source/WebCore/svg/SVGPolygonElement.h +++ b/Source/WebCore/svg/SVGPolygonElement.h @@ -18,25 +18,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPolygonElement_h -#define SVGPolygonElement_h +#pragma once -#if ENABLE(SVG) #include "SVGPolyElement.h" namespace WebCore { class SVGPolygonElement final : public SVGPolyElement { public: - static PassRefPtr<SVGPolygonElement> create(const QualifiedName&, Document&); + static Ref<SVGPolygonElement> create(const QualifiedName&, Document&); private: SVGPolygonElement(const QualifiedName&, Document&); }; -NODE_TYPE_CASTS(SVGPolygonElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPolygonElement.idl b/Source/WebCore/svg/SVGPolygonElement.idl index 8c088529f..815836501 100644 --- a/Source/WebCore/svg/SVGPolygonElement.idl +++ b/Source/WebCore/svg/SVGPolygonElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPolygonElement : SVGGraphicsElement { +interface SVGPolygonElement : SVGGraphicsElement { readonly attribute SVGPointList points; readonly attribute SVGPointList animatedPoints; }; diff --git a/Source/WebCore/svg/SVGPolylineElement.cpp b/Source/WebCore/svg/SVGPolylineElement.cpp index cdde836f5..686608114 100644 --- a/Source/WebCore/svg/SVGPolylineElement.cpp +++ b/Source/WebCore/svg/SVGPolylineElement.cpp @@ -19,9 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGPolylineElement.h" + #include "SVGNames.h" namespace WebCore { @@ -32,11 +31,9 @@ inline SVGPolylineElement::SVGPolylineElement(const QualifiedName& tagName, Docu ASSERT(hasTagName(SVGNames::polylineTag)); } -PassRefPtr<SVGPolylineElement> SVGPolylineElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGPolylineElement> SVGPolylineElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGPolylineElement(tagName, document)); + return adoptRef(*new SVGPolylineElement(tagName, document)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPolylineElement.h b/Source/WebCore/svg/SVGPolylineElement.h index f4275e462..d0bf4340f 100644 --- a/Source/WebCore/svg/SVGPolylineElement.h +++ b/Source/WebCore/svg/SVGPolylineElement.h @@ -18,25 +18,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPolylineElement_h -#define SVGPolylineElement_h +#pragma once -#if ENABLE(SVG) #include "SVGPolyElement.h" namespace WebCore { class SVGPolylineElement final : public SVGPolyElement { public: - static PassRefPtr<SVGPolylineElement> create(const QualifiedName&, Document&); + static Ref<SVGPolylineElement> create(const QualifiedName&, Document&); private: SVGPolylineElement(const QualifiedName&, Document&); }; -NODE_TYPE_CASTS(SVGPolylineElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGPolylineElement.idl b/Source/WebCore/svg/SVGPolylineElement.idl index de8a24b3e..986454b3b 100644 --- a/Source/WebCore/svg/SVGPolylineElement.idl +++ b/Source/WebCore/svg/SVGPolylineElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGPolylineElement : SVGGraphicsElement { +interface SVGPolylineElement : SVGGraphicsElement { readonly attribute SVGPointList points; readonly attribute SVGPointList animatedPoints; }; diff --git a/Source/WebCore/svg/SVGPreserveAspectRatio.h b/Source/WebCore/svg/SVGPreserveAspectRatio.h index 5e6f4b9f4..44b7fc459 100644 --- a/Source/WebCore/svg/SVGPreserveAspectRatio.h +++ b/Source/WebCore/svg/SVGPreserveAspectRatio.h @@ -1,90 +1,111 @@ /* - * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGPreserveAspectRatio_h -#define SVGPreserveAspectRatio_h +#pragma once -#if ENABLE(SVG) -#include "SVGPropertyTraits.h" +#include "ExceptionCode.h" +#include "SVGPreserveAspectRatioValue.h" +#include "SVGPropertyTearOff.h" namespace WebCore { -class AffineTransform; -class FloatRect; - -typedef int ExceptionCode; - -class SVGPreserveAspectRatio { - WTF_MAKE_FAST_ALLOCATED; +class SVGPreserveAspectRatio : public SVGPropertyTearOff<SVGPreserveAspectRatioValue> { public: - enum SVGPreserveAspectRatioType { - SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, - SVG_PRESERVEASPECTRATIO_NONE = 1, - SVG_PRESERVEASPECTRATIO_XMINYMIN = 2, - SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3, - SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4, - SVG_PRESERVEASPECTRATIO_XMINYMID = 5, - SVG_PRESERVEASPECTRATIO_XMIDYMID = 6, - SVG_PRESERVEASPECTRATIO_XMAXYMID = 7, - SVG_PRESERVEASPECTRATIO_XMINYMAX = 8, - SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9, - SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10 - }; - - enum SVGMeetOrSliceType { - SVG_MEETORSLICE_UNKNOWN = 0, - SVG_MEETORSLICE_MEET = 1, - SVG_MEETORSLICE_SLICE = 2 - }; - - SVGPreserveAspectRatio(); - - void setAlign(unsigned short align, ExceptionCode&); - unsigned short align() const { return m_align; } - - void setMeetOrSlice(unsigned short, ExceptionCode&); - unsigned short meetOrSlice() const { return m_meetOrSlice; } - - void transformRect(FloatRect& destRect, FloatRect& srcRect); - - AffineTransform getCTM(float logicX, float logicY, - float logicWidth, float logicHeight, - float physWidth, float physHeight) const; - - void parse(const String&); - bool parse(const UChar*& currParam, const UChar* end, bool validate); - - String valueAsString() const; + static Ref<SVGPreserveAspectRatio> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGPreserveAspectRatioValue& value) + { + return adoptRef(*new SVGPreserveAspectRatio(animatedProperty, role, value)); + } + + static Ref<SVGPreserveAspectRatio> create(const SVGPreserveAspectRatioValue& initialValue = { }) + { + return adoptRef(*new SVGPreserveAspectRatio(initialValue)); + } + + static Ref<SVGPreserveAspectRatio> create(const SVGPreserveAspectRatioValue* initialValue) + { + return adoptRef(*new SVGPreserveAspectRatio(initialValue)); + } + + template<typename T> static ExceptionOr<Ref<SVGPreserveAspectRatio>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } + + unsigned short align() + { + return propertyReference().align(); + } + + ExceptionOr<void> setAlign(float value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().setAlign(value); + if (result.hasException()) + return result; + + commitChange(); + return result; + } + + unsigned short meetOrSlice() + { + return propertyReference().meetOrSlice(); + } + + ExceptionOr<void> setMeetOrSlice(float value) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + auto result = propertyReference().setMeetOrSlice(value); + if (result.hasException()) + return result; + + commitChange(); + return result; + } private: - SVGPreserveAspectRatioType m_align; - SVGMeetOrSliceType m_meetOrSlice; -}; - -template<> -struct SVGPropertyTraits<SVGPreserveAspectRatio> { - static SVGPreserveAspectRatio initialValue() { return SVGPreserveAspectRatio(); } - static String toString(const SVGPreserveAspectRatio& type) { return type.valueAsString(); } + SVGPreserveAspectRatio(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGPreserveAspectRatioValue& value) + : SVGPropertyTearOff<SVGPreserveAspectRatioValue>(&animatedProperty, role, value) + { + } + + explicit SVGPreserveAspectRatio(const SVGPreserveAspectRatioValue& initialValue) + : SVGPropertyTearOff<SVGPreserveAspectRatioValue>(initialValue) + { + } + + explicit SVGPreserveAspectRatio(const SVGPreserveAspectRatioValue* initialValue) + : SVGPropertyTearOff<SVGPreserveAspectRatioValue>(initialValue) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGPreserveAspectRatio_h diff --git a/Source/WebCore/svg/SVGPreserveAspectRatio.idl b/Source/WebCore/svg/SVGPreserveAspectRatio.idl index 5f4ed8ad7..03399c21f 100644 --- a/Source/WebCore/svg/SVGPreserveAspectRatio.idl +++ b/Source/WebCore/svg/SVGPreserveAspectRatio.idl @@ -24,7 +24,7 @@ */ [ - Conditional=SVG + ConstantsScope=SVGPreserveAspectRatioValue ] interface SVGPreserveAspectRatio { // Alignment Types const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0; @@ -44,8 +44,6 @@ const unsigned short SVG_MEETORSLICE_MEET = 1; const unsigned short SVG_MEETORSLICE_SLICE = 2; - [StrictTypeChecking, SetterRaisesException] attribute unsigned short align; - - [StrictTypeChecking, SetterRaisesException] attribute unsigned short meetOrSlice; + [SetterMayThrowException] attribute unsigned short align; + [SetterMayThrowException] attribute unsigned short meetOrSlice; }; - diff --git a/Source/WebCore/svg/SVGPreserveAspectRatio.cpp b/Source/WebCore/svg/SVGPreserveAspectRatioValue.cpp index 7758a5c4f..d5d393eaf 100644 --- a/Source/WebCore/svg/SVGPreserveAspectRatio.cpp +++ b/Source/WebCore/svg/SVGPreserveAspectRatioValue.cpp @@ -20,148 +20,163 @@ */ #include "config.h" - -#if ENABLE(SVG) -#include "SVGPreserveAspectRatio.h" +#include "SVGPreserveAspectRatioValue.h" #include "AffineTransform.h" #include "ExceptionCode.h" #include "FloatRect.h" #include "SVGParserUtilities.h" -#include <wtf/text/WTFString.h> +#include <wtf/text/StringView.h> namespace WebCore { -SVGPreserveAspectRatio::SVGPreserveAspectRatio() +SVGPreserveAspectRatioValue::SVGPreserveAspectRatioValue() : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID) , m_meetOrSlice(SVG_MEETORSLICE_MEET) { } -void SVGPreserveAspectRatio::setAlign(unsigned short align, ExceptionCode& ec) +ExceptionOr<void> SVGPreserveAspectRatioValue::setAlign(unsigned short align) { - if (align == SVG_PRESERVEASPECTRATIO_UNKNOWN || align > SVG_PRESERVEASPECTRATIO_XMAXYMAX) { - ec = NOT_SUPPORTED_ERR; - return; - } + if (align == SVG_PRESERVEASPECTRATIO_UNKNOWN || align > SVG_PRESERVEASPECTRATIO_XMAXYMAX) + return Exception { NOT_SUPPORTED_ERR }; m_align = static_cast<SVGPreserveAspectRatioType>(align); + return { }; } -void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice, ExceptionCode& ec) +ExceptionOr<void> SVGPreserveAspectRatioValue::setMeetOrSlice(unsigned short meetOrSlice) { - if (meetOrSlice == SVG_MEETORSLICE_UNKNOWN || meetOrSlice > SVG_MEETORSLICE_SLICE) { - ec = NOT_SUPPORTED_ERR; - return; - } + if (meetOrSlice == SVG_MEETORSLICE_UNKNOWN || meetOrSlice > SVG_MEETORSLICE_SLICE) + return Exception { NOT_SUPPORTED_ERR }; m_meetOrSlice = static_cast<SVGMeetOrSliceType>(meetOrSlice); + return { }; +} + +void SVGPreserveAspectRatioValue::parse(const String& value) +{ + auto upconvertedCharacters = StringView(value).upconvertedCharacters(); + const UChar* begin = upconvertedCharacters; + parseInternal(begin, begin + value.length(), true); } -void SVGPreserveAspectRatio::parse(const String& value) +bool SVGPreserveAspectRatioValue::parse(const UChar*& currParam, const UChar* end, bool validate) { - const UChar* begin = value.deprecatedCharacters(); - parse(begin, begin + value.length(), true); + return parseInternal(currParam, end, validate); } -bool SVGPreserveAspectRatio::parse(const UChar*& currParam, const UChar* end, bool validate) +bool SVGPreserveAspectRatioValue::parseInternal(const UChar*& currParam, const UChar* end, bool validate) { - // FIXME: Rewrite this parser, without gotos! + SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_XMIDYMID; + SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET; + + m_align = align; + m_meetOrSlice = meetOrSlice; + if (!skipOptionalSVGSpaces(currParam, end)) - goto bailOut; + return false; if (*currParam == 'd') { - if (!skipString(currParam, end, "defer")) - goto bailOut; + if (!skipString(currParam, end, "defer")) { + LOG_ERROR("Skipped to parse except for *defer* value."); + return false; + } // FIXME: We just ignore the "defer" here. if (currParam == end) return true; if (!skipOptionalSVGSpaces(currParam, end)) - goto bailOut; + return false; } if (*currParam == 'n') { - if (!skipString(currParam, end, "none")) - goto bailOut; - m_align = SVG_PRESERVEASPECTRATIO_NONE; + if (!skipString(currParam, end, "none")) { + LOG_ERROR("Skipped to parse except for *none* value."); + return false; + } + align = SVG_PRESERVEASPECTRATIO_NONE; skipOptionalSVGSpaces(currParam, end); } else if (*currParam == 'x') { if ((end - currParam) < 8) - goto bailOut; + return false; if (currParam[1] != 'M' || currParam[4] != 'Y' || currParam[5] != 'M') - goto bailOut; + return false; if (currParam[2] == 'i') { if (currParam[3] == 'n') { if (currParam[6] == 'i') { if (currParam[7] == 'n') - m_align = SVG_PRESERVEASPECTRATIO_XMINYMIN; + align = SVG_PRESERVEASPECTRATIO_XMINYMIN; else if (currParam[7] == 'd') - m_align = SVG_PRESERVEASPECTRATIO_XMINYMID; + align = SVG_PRESERVEASPECTRATIO_XMINYMID; else - goto bailOut; + return false; } else if (currParam[6] == 'a' && currParam[7] == 'x') - m_align = SVG_PRESERVEASPECTRATIO_XMINYMAX; + align = SVG_PRESERVEASPECTRATIO_XMINYMAX; else - goto bailOut; + return false; } else if (currParam[3] == 'd') { if (currParam[6] == 'i') { if (currParam[7] == 'n') - m_align = SVG_PRESERVEASPECTRATIO_XMIDYMIN; + align = SVG_PRESERVEASPECTRATIO_XMIDYMIN; else if (currParam[7] == 'd') - m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID; + align = SVG_PRESERVEASPECTRATIO_XMIDYMID; else - goto bailOut; + return false; } else if (currParam[6] == 'a' && currParam[7] == 'x') - m_align = SVG_PRESERVEASPECTRATIO_XMIDYMAX; + align = SVG_PRESERVEASPECTRATIO_XMIDYMAX; else - goto bailOut; + return false; } else - goto bailOut; + return false; } else if (currParam[2] == 'a' && currParam[3] == 'x') { if (currParam[6] == 'i') { if (currParam[7] == 'n') - m_align = SVG_PRESERVEASPECTRATIO_XMAXYMIN; + align = SVG_PRESERVEASPECTRATIO_XMAXYMIN; else if (currParam[7] == 'd') - m_align = SVG_PRESERVEASPECTRATIO_XMAXYMID; + align = SVG_PRESERVEASPECTRATIO_XMAXYMID; else - goto bailOut; + return false; } else if (currParam[6] == 'a' && currParam[7] == 'x') - m_align = SVG_PRESERVEASPECTRATIO_XMAXYMAX; + align = SVG_PRESERVEASPECTRATIO_XMAXYMAX; else - goto bailOut; + return false; } else - goto bailOut; + return false; currParam += 8; skipOptionalSVGSpaces(currParam, end); } else - goto bailOut; + return false; if (currParam < end) { if (*currParam == 'm') { - if (!skipString(currParam, end, "meet")) - goto bailOut; + if (!skipString(currParam, end, "meet")) { + LOG_ERROR("Skipped to parse except for *meet* or *slice* value."); + return false; + } skipOptionalSVGSpaces(currParam, end); } else if (*currParam == 's') { - if (!skipString(currParam, end, "slice")) - goto bailOut; + if (!skipString(currParam, end, "slice")) { + LOG_ERROR("Skipped to parse except for *meet* or *slice* value."); + return false; + } skipOptionalSVGSpaces(currParam, end); - if (m_align != SVG_PRESERVEASPECTRATIO_NONE) - m_meetOrSlice = SVG_MEETORSLICE_SLICE; + if (align != SVG_PRESERVEASPECTRATIO_NONE) + meetOrSlice = SVG_MEETORSLICE_SLICE; } } - if (end != currParam && validate) { -bailOut: - m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID; - m_meetOrSlice = SVG_MEETORSLICE_MEET; + if (end != currParam && validate) return false; - } + + m_align = align; + m_meetOrSlice = meetOrSlice; + return true; } -void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRect) +void SVGPreserveAspectRatioValue::transformRect(FloatRect& destRect, FloatRect& srcRect) { if (m_align == SVG_PRESERVEASPECTRATIO_NONE) return; @@ -170,21 +185,21 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe float origDestWidth = destRect.width(); float origDestHeight = destRect.height(); switch (m_meetOrSlice) { - case SVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN: + case SVGPreserveAspectRatioValue::SVG_MEETORSLICE_UNKNOWN: break; - case SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET: { + case SVGPreserveAspectRatioValue::SVG_MEETORSLICE_MEET: { float widthToHeightMultiplier = srcRect.height() / srcRect.width(); if (origDestHeight > origDestWidth * widthToHeightMultiplier) { destRect.setHeight(origDestWidth * widthToHeightMultiplier); switch (m_align) { - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMINYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMID: destRect.setY(destRect.y() + origDestHeight / 2 - destRect.height() / 2); break; - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMINYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMAX: destRect.setY(destRect.y() + origDestHeight - destRect.height()); break; default: @@ -194,14 +209,14 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe if (origDestWidth > origDestHeight / widthToHeightMultiplier) { destRect.setWidth(origDestHeight / widthToHeightMultiplier); switch (m_align) { - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMIN: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMAX: destRect.setX(destRect.x() + origDestWidth / 2 - destRect.width() / 2); break; - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMIN: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMAX: destRect.setX(destRect.x() + origDestWidth - destRect.width()); break; default: @@ -210,21 +225,21 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe } break; } - case SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE: { + case SVGPreserveAspectRatioValue::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 (m_align) { - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMINYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMID: srcRect.setY(srcRect.y() + imageSize.height() / 2 - srcRect.height() / 2); break; - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMINYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMAX: srcRect.setY(srcRect.y() + imageSize.height() - srcRect.height()); break; default: @@ -236,14 +251,14 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe float destToSrcMultiplier = srcRect.height() / destRect.height(); srcRect.setWidth(destRect.width() * destToSrcMultiplier); switch (m_align) { - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMIN: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMIDYMAX: srcRect.setX(srcRect.x() + imageSize.width() / 2 - srcRect.width() / 2); break; - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID: - case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMIN: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMID: + case SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_XMAXYMAX: srcRect.setX(srcRect.x() + imageSize.width() - srcRect.width()); break; default: @@ -255,9 +270,14 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe } } -AffineTransform SVGPreserveAspectRatio::getCTM(float logicalX, float logicalY, float logicalWidth, float logicalHeight, float physicalWidth, float physicalHeight) const +AffineTransform SVGPreserveAspectRatioValue::getCTM(float logicalX, float logicalY, float logicalWidth, float logicalHeight, float physicalWidth, float physicalHeight) const { AffineTransform transform; + if (!logicalWidth || !logicalHeight || !physicalWidth || !physicalHeight) { + ASSERT_NOT_REACHED(); + return transform; + } + if (m_align == SVG_PRESERVEASPECTRATIO_UNKNOWN) return transform; @@ -301,7 +321,7 @@ AffineTransform SVGPreserveAspectRatio::getCTM(float logicalX, float logicalY, f return transform; } -String SVGPreserveAspectRatio::valueAsString() const +String SVGPreserveAspectRatioValue::valueAsString() const { String alignType; @@ -353,5 +373,3 @@ String SVGPreserveAspectRatio::valueAsString() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGPreserveAspectRatioValue.h b/Source/WebCore/svg/SVGPreserveAspectRatioValue.h new file mode 100644 index 000000000..a1fc114f6 --- /dev/null +++ b/Source/WebCore/svg/SVGPreserveAspectRatioValue.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@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. + */ + +#pragma once + +#include "ExceptionOr.h" +#include "SVGPropertyTraits.h" + +namespace WebCore { + +class AffineTransform; +class FloatRect; + +class SVGPreserveAspectRatioValue { + WTF_MAKE_FAST_ALLOCATED; +public: + enum SVGPreserveAspectRatioType { + SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, + SVG_PRESERVEASPECTRATIO_NONE = 1, + SVG_PRESERVEASPECTRATIO_XMINYMIN = 2, + SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3, + SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4, + SVG_PRESERVEASPECTRATIO_XMINYMID = 5, + SVG_PRESERVEASPECTRATIO_XMIDYMID = 6, + SVG_PRESERVEASPECTRATIO_XMAXYMID = 7, + SVG_PRESERVEASPECTRATIO_XMINYMAX = 8, + SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9, + SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10 + }; + + enum SVGMeetOrSliceType { + SVG_MEETORSLICE_UNKNOWN = 0, + SVG_MEETORSLICE_MEET = 1, + SVG_MEETORSLICE_SLICE = 2 + }; + + SVGPreserveAspectRatioValue(); + + ExceptionOr<void> setAlign(unsigned short); + unsigned short align() const { return m_align; } + + ExceptionOr<void> setMeetOrSlice(unsigned short); + unsigned short meetOrSlice() const { return m_meetOrSlice; } + + void transformRect(FloatRect& destRect, FloatRect& srcRect); + + AffineTransform getCTM(float logicalX, float logicalY, float logicalWidth, float logicalHeight, float physicalWidth, float physicalHeight) const; + + void parse(const String&); + bool parse(const UChar*& currParam, const UChar* end, bool validate); + + String valueAsString() const; + +private: + SVGPreserveAspectRatioType m_align; + SVGMeetOrSliceType m_meetOrSlice; + + bool parseInternal(const UChar*& currParam, const UChar* end, bool validate); +}; + +template<> struct SVGPropertyTraits<SVGPreserveAspectRatioValue> { + static SVGPreserveAspectRatioValue initialValue() { return SVGPreserveAspectRatioValue(); } + static String toString(const SVGPreserveAspectRatioValue& type) { return type.valueAsString(); } +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGRadialGradientElement.cpp b/Source/WebCore/svg/SVGRadialGradientElement.cpp index a92bf0010..355479f07 100644 --- a/Source/WebCore/svg/SVGRadialGradientElement.cpp +++ b/Source/WebCore/svg/SVGRadialGradientElement.cpp @@ -22,21 +22,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGRadialGradientElement.h" -#include "Attribute.h" #include "FloatConversion.h" #include "FloatPoint.h" #include "RadialGradientAttributes.h" #include "RenderSVGResourceRadialGradient.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGStopElement.h" -#include "SVGTransform.h" -#include "SVGTransformList.h" #include "SVGUnitTypes.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -72,47 +67,45 @@ inline SVGRadialGradientElement::SVGRadialGradientElement(const QualifiedName& t registerAnimatedPropertiesForSVGRadialGradientElement(); } -PassRefPtr<SVGRadialGradientElement> SVGRadialGradientElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGRadialGradientElement> SVGRadialGradientElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGRadialGradientElement(tagName, document)); + return adoptRef(*new SVGRadialGradientElement(tagName, document)); } bool SVGRadialGradientElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::cxAttr); - supportedAttributes.add(SVGNames::cyAttr); - supportedAttributes.add(SVGNames::fxAttr); - supportedAttributes.add(SVGNames::fyAttr); - supportedAttributes.add(SVGNames::rAttr); - supportedAttributes.add(SVGNames::frAttr); + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { + supportedAttributes.get().add(SVGNames::cxAttr); + supportedAttributes.get().add(SVGNames::cyAttr); + supportedAttributes.get().add(SVGNames::fxAttr); + supportedAttributes.get().add(SVGNames::fyAttr); + supportedAttributes.get().add(SVGNames::rAttr); + supportedAttributes.get().add(SVGNames::frAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGRadialGradientElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGradientElement::parseAttribute(name, value); - else if (name == SVGNames::cxAttr) - setCxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::cxAttr) + setCxBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::cyAttr) - setCyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setCyBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::rAttr) - setRBaseValue(SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths)); + setRBaseValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::fxAttr) - setFxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + setFxBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::fyAttr) - setFyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setFyBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::frAttr) - setFrBaseValue(SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths)); - else - ASSERT_NOT_REACHED(); + setFrBaseValue(SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths)); reportAttributeParsingError(parseError, name, value); + + SVGGradientElement::parseAttribute(name, value); } void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName) @@ -122,7 +115,7 @@ void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); updateRelativeLengthsInformation(); @@ -130,9 +123,9 @@ void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName object->setNeedsLayout(); } -RenderPtr<RenderElement> SVGRadialGradientElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGRadialGradientElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGResourceRadialGradient>(*this, std::move(style)); + return createRenderer<RenderSVGResourceRadialGradient>(*this, WTFMove(style)); } static void setGradientAttributes(SVGGradientElement& element, RadialGradientAttributes& attributes, bool isRadial = true) @@ -156,25 +149,25 @@ static void setGradientAttributes(SVGGradientElement& element, RadialGradientAtt } if (isRadial) { - SVGRadialGradientElement* radial = toSVGRadialGradientElement(&element); + SVGRadialGradientElement& radial = downcast<SVGRadialGradientElement>(element); if (!attributes.hasCx() && element.hasAttribute(SVGNames::cxAttr)) - attributes.setCx(radial->cx()); + attributes.setCx(radial.cx()); if (!attributes.hasCy() && element.hasAttribute(SVGNames::cyAttr)) - attributes.setCy(radial->cy()); + attributes.setCy(radial.cy()); if (!attributes.hasR() && element.hasAttribute(SVGNames::rAttr)) - attributes.setR(radial->r()); + attributes.setR(radial.r()); if (!attributes.hasFx() && element.hasAttribute(SVGNames::fxAttr)) - attributes.setFx(radial->fx()); + attributes.setFx(radial.fx()); if (!attributes.hasFy() && element.hasAttribute(SVGNames::fyAttr)) - attributes.setFy(radial->fy()); + attributes.setFy(radial.fy()); if (!attributes.hasFr() && element.hasAttribute(SVGNames::frAttr)) - attributes.setFr(radial->fr()); + attributes.setFr(radial.fr()); } } @@ -192,8 +185,8 @@ bool SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttribute while (true) { // Respect xlink:href, take attributes from referenced element Node* refNode = SVGURIReference::targetElementFromIRIString(current->href(), document()); - if (refNode && isSVGGradientElement(*refNode)) { - current = toSVGGradientElement(refNode); + if (is<SVGGradientElement>(refNode)) { + current = downcast<SVGGradientElement>(refNode); // Cycle detection if (processedGradients.contains(current)) @@ -229,5 +222,3 @@ bool SVGRadialGradientElement::selfHasRelativeLengths() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGRadialGradientElement.h b/Source/WebCore/svg/SVGRadialGradientElement.h index df8175d4e..aa6604b97 100644 --- a/Source/WebCore/svg/SVGRadialGradientElement.h +++ b/Source/WebCore/svg/SVGRadialGradientElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGRadialGradientElement_h -#define SVGRadialGradientElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedLength.h" #include "SVGGradientElement.h" #include "SVGNames.h" @@ -32,20 +30,20 @@ struct RadialGradientAttributes; class SVGRadialGradientElement final : public SVGGradientElement { public: - static PassRefPtr<SVGRadialGradientElement> create(const QualifiedName&, Document&); + static Ref<SVGRadialGradientElement> create(const QualifiedName&, Document&); bool collectGradientAttributes(RadialGradientAttributes&); private: SVGRadialGradientElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGRadialGradientElement) DECLARE_ANIMATED_LENGTH(Cx, cx) @@ -57,9 +55,4 @@ private: END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGRadialGradientElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGRadialGradientElement.idl b/Source/WebCore/svg/SVGRadialGradientElement.idl index d4b589f8f..1342c7537 100644 --- a/Source/WebCore/svg/SVGRadialGradientElement.idl +++ b/Source/WebCore/svg/SVGRadialGradientElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGRadialGradientElement : SVGGradientElement { +interface SVGRadialGradientElement : SVGGradientElement { readonly attribute SVGAnimatedLength cx; readonly attribute SVGAnimatedLength cy; readonly attribute SVGAnimatedLength r; diff --git a/Source/WebCore/svg/SVGRect.h b/Source/WebCore/svg/SVGRect.h index e3152d668..0e21f5f66 100644 --- a/Source/WebCore/svg/SVGRect.h +++ b/Source/WebCore/svg/SVGRect.h @@ -17,34 +17,117 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGRect_h -#define SVGRect_h +#pragma once -#if ENABLE(SVG) -#include "FloatRect.h" -#include "SVGPropertyTraits.h" -#include <wtf/text/StringBuilder.h> +#include "SVGPropertyTearOff.h" +#include "SVGRectTraits.h" namespace WebCore { -template<> -struct SVGPropertyTraits<FloatRect> { - static FloatRect initialValue() { return FloatRect(); } - static String toString(const FloatRect& type) - { - StringBuilder builder; - builder.appendNumber(type.x()); - builder.append(' '); - builder.appendNumber(type.y()); - builder.append(' '); - builder.appendNumber(type.width()); - builder.append(' '); - builder.appendNumber(type.height()); - return builder.toString(); +class SVGRect : public SVGPropertyTearOff<FloatRect> { +public: + static Ref<SVGRect> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, FloatRect& value) + { + return adoptRef(*new SVGRect(animatedProperty, role, value)); + } + + static Ref<SVGRect> create(const FloatRect& initialValue = { }) + { + return adoptRef(*new SVGRect(initialValue)); + } + + static Ref<SVGRect> create(const FloatRect* initialValue) + { + return adoptRef(*new SVGRect(initialValue)); + } + + template<typename T> static ExceptionOr<Ref<SVGRect>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } + + float x() + { + return propertyReference().x(); + } + + ExceptionOr<void> setX(float xValue) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setX(xValue); + commitChange(); + + return { }; + } + + float y() + { + return propertyReference().y(); + } + + ExceptionOr<void> setY(float xValue) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setY(xValue); + commitChange(); + + return { }; + } + + float width() + { + return propertyReference().width(); + } + + ExceptionOr<void> setWidth(float widthValue) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setWidth(widthValue); + commitChange(); + + return { }; + } + + float height() + { + return propertyReference().height(); + } + + ExceptionOr<void> setHeight(float heightValue) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setHeight(heightValue); + commitChange(); + + return { }; + } + +private: + SVGRect(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, FloatRect& value) + : SVGPropertyTearOff<FloatRect>(&animatedProperty, role, value) + { + } + + explicit SVGRect(const FloatRect& initialValue) + : SVGPropertyTearOff<FloatRect>(initialValue) + { + } + + explicit SVGRect(const FloatRect* initialValue) + : SVGPropertyTearOff<FloatRect>(initialValue) + { } }; -} // namespace WebCore -#endif // ENABLE(SVG) -#endif // SVGRect_h +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGRect.idl b/Source/WebCore/svg/SVGRect.idl index 22646187b..395a7f5be 100644 --- a/Source/WebCore/svg/SVGRect.idl +++ b/Source/WebCore/svg/SVGRect.idl @@ -20,12 +20,10 @@ * Boston, MA 02110-1301, USA. */ -[ - Conditional=SVG -] interface SVGRect { - [StrictTypeChecking] attribute float x; - [StrictTypeChecking] attribute float y; - [StrictTypeChecking] attribute float width; - [StrictTypeChecking] attribute float height; +interface SVGRect { + [SetterMayThrowException] attribute unrestricted float x; + [SetterMayThrowException] attribute unrestricted float y; + [SetterMayThrowException] attribute unrestricted float width; + [SetterMayThrowException] attribute unrestricted float height; }; diff --git a/Source/WebCore/svg/SVGRectElement.cpp b/Source/WebCore/svg/SVGRectElement.cpp index ecee2d73c..06399a0b3 100644 --- a/Source/WebCore/svg/SVGRectElement.cpp +++ b/Source/WebCore/svg/SVGRectElement.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -19,16 +20,12 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGRectElement.h" -#include "Attribute.h" #include "RenderSVGPath.h" #include "RenderSVGRect.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" -#include "SVGLength.h" +#include "SVGLengthValue.h" #include "SVGNames.h" namespace WebCore { @@ -66,105 +63,56 @@ inline SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document& do registerAnimatedPropertiesForSVGRectElement(); } -PassRefPtr<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGRectElement(tagName, document)); -} - -bool SVGRectElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); - supportedAttributes.add(SVGNames::rxAttr); - supportedAttributes.add(SVGNames::ryAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGRectElement(tagName, document)); } void SVGRectElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::rxAttr) - setRxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); + setRxBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::ryAttr) - setRyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); + setRyBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGGraphicsElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - bool isLengthAttribute = attrName == SVGNames::xAttr - || attrName == SVGNames::yAttr - || attrName == SVGNames::widthAttr - || attrName == SVGNames::heightAttr - || attrName == SVGNames::rxAttr - || attrName == SVGNames::ryAttr; - - if (isLengthAttribute) - updateRelativeLengthsInformation(); - - RenderSVGShape* renderer = toRenderSVGShape(this->renderer()); - if (!renderer) - return; - - if (isLengthAttribute) { - renderer->setNeedsShapeUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || attrName == SVGNames::rxAttr || attrName == SVGNames::ryAttr) { + InstanceInvalidationGuard guard(*this); + invalidateSVGPresentationAttributeStyle(); return; } if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + if (auto* renderer = downcast<RenderSVGShape>(this->renderer())) { + InstanceInvalidationGuard guard(*this); + RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } return; } - ASSERT_NOT_REACHED(); + SVGGraphicsElement::svgAttributeChanged(attrName); } -bool SVGRectElement::selfHasRelativeLengths() const +RenderPtr<RenderElement> SVGRectElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return x().isRelative() - || y().isRelative() - || width().isRelative() - || height().isRelative() - || rx().isRelative() - || ry().isRelative(); -} - -RenderPtr<RenderElement> SVGRectElement::createElementRenderer(PassRef<RenderStyle> style) -{ - return createRenderer<RenderSVGRect>(*this, std::move(style)); + return createRenderer<RenderSVGRect>(*this, WTFMove(style)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGRectElement.h b/Source/WebCore/svg/SVGRectElement.h index 0247ba443..7b2f87ec4 100644 --- a/Source/WebCore/svg/SVGRectElement.h +++ b/Source/WebCore/svg/SVGRectElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGRectElement_h -#define SVGRectElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGExternalResourcesRequired.h" @@ -33,21 +31,19 @@ namespace WebCore { class SVGRectElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGRectElement> create(const QualifiedName&, Document&); + static Ref<SVGRectElement> create(const QualifiedName&, Document&); private: SVGRectElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const final { return true; } - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGRectElement) DECLARE_ANIMATED_LENGTH(X, x) @@ -56,13 +52,8 @@ private: DECLARE_ANIMATED_LENGTH(Height, height) DECLARE_ANIMATED_LENGTH(Rx, rx) DECLARE_ANIMATED_LENGTH(Ry, ry) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGRectElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGRectElement.idl b/Source/WebCore/svg/SVGRectElement.idl index b08bfdbcf..0239e80c0 100644 --- a/Source/WebCore/svg/SVGRectElement.idl +++ b/Source/WebCore/svg/SVGRectElement.idl @@ -24,9 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGRectElement : SVGGraphicsElement { +interface SVGRectElement : SVGGraphicsElement { readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; readonly attribute SVGAnimatedLength width; diff --git a/Source/WebCore/svg/SVGRectTraits.h b/Source/WebCore/svg/SVGRectTraits.h new file mode 100644 index 000000000..7d84c6e25 --- /dev/null +++ b/Source/WebCore/svg/SVGRectTraits.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "FloatRect.h" +#include "SVGPropertyTraits.h" +#include <wtf/text/StringBuilder.h> + +namespace WebCore { + +template<> +struct SVGPropertyTraits<FloatRect> { + static FloatRect initialValue() { return { }; } + static String toString(const FloatRect& type) + { + StringBuilder builder; + builder.appendNumber(type.x()); + builder.append(' '); + builder.appendNumber(type.y()); + builder.append(' '); + builder.appendNumber(type.width()); + builder.append(' '); + builder.appendNumber(type.height()); + return builder.toString(); + } +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGRenderingIntent.h b/Source/WebCore/svg/SVGRenderingIntent.h index 230258a6a..422926c20 100644 --- a/Source/WebCore/svg/SVGRenderingIntent.h +++ b/Source/WebCore/svg/SVGRenderingIntent.h @@ -17,16 +17,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGRenderingIntent_h -#define SVGRenderingIntent_h - -#if ENABLE(SVG) +#pragma once #include <wtf/RefCounted.h> namespace WebCore { -class SVGRenderingIntent : public RefCounted<SVGRenderingIntent> { +class SVGRenderingIntent final : public RefCounted<SVGRenderingIntent> { public: enum SVGRenderingIntentType { RENDERING_INTENT_UNKNOWN = 0, @@ -42,8 +39,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGRenderingIntent_h - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGRenderingIntent.idl b/Source/WebCore/svg/SVGRenderingIntent.idl index 708f7a1a9..efffef5a9 100644 --- a/Source/WebCore/svg/SVGRenderingIntent.idl +++ b/Source/WebCore/svg/SVGRenderingIntent.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SuppressToJSObject, ImplementationLacksVTable ] interface SVGRenderingIntent { diff --git a/Source/WebCore/svg/SVGSVGElement.cpp b/Source/WebCore/svg/SVGSVGElement.cpp index 5a9fe0ce5..13738b754 100644 --- a/Source/WebCore/svg/SVGSVGElement.cpp +++ b/Source/WebCore/svg/SVGSVGElement.cpp @@ -1,7 +1,8 @@ /* * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org> - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007-2017 Apple Inc. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -20,44 +21,30 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGSVGElement.h" -#include "AffineTransform.h" -#include "Attribute.h" #include "CSSHelper.h" -#include "Document.h" +#include "DOMWrapperWorld.h" #include "ElementIterator.h" -#include "EventListener.h" #include "EventNames.h" -#include "FloatConversion.h" -#include "FloatRect.h" -#include "Frame.h" #include "FrameSelection.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "HTMLNames.h" -#include "RenderObject.h" +#include "MainFrame.h" #include "RenderSVGResource.h" -#include "RenderSVGModelObject.h" #include "RenderSVGRoot.h" #include "RenderSVGViewportContainer.h" #include "RenderView.h" -#include "RenderWidget.h" #include "SMILTimeContainer.h" #include "SVGAngle.h" -#include "SVGElementInstance.h" -#include "SVGFitToViewBox.h" -#include "SVGNames.h" -#include "SVGPreserveAspectRatio.h" +#include "SVGLength.h" +#include "SVGMatrix.h" +#include "SVGNumber.h" +#include "SVGPoint.h" +#include "SVGRect.h" +#include "SVGStaticPropertyTearOff.h" #include "SVGTransform.h" -#include "SVGTransformList.h" #include "SVGViewElement.h" #include "SVGViewSpec.h" -#include "SVGZoomEvent.h" #include "StaticNodeList.h" -#include <wtf/StdLibExtras.h> namespace WebCore { @@ -85,81 +72,80 @@ inline SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document& docu : SVGGraphicsElement(tagName, document) , m_x(LengthModeWidth) , m_y(LengthModeHeight) - , m_width(LengthModeWidth, "100%") - , m_height(LengthModeHeight, "100%") - , m_useCurrentView(false) - , m_zoomAndPan(SVGZoomAndPanMagnify) + , m_width(LengthModeWidth, ASCIILiteral("100%")) + , m_height(LengthModeHeight, ASCIILiteral("100%")) , m_timeContainer(SMILTimeContainer::create(this)) { ASSERT(hasTagName(SVGNames::svgTag)); registerAnimatedPropertiesForSVGSVGElement(); - document.registerForPageCacheSuspensionCallbacks(this); + document.registerForDocumentSuspensionCallbacks(this); +} + +Ref<SVGSVGElement> SVGSVGElement::create(const QualifiedName& tagName, Document& document) +{ + return adoptRef(*new SVGSVGElement(tagName, document)); } -PassRefPtr<SVGSVGElement> SVGSVGElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGSVGElement> SVGSVGElement::create(Document& document) { - return adoptRef(new SVGSVGElement(tagName, document)); + return create(SVGNames::svgTag, document); } SVGSVGElement::~SVGSVGElement() { if (m_viewSpec) m_viewSpec->resetContextElement(); - document().unregisterForPageCacheSuspensionCallbacks(this); - // There are cases where removedFromDocument() is not called. - // see ContainerNode::removeAllChildren, called by its destructor. - document().accessSVGExtensions()->removeTimeContainer(this); + document().unregisterForDocumentSuspensionCallbacks(this); + document().accessSVGExtensions().removeTimeContainer(this); } -void SVGSVGElement::didMoveToNewDocument(Document* oldDocument) +void SVGSVGElement::didMoveToNewDocument(Document& oldDocument) { - if (oldDocument) - oldDocument->unregisterForPageCacheSuspensionCallbacks(this); - document().registerForPageCacheSuspensionCallbacks(this); + oldDocument.unregisterForDocumentSuspensionCallbacks(this); + document().registerForDocumentSuspensionCallbacks(this); SVGGraphicsElement::didMoveToNewDocument(oldDocument); } const AtomicString& SVGSVGElement::contentScriptType() const { - DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("text/ecmascript", AtomicString::ConstructFromLiteral)); - const AtomicString& n = fastGetAttribute(SVGNames::contentScriptTypeAttr); - return n.isNull() ? defaultValue : n; + static NeverDestroyed<AtomicString> defaultScriptType { "text/ecmascript" }; + const AtomicString& type = attributeWithoutSynchronization(SVGNames::contentScriptTypeAttr); + return type.isNull() ? defaultScriptType.get() : type; } void SVGSVGElement::setContentScriptType(const AtomicString& type) { - setAttribute(SVGNames::contentScriptTypeAttr, type); + setAttributeWithoutSynchronization(SVGNames::contentScriptTypeAttr, type); } const AtomicString& SVGSVGElement::contentStyleType() const { - DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("text/css", AtomicString::ConstructFromLiteral)); - const AtomicString& n = fastGetAttribute(SVGNames::contentStyleTypeAttr); - return n.isNull() ? defaultValue : n; + static NeverDestroyed<AtomicString> defaultStyleType { "text/css" }; + const AtomicString& type = attributeWithoutSynchronization(SVGNames::contentStyleTypeAttr); + return type.isNull() ? defaultStyleType.get() : type; } void SVGSVGElement::setContentStyleType(const AtomicString& type) { - setAttribute(SVGNames::contentStyleTypeAttr, type); + setAttributeWithoutSynchronization(SVGNames::contentStyleTypeAttr, type); } -FloatRect SVGSVGElement::viewport() const +Ref<SVGRect> SVGSVGElement::viewport() const { - // FIXME: This method doesn't follow the spec and is basically untested. Parent documents are not considered here. - // As we have no test coverage for this, we're going to disable it completly for now. - return FloatRect(); + // FIXME: Not implemented. + return SVGRect::create(); } float SVGSVGElement::pixelUnitToMillimeterX() const { - // 2.54 / cssPixelsPerInch gives CM. - return (2.54f / cssPixelsPerInch) * 10.0f; + // There are 25.4 millimeters in an inch. + return 25.4f / cssPixelsPerInch; } float SVGSVGElement::pixelUnitToMillimeterY() const { - // 2.54 / cssPixelsPerInch gives CM. - return (2.54f / cssPixelsPerInch) * 10.0f; + // There are 25.4 millimeters in an inch. + return 25.4f / cssPixelsPerInch; } float SVGSVGElement::screenPixelToMillimeterX() const @@ -172,49 +158,47 @@ float SVGSVGElement::screenPixelToMillimeterY() const return pixelUnitToMillimeterY(); } -SVGViewSpec* SVGSVGElement::currentView() +SVGViewSpec& SVGSVGElement::currentView() { if (!m_viewSpec) - m_viewSpec = SVGViewSpec::create(this); - return m_viewSpec.get(); + m_viewSpec = SVGViewSpec::create(*this); + return *m_viewSpec; } -float SVGSVGElement::currentScale() const +Frame* SVGSVGElement::frameForCurrentScale() const { - if (!inDocument() || !isOutermostSVGSVGElement()) - return 1; - + // The behavior of currentScale() is undefined when we're dealing with non-standalone SVG documents. + // If the document is embedded, the scaling is handled by the host renderer. + if (!isConnected() || !isOutermostSVGSVGElement()) + return nullptr; Frame* frame = document().frame(); - if (!frame) - return 1; + return frame && frame->isMainFrame() ? frame : nullptr; +} - // The behaviour of currentScale() is undefined, when we're dealing with non-standalone SVG documents. - // If the svg is embedded, the scaling is handled by the host renderer, so when asking from inside - // the SVG document, a scale value of 1 seems reasonable, as it doesn't know anything about the parent scale. - return frame->tree().parent() ? 1 : frame->pageZoomFactor(); +float SVGSVGElement::currentScale() const +{ + // When asking from inside an embedded SVG document, a scale value of 1 seems reasonable, as it doesn't + // know anything about the parent scale. + Frame* frame = frameForCurrentScale(); + return frame ? frame->pageZoomFactor() : 1; } void SVGSVGElement::setCurrentScale(float scale) { - if (!inDocument() || !isOutermostSVGSVGElement()) - return; - - Frame* frame = document().frame(); - if (!frame) - return; - - // The behaviour of setCurrentScale() is undefined, when we're dealing with non-standalone SVG documents. - // We choose the ignore this call, it's pretty useless to support calling setCurrentScale() from within - // an embedded SVG document, for the same reasons as in currentScale() - needs resolution by SVG WG. - if (frame->tree().parent()) - return; + if (Frame* frame = frameForCurrentScale()) + frame->setPageZoomFactor(scale); +} - frame->setPageZoomFactor(scale); +Ref<SVGPoint> SVGSVGElement::currentTranslate() +{ + return SVGStaticPropertyTearOff<SVGSVGElement, SVGPoint>::create(*this, m_currentTranslate, &SVGSVGElement::updateCurrentTranslate); } void SVGSVGElement::setCurrentTranslate(const FloatPoint& translation) { - m_translation = translation; + if (m_currentTranslate == translation) + return; + m_currentTranslate = translation; updateCurrentTranslate(); } @@ -222,83 +206,92 @@ void SVGSVGElement::updateCurrentTranslate() { if (RenderObject* object = renderer()) object->setNeedsLayout(); - if (parentNode() == &document() && document().renderView()) document().renderView()->repaint(); } void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - SVGParsingError parseError = NoError; - if (!nearestViewportElement()) { - bool setListener = true; - - // Only handle events if we're the outermost <svg> element - if (name == HTMLNames::onunloadAttr) - document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value); - else if (name == HTMLNames::onresizeAttr) - document().setWindowAttributeEventListener(eventNames().resizeEvent, name, value); - else if (name == HTMLNames::onscrollAttr) - document().setWindowAttributeEventListener(eventNames().scrollEvent, name, value); - else if (name == SVGNames::onzoomAttr) - document().setWindowAttributeEventListener(eventNames().zoomEvent, name, value); - else - setListener = false; - - if (setListener) + // For these events, the outermost <svg> element works like a <body> element does, + // setting certain event handlers directly on the window object. + if (name == HTMLNames::onunloadAttr) { + document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value, mainThreadNormalWorld()); + return; + } + if (name == HTMLNames::onresizeAttr) { + document().setWindowAttributeEventListener(eventNames().resizeEvent, name, value, mainThreadNormalWorld()); + return; + } + if (name == HTMLNames::onscrollAttr) { + document().setWindowAttributeEventListener(eventNames().scrollEvent, name, value, mainThreadNormalWorld()); return; + } + if (name == SVGNames::onzoomAttr) { + document().setWindowAttributeEventListener(eventNames().zoomEvent, name, value, mainThreadNormalWorld()); + return; + } + } + + // For these events, any <svg> element works like a <body> element does, + // setting certain event handlers directly on the window object. + // FIXME: Why different from the events above that work only on the outermost <svg> element? + if (name == HTMLNames::onabortAttr) { + document().setWindowAttributeEventListener(eventNames().abortEvent, name, value, mainThreadNormalWorld()); + return; + } + if (name == HTMLNames::onerrorAttr) { + document().setWindowAttributeEventListener(eventNames().errorEvent, name, value, mainThreadNormalWorld()); + return; } - if (name == HTMLNames::onabortAttr) - document().setWindowAttributeEventListener(eventNames().abortEvent, name, value); - else if (name == HTMLNames::onerrorAttr) - document().setWindowAttributeEventListener(eventNames().errorEvent, name, value); - else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + SVGParsingError parseError = NoError; + + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); - else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); - else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value) - || SVGFitToViewBox::parseAttribute(this, name, value) - || SVGZoomAndPan::parseAttribute(this, name, value)) { - } else - SVGGraphicsElement::parseAttribute(name, value); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); + else if (name == SVGNames::widthAttr) { + auto length = SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths); + if (parseError != NoError || value.isEmpty()) { + // FIXME: This is definitely the correct behavior for a missing/removed attribute. + // Not sure it's correct for the empty string or for something that can't be parsed. + length = SVGLengthValue(LengthModeWidth, ASCIILiteral("100%")); + } + setWidthBaseValue(length); + } else if (name == SVGNames::heightAttr) { + auto length = SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths); + if (parseError != NoError || value.isEmpty()) { + // FIXME: This is definitely the correct behavior for a removed attribute. + // Not sure it's correct for the empty string or for something that can't be parsed. + length = SVGLengthValue(LengthModeHeight, ASCIILiteral("100%")); + } + setHeightBaseValue(length); + } reportAttributeParsingError(parseError, name, value); + + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGFitToViewBox::parseAttribute(this, name, value); + SVGZoomAndPan::parseAttribute(*this, name, value); + SVGGraphicsElement::parseAttribute(name, value); } void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName) { bool updateRelativeLengthsOrViewBox = false; - bool widthChanged = attrName == SVGNames::widthAttr; - if (widthChanged - || attrName == SVGNames::heightAttr - || attrName == SVGNames::xAttr - || attrName == SVGNames::yAttr) { + if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) { + invalidateSVGPresentationAttributeStyle(); updateRelativeLengthsOrViewBox = true; - updateRelativeLengthsInformation(); - - // At the SVG/HTML boundary (aka RenderSVGRoot), the width attribute can - // affect the replaced size so we need to mark it for updating. - if (widthChanged) { - RenderObject* renderObject = renderer(); - if (renderObject && renderObject->isSVGRoot()) - toRenderSVGRoot(renderObject)->setNeedsLayoutAndPrefWidthsRecalc(); - } } if (SVGFitToViewBox::isKnownAttribute(attrName)) { updateRelativeLengthsOrViewBox = true; - if (RenderObject* object = renderer()) - object->setNeedsTransformUpdate(); + if (auto* renderer = this->renderer()) + renderer->setNeedsTransformUpdate(); } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (updateRelativeLengthsOrViewBox || SVGLangSpace::isKnownAttribute(attrName) @@ -312,66 +305,52 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName) SVGGraphicsElement::svgAttributeChanged(attrName); } -unsigned SVGSVGElement::suspendRedraw(unsigned /* maxWaitMilliseconds */) +unsigned SVGSVGElement::suspendRedraw(unsigned) { - // FIXME: Implement me (see bug 11275) return 0; } -void SVGSVGElement::unsuspendRedraw(unsigned /* suspendHandleId */) +void SVGSVGElement::unsuspendRedraw(unsigned) { - // FIXME: Implement me (see bug 11275) } void SVGSVGElement::unsuspendRedrawAll() { - // FIXME: Implement me (see bug 11275) } void SVGSVGElement::forceRedraw() { - // FIXME: Implement me (see bug 11275) } -PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const FloatRect& rect, SVGElement* referenceElement, CollectIntersectionOrEnclosure collect) const +Ref<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(SVGRect& rect, SVGElement* referenceElement, bool (*checkFunction)(const SVGElement*, SVGRect&)) { Vector<Ref<Element>> elements; - - for (auto& svgElement : descendantsOfType<SVGElement>(*(referenceElement ? referenceElement : this))) { - if (collect == CollectIntersectionList) { - if (RenderSVGModelObject::checkIntersection(svgElement.renderer(), rect)) - elements.append(const_cast<SVGElement&>(svgElement)); - } else { - if (RenderSVGModelObject::checkEnclosure(svgElement.renderer(), rect)) - elements.append(const_cast<SVGElement&>(svgElement)); - } + for (auto& element : descendantsOfType<SVGElement>(referenceElement ? *referenceElement : *this)) { + if (checkFunction(&element, rect)) + elements.append(element); } - - return StaticElementList::adopt(elements); + return StaticElementList::create(WTFMove(elements)); } -PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(const FloatRect& rect, SVGElement* referenceElement) const +Ref<NodeList> SVGSVGElement::getIntersectionList(SVGRect& rect, SVGElement* referenceElement) { - return collectIntersectionOrEnclosureList(rect, referenceElement, CollectIntersectionList); + document().updateLayoutIgnorePendingStylesheets(); + return collectIntersectionOrEnclosureList(rect, referenceElement, checkIntersection); } -PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(const FloatRect& rect, SVGElement* referenceElement) const +Ref<NodeList> SVGSVGElement::getEnclosureList(SVGRect& rect, SVGElement* referenceElement) { - return collectIntersectionOrEnclosureList(rect, referenceElement, CollectEnclosureList); + return collectIntersectionOrEnclosureList(rect, referenceElement, checkEnclosure); } -bool SVGSVGElement::checkIntersection(const SVGElement* element, const FloatRect& rect) const +bool SVGSVGElement::checkIntersection(const SVGElement* element, SVGRect& rect) { - if (!element) - return false; - return RenderSVGModelObject::checkIntersection(element->renderer(), rect); + return element && RenderSVGModelObject::checkIntersection(element->renderer(), rect.propertyReference()); } -bool SVGSVGElement::checkEnclosure(const SVGElement* element, const FloatRect& rect) const +bool SVGSVGElement::checkEnclosure(const SVGElement* element, SVGRect& rect) { - if (!element) - return false; - return RenderSVGModelObject::checkEnclosure(element->renderer(), rect); + return element && RenderSVGModelObject::checkEnclosure(element->renderer(), rect.propertyReference()); } void SVGSVGElement::deselectAll() @@ -380,44 +359,44 @@ void SVGSVGElement::deselectAll() frame->selection().clear(); } -float SVGSVGElement::createSVGNumber() +Ref<SVGNumber> SVGSVGElement::createSVGNumber() { - return 0.0f; + return SVGNumber::create(); } -SVGLength SVGSVGElement::createSVGLength() +Ref<SVGLength> SVGSVGElement::createSVGLength() { - return SVGLength(); + return SVGLength::create(); } -SVGAngle SVGSVGElement::createSVGAngle() +Ref<SVGAngle> SVGSVGElement::createSVGAngle() { - return SVGAngle(); + return SVGAngle::create(); } -SVGPoint SVGSVGElement::createSVGPoint() +Ref<SVGPoint> SVGSVGElement::createSVGPoint() { - return SVGPoint(); + return SVGPoint::create(); } -SVGMatrix SVGSVGElement::createSVGMatrix() +Ref<SVGMatrix> SVGSVGElement::createSVGMatrix() { - return SVGMatrix(); + return SVGMatrix::create(); } -FloatRect SVGSVGElement::createSVGRect() +Ref<SVGRect> SVGSVGElement::createSVGRect() { - return FloatRect(); + return SVGRect::create(); } -SVGTransform SVGSVGElement::createSVGTransform() +Ref<SVGTransform> SVGSVGElement::createSVGTransform() { - return SVGTransform(SVGTransform::SVG_TRANSFORM_MATRIX); + return SVGTransform::create(SVGTransformValue { SVGTransformValue::SVG_TRANSFORM_MATRIX }); } -SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const SVGMatrix& matrix) +Ref<SVGTransform> SVGSVGElement::createSVGTransformFromMatrix(SVGMatrix& matrix) { - return SVGTransform(static_cast<const AffineTransform&>(matrix)); + return SVGTransform::create(SVGTransformValue { matrix.propertyReference() }); } AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope mode) const @@ -433,7 +412,7 @@ AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMSc SVGLengthContext lengthContext(this); transform.translate(x().value(lengthContext), y().value(lengthContext)); } else if (mode == SVGLocatable::ScreenScope) { - if (RenderObject* renderer = this->renderer()) { + if (auto* renderer = this->renderer()) { FloatPoint location; float zoomFactor = 1; @@ -441,15 +420,15 @@ AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMSc // to map an element from SVG viewport coordinates to CSS box coordinates. // RenderSVGRoot's localToAbsolute method expects CSS box coordinates. // We also need to adjust for the zoom level factored into CSS coordinates (bug #96361). - if (renderer->isSVGRoot()) { - location = toRenderSVGRoot(renderer)->localToBorderBoxTransform().mapPoint(location); + if (is<RenderSVGRoot>(*renderer)) { + location = downcast<RenderSVGRoot>(*renderer).localToBorderBoxTransform().mapPoint(location); zoomFactor = 1 / renderer->style().effectiveZoom(); } // Translate in our CSS parent coordinate space // FIXME: This doesn't work correctly with CSS transforms. location = renderer->localToAbsolute(location, UseTransforms); - location.scale(zoomFactor, zoomFactor); + location.scale(zoomFactor); // Be careful here! localToBorderBoxTransform() included the x/y offset coming from the viewBoxToViewTransform(), // so we have to subtract it here (original cause of bug #27183) @@ -457,9 +436,9 @@ AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMSc // Respect scroll offset. if (FrameView* view = document().view()) { - LayoutSize scrollOffset = view->scrollOffset(); - scrollOffset.scale(zoomFactor); - transform.translate(-scrollOffset.width(), -scrollOffset.height()); + LayoutPoint scrollPosition = view->scrollPosition(); + scrollPosition.scale(zoomFactor); + transform.translate(-scrollPosition.x(), -scrollPosition.y()); } } } @@ -469,6 +448,8 @@ AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMSc bool SVGSVGElement::rendererIsNeeded(const RenderStyle& style) { + if (!isValid()) + return false; // FIXME: We should respect display: none on the documentElement svg element // but many things in FrameView and SVGImage depend on the RenderSVGRoot when // they should instead depend on the RenderView. @@ -478,32 +459,31 @@ bool SVGSVGElement::rendererIsNeeded(const RenderStyle& style) return StyledElement::rendererIsNeeded(style); } -RenderPtr<RenderElement> SVGSVGElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGSVGElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { if (isOutermostSVGSVGElement()) - return createRenderer<RenderSVGRoot>(*this, std::move(style)); - - return createRenderer<RenderSVGViewportContainer>(*this, std::move(style)); + return createRenderer<RenderSVGRoot>(*this, WTFMove(style)); + return createRenderer<RenderSVGViewportContainer>(*this, WTFMove(style)); } Node::InsertionNotificationRequest SVGSVGElement::insertedInto(ContainerNode& rootParent) { - if (rootParent.inDocument()) { - document().accessSVGExtensions()->addTimeContainer(this); + if (rootParent.isConnected()) { + document().accessSVGExtensions().addTimeContainer(this); // Animations are started at the end of document parsing and after firing the load event, // but if we miss that train (deferred programmatic element insertion for example) we need // to initialize the time container here. - if (!document().parsing() && !document().processingLoadEvent() && document().loadEventFinished() && !timeContainer()->isStarted()) - timeContainer()->begin(); + if (!document().parsing() && !document().processingLoadEvent() && document().loadEventFinished() && !m_timeContainer->isStarted()) + m_timeContainer->begin(); } return SVGGraphicsElement::insertedInto(rootParent); } void SVGSVGElement::removedFrom(ContainerNode& rootParent) { - if (rootParent.inDocument()) - document().accessSVGExtensions()->removeTimeContainer(this); + if (rootParent.isConnected()) + document().accessSVGExtensions().removeTimeContainer(this); SVGGraphicsElement::removedFrom(rootParent); } @@ -531,10 +511,9 @@ float SVGSVGElement::getCurrentTime() const void SVGSVGElement::setCurrentTime(float seconds) { - if (std::isnan(seconds)) + if (!std::isfinite(seconds)) return; - seconds = std::max(seconds, 0.0f); - m_timeContainer->setElapsed(seconds); + m_timeContainer->setElapsed(std::max(seconds, 0.0f)); } bool SVGSVGElement::selfHasRelativeLengths() const @@ -551,117 +530,72 @@ FloatRect SVGSVGElement::currentViewBoxRect() const if (m_useCurrentView) return m_viewSpec ? m_viewSpec->viewBox() : FloatRect(); - FloatRect useViewBox = viewBox(); - if (!useViewBox.isEmpty()) - return useViewBox; - if (!renderer() || !renderer()->isSVGRoot()) - return FloatRect(); - if (!toRenderSVGRoot(renderer())->isEmbeddedThroughSVGImage()) - return FloatRect(); + FloatRect viewBox = this->viewBox(); + if (!viewBox.isEmpty()) + return viewBox; + + if (!is<RenderSVGRoot>(renderer())) + return { }; + if (!downcast<RenderSVGRoot>(*renderer()).isEmbeddedThroughSVGImage()) + return { }; Length intrinsicWidth = this->intrinsicWidth(); Length intrinsicHeight = this->intrinsicHeight(); if (!intrinsicWidth.isFixed() || !intrinsicHeight.isFixed()) - return FloatRect(); + return { }; // If no viewBox is specified but non-relative width/height values, then we // should always synthesize a viewBox if we're embedded through a SVGImage. - return FloatRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0))); + return { 0, 0, floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0) }; } FloatSize SVGSVGElement::currentViewportSize() const { - Length intrinsicWidth = this->intrinsicWidth(); - Length intrinsicHeight = this->intrinsicHeight(); - if (intrinsicWidth.isFixed() && intrinsicHeight.isFixed()) - return FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)); - - if (!renderer()) - return FloatSize(); + FloatSize viewportSize; - if (renderer()->isSVGRoot()) { - LayoutRect contentBoxRect = toRenderSVGRoot(renderer())->contentBoxRect(); - return FloatSize(contentBoxRect.width() / renderer()->style().effectiveZoom(), contentBoxRect.height() / renderer()->style().effectiveZoom()); + if (renderer()) { + if (is<RenderSVGRoot>(*renderer())) { + auto& root = downcast<RenderSVGRoot>(*renderer()); + viewportSize = root.contentBoxRect().size() / root.style().effectiveZoom(); + } else + viewportSize = downcast<RenderSVGViewportContainer>(*renderer()).viewport().size(); } - FloatRect viewportRect = toRenderSVGViewportContainer(renderer())->viewport(); - return FloatSize(viewportRect.width(), viewportRect.height()); -} - -bool SVGSVGElement::widthAttributeEstablishesViewport() const -{ - if (!renderer() || renderer()->isSVGViewportContainer()) - return true; - - // Spec: http://www.w3.org/TR/SVG/coords.html#ViewportSpace - // The ‘width’ attribute on the outermost svg element establishes the viewport's width, unless the following conditions are met: - // - the SVG content is a separately stored resource that is embedded by reference (such as the ‘object’ element in XHTML [XHTML]), or - // the SVG content is embedded inline within a containing document; - // - and the referencing element or containing document is styled using CSS [CSS2] or XSL [XSL]; - // - and there are CSS-compatible positioning properties ([CSS2], section 9.3) specified on the referencing element (e.g., the ‘object’ element) - // or on the containing document's outermost svg element that are sufficient to establish the width of the viewport. Under these conditions, - // the positioning properties establish the viewport's width. - RenderSVGRoot* root = toRenderSVGRoot(renderer()); + if (!viewportSize.isEmpty()) + return viewportSize; - // SVG embedded through object/embed/iframe. - if (root->isEmbeddedThroughFrameContainingSVGDocument()) - return !root->hasReplacedLogicalWidth() && !document().frame()->ownerRenderer()->hasReplacedLogicalWidth(); + if (!(hasIntrinsicWidth() && hasIntrinsicHeight())) + return { }; - // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG. - if (root->isEmbeddedThroughSVGImage() || document().documentElement() != this) - return !root->hasReplacedLogicalWidth(); - - return true; + return FloatSize(floatValueForLength(intrinsicWidth(), 0), floatValueForLength(intrinsicHeight(), 0)); } -bool SVGSVGElement::heightAttributeEstablishesViewport() const +bool SVGSVGElement::hasIntrinsicWidth() const { - if (!renderer() || renderer()->isSVGViewportContainer()) - return true; - - // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing - // Similarly, if there are positioning properties specified on the referencing element or on the outermost svg element - // that are sufficient to establish the height of the viewport, then these positioning properties establish the viewport's - // height; otherwise, the ‘height’ attribute on the outermost svg element establishes the viewport's height. - RenderSVGRoot* root = toRenderSVGRoot(renderer()); - - // SVG embedded through object/embed/iframe. - if (root->isEmbeddedThroughFrameContainingSVGDocument()) - return !root->hasReplacedLogicalHeight() && !document().frame()->ownerRenderer()->hasReplacedLogicalHeight(); - - // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG. - if (root->isEmbeddedThroughSVGImage() || document().documentElement() != this) - return !root->hasReplacedLogicalHeight(); - - return true; + return width().unitType() != LengthTypePercentage; } -Length SVGSVGElement::intrinsicWidth(ConsiderCSSMode mode) const +bool SVGSVGElement::hasIntrinsicHeight() const { - if (widthAttributeEstablishesViewport() || mode == IgnoreCSSProperties) { - if (width().unitType() == LengthTypePercentage) - return Length(width().valueAsPercentage() * 100, Percent); + return height().unitType() != LengthTypePercentage; +} - SVGLengthContext lengthContext(this); - return Length(width().value(lengthContext), Fixed); - } +Length SVGSVGElement::intrinsicWidth() const +{ + if (width().unitType() == LengthTypePercentage) + return Length(0, Fixed); - ASSERT(renderer()); - return renderer()->style().width(); + SVGLengthContext lengthContext(this); + return Length(width().value(lengthContext), Fixed); } -Length SVGSVGElement::intrinsicHeight(ConsiderCSSMode mode) const +Length SVGSVGElement::intrinsicHeight() const { - if (heightAttributeEstablishesViewport() || mode == IgnoreCSSProperties) { - if (height().unitType() == LengthTypePercentage) - return Length(height().valueAsPercentage() * 100, Percent); + if (height().unitType() == LengthTypePercentage) + return Length(0, Fixed); - SVGLengthContext lengthContext(this); - return Length(height().value(lengthContext), Fixed); - } - - ASSERT(renderer()); - return renderer()->style().height(); + SVGLengthContext lengthContext(this); + return Length(height().value(lengthContext), Fixed); } AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const @@ -669,19 +603,12 @@ AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float vie if (!m_useCurrentView || !m_viewSpec) return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), preserveAspectRatio(), viewWidth, viewHeight); - AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), m_viewSpec->preserveAspectRatio(), viewWidth, viewHeight); - const SVGTransformList& transformList = m_viewSpec->transformBaseValue(); - if (transformList.isEmpty()) - return ctm; - - AffineTransform transform; - if (transformList.concatenate(transform)) - ctm *= transform; - - return ctm; + AffineTransform transform = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), m_viewSpec->preserveAspectRatio(), viewWidth, viewHeight); + m_viewSpec->transformBaseValue().concatenate(transform); + return transform; } -void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* anchorNode) +void SVGSVGElement::scrollToAnchor(const String& fragmentIdentifier, Element* anchorNode) { auto renderer = this->renderer(); SVGViewSpec* view = m_viewSpec.get(); @@ -700,32 +627,28 @@ void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* if (fragmentIdentifier.startsWith("svgView(")) { if (!view) - view = currentView(); // Create the SVGViewSpec. - + view = ¤tView(); // Create the SVGViewSpec. if (view->parseViewSpec(fragmentIdentifier)) m_useCurrentView = true; else view->reset(); - if (renderer && (hadUseCurrentView || m_useCurrentView)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } - // Spec: If the SVG fragment identifier addresses a ‘view’ element within an SVG document (e.g., MyDrawing.svg#MyView - // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor ‘svg’ element is displayed in the viewport. - // Any view specification attributes included on the given ‘view’ element override the corresponding view specification - // attributes on the closest ancestor ‘svg’ element. - if (anchorNode && isSVGViewElement(anchorNode)) { - if (SVGViewElement* viewElement = toSVGViewElement(anchorNode)) { - SVGElement* element = SVGLocatable::nearestViewportElement(viewElement); - if (element->hasTagName(SVGNames::svgTag)) { - SVGSVGElement* svg = static_cast<SVGSVGElement*>(element); - svg->inheritViewAttributes(viewElement); - - if (RenderElement* renderer = svg->renderer()) - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); - } + // Spec: If the SVG fragment identifier addresses a "view" element within an SVG document (e.g., MyDrawing.svg#MyView + // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor "svg" element is displayed in the viewport. + // Any view specification attributes included on the given "view" element override the corresponding view specification + // attributes on the closest ancestor "svg" element. + if (is<SVGViewElement>(anchorNode)) { + auto& viewElement = downcast<SVGViewElement>(*anchorNode); + auto* viewportElement = SVGLocatable::nearestViewportElement(&viewElement); + if (is<SVGSVGElement>(viewportElement)) { + auto& element = downcast<SVGSVGElement>(*viewportElement); + element.inheritViewAttributes(viewElement); + if (auto* renderer = element.renderer()) + RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); } return; } @@ -734,33 +657,33 @@ void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* // FIXME: We need to actually "highlight" the viewTarget(s). } -void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) +void SVGSVGElement::inheritViewAttributes(const SVGViewElement& viewElement) { - SVGViewSpec* view = currentView(); + SVGViewSpec& view = currentView(); m_useCurrentView = true; - if (viewElement->hasAttribute(SVGNames::viewBoxAttr)) - view->setViewBoxBaseValue(viewElement->viewBox()); + if (viewElement.hasAttribute(SVGNames::viewBoxAttr)) + view.setViewBoxBaseValue(viewElement.viewBox()); else - view->setViewBoxBaseValue(viewBox()); + view.setViewBoxBaseValue(viewBox()); - if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) - view->setPreserveAspectRatioBaseValue(viewElement->preserveAspectRatioBaseValue()); + if (viewElement.hasAttribute(SVGNames::preserveAspectRatioAttr)) + view.setPreserveAspectRatioBaseValue(viewElement.preserveAspectRatioBaseValue()); else - view->setPreserveAspectRatioBaseValue(preserveAspectRatioBaseValue()); + view.setPreserveAspectRatioBaseValue(preserveAspectRatioBaseValue()); - if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr)) - view->setZoomAndPanBaseValue(viewElement->zoomAndPan()); + if (viewElement.hasAttribute(SVGNames::zoomAndPanAttr)) + view.setZoomAndPanBaseValue(viewElement.zoomAndPan()); else - view->setZoomAndPanBaseValue(zoomAndPan()); + view.setZoomAndPanBaseValue(zoomAndPan()); } -void SVGSVGElement::documentWillSuspendForPageCache() +void SVGSVGElement::prepareForDocumentSuspension() { pauseAnimations(); } -void SVGSVGElement::documentDidResumeFromPageCache() +void SVGSVGElement::resumeFromDocumentSuspension() { unpauseAnimations(); } @@ -769,19 +692,24 @@ void SVGSVGElement::documentDidResumeFromPageCache() // See http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGSVGElement Element* SVGSVGElement::getElementById(const AtomicString& id) { + if (id.isNull()) + return nullptr; + Element* element = treeScope().getElementById(id); - if (element && element->isDescendantOf(this)) + if (element && element->isDescendantOf(*this)) return element; - - // Fall back to traversing our subtree. Duplicate ids are allowed, the first found will - // be returned. - for (auto& element : descendantsOfType<Element>(*this)) { - if (element.getIdAttribute() == id) - return &element; + if (treeScope().containsMultipleElementsWithId(id)) { + for (auto* element : *treeScope().getAllElementsById(id)) { + if (element->isDescendantOf(*this)) + return element; + } } - return 0; + return nullptr; } +bool SVGSVGElement::isValid() const +{ + return SVGTests::isValid(); } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGSVGElement.h b/Source/WebCore/svg/SVGSVGElement.h index b5b1e6cb8..ef54f12c3 100644 --- a/Source/WebCore/svg/SVGSVGElement.h +++ b/Source/WebCore/svg/SVGSVGElement.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007, 2010 Rob Buis <buis@kde.org> + * Copyright (C) 2015 Apple Inc. 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 @@ -18,10 +19,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGSVGElement_h -#define SVGSVGElement_h +#pragma once -#if ENABLE(SVG) +#include "FloatPoint.h" #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGAnimatedPreserveAspectRatio.h" @@ -33,158 +33,162 @@ namespace WebCore { +class SMILTimeContainer; class SVGAngle; +class SVGLength; class SVGMatrix; +class SVGNumber; +class SVGRect; class SVGTransform; class SVGViewSpec; -class SVGViewElement; -class SMILTimeContainer; - -class SVGSVGElement final : public SVGGraphicsElement, - public SVGExternalResourcesRequired, - public SVGFitToViewBox, - public SVGZoomAndPan { -public: - static PassRefPtr<SVGSVGElement> create(const QualifiedName&, Document&); - using SVGGraphicsElement::ref; - using SVGGraphicsElement::deref; +class SVGSVGElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired, public SVGFitToViewBox, public SVGZoomAndPan { - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSVGElement) + DECLARE_ANIMATED_LENGTH(X, x) + DECLARE_ANIMATED_LENGTH(Y, y) + DECLARE_ANIMATED_LENGTH(Width, width) + DECLARE_ANIMATED_LENGTH(Height, height) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_RECT(ViewBox, viewBox) + DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) + END_DECLARE_ANIMATED_PROPERTIES - // 'SVGSVGElement' functions +public: // DOM const AtomicString& contentScriptType() const; - void setContentScriptType(const AtomicString& type); + void setContentScriptType(const AtomicString&); const AtomicString& contentStyleType() const; - void setContentStyleType(const AtomicString& type); + void setContentStyleType(const AtomicString&); - FloatRect viewport() const; + Ref<SVGRect> viewport() const; float pixelUnitToMillimeterX() const; float pixelUnitToMillimeterY() const; float screenPixelToMillimeterX() const; float screenPixelToMillimeterY() const; - bool useCurrentView() const { return m_useCurrentView; } - SVGViewSpec* currentView(); - - enum ConsiderCSSMode { - RespectCSSProperties, - IgnoreCSSProperties - }; - - // RenderSVGRoot wants to query the intrinsic size, by only examining the width/height attributes. - Length intrinsicWidth(ConsiderCSSMode = RespectCSSProperties) const; - Length intrinsicHeight(ConsiderCSSMode = RespectCSSProperties) const; - FloatSize currentViewportSize() const; - FloatRect currentViewBoxRect() const; + bool useCurrentView() const; + SVGViewSpec& currentView(); float currentScale() const; - void setCurrentScale(float scale); + void setCurrentScale(float); - SVGPoint& currentTranslate() { return m_translation; } - void setCurrentTranslate(const FloatPoint&); + Ref<SVGPoint> currentTranslate(); + FloatPoint currentTranslateValue(); - // Only used from the bindings. - void updateCurrentTranslate(); + unsigned suspendRedraw(unsigned maxWaitMilliseconds); + void unsuspendRedraw(unsigned suspendHandleId); + void unsuspendRedrawAll(); + void forceRedraw(); - SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } - void pauseAnimations(); void unpauseAnimations(); bool animationsPaused() const; float getCurrentTime() const; - void setCurrentTime(float seconds); + void setCurrentTime(float); - unsigned suspendRedraw(unsigned maxWaitMilliseconds); - void unsuspendRedraw(unsigned suspendHandleId); - void unsuspendRedrawAll(); - void forceRedraw(); - - PassRefPtr<NodeList> getIntersectionList(const FloatRect&, SVGElement* referenceElement) const; - PassRefPtr<NodeList> getEnclosureList(const FloatRect&, SVGElement* referenceElement) const; - bool checkIntersection(const SVGElement*, const FloatRect&) const; - bool checkEnclosure(const SVGElement*, const FloatRect&) const; + Ref<NodeList> getIntersectionList(SVGRect&, SVGElement* referenceElement); + Ref<NodeList> getEnclosureList(SVGRect&, SVGElement* referenceElement); + static bool checkIntersection(const SVGElement*, SVGRect&); + static bool checkEnclosure(const SVGElement*, SVGRect&); void deselectAll(); - static float createSVGNumber(); - static SVGLength createSVGLength(); - static SVGAngle createSVGAngle(); - static SVGPoint createSVGPoint(); - static SVGMatrix createSVGMatrix(); - static FloatRect createSVGRect(); - static SVGTransform createSVGTransform(); - static SVGTransform createSVGTransformFromMatrix(const SVGMatrix&); - - AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const; - - void setupInitialView(const String& fragmentIdentifier, Element* anchorNode); + static Ref<SVGNumber> createSVGNumber(); + static Ref<SVGLength> createSVGLength(); + static Ref<SVGAngle> createSVGAngle(); + static Ref<SVGPoint> createSVGPoint(); + static Ref<SVGMatrix> createSVGMatrix(); + static Ref<SVGRect> createSVGRect(); + static Ref<SVGTransform> createSVGTransform(); + static Ref<SVGTransform> createSVGTransformFromMatrix(SVGMatrix&); Element* getElementById(const AtomicString&); - bool widthAttributeEstablishesViewport() const; - bool heightAttributeEstablishesViewport() const; - - SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; } - void setZoomAndPan(unsigned short zoomAndPan) { m_zoomAndPan = SVGZoomAndPan::parseFromNumber(zoomAndPan); } + SVGZoomAndPanType zoomAndPan() const; + void setZoomAndPan(unsigned short); - bool hasEmptyViewBox() const { return viewBoxIsValid() && viewBox().isEmpty(); } - -private: - SVGSVGElement(const QualifiedName&, Document&); - virtual ~SVGSVGElement(); +public: + static Ref<SVGSVGElement> create(const QualifiedName&, Document&); + static Ref<SVGSVGElement> create(Document&); + void scrollToAnchor(const String& fragmentIdentifier, Element* anchor); - virtual void didMoveToNewDocument(Document* oldDocument) override; + using SVGGraphicsElement::ref; + using SVGGraphicsElement::deref; - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; + SMILTimeContainer& timeContainer(); - virtual bool rendererIsNeeded(const RenderStyle&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + void setCurrentTranslate(const FloatPoint&); // Used to pan. + void updateCurrentTranslate(); // Used from DOM bindings to create an SVGStaticPropertyTearOff for currentTranslate. - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + bool hasIntrinsicWidth() const; + bool hasIntrinsicHeight() const; + Length intrinsicWidth() const; + Length intrinsicHeight() const; - virtual void svgAttributeChanged(const QualifiedName&) override; + FloatSize currentViewportSize() const; + FloatRect currentViewBoxRect() const; - virtual bool selfHasRelativeLengths() const override; + bool hasEmptyViewBox() const; + AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const; - void inheritViewAttributes(SVGViewElement*); +private: + SVGSVGElement(const QualifiedName&, Document&); + virtual ~SVGSVGElement(); - enum CollectIntersectionOrEnclosure { - CollectIntersectionList, - CollectEnclosureList - }; + bool isValid() const override; + void didMoveToNewDocument(Document& oldDocument) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool rendererIsNeeded(const RenderStyle&) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; + void svgAttributeChanged(const QualifiedName&) override; + bool selfHasRelativeLengths() const override; + void prepareForDocumentSuspension() override; + void resumeFromDocumentSuspension() override; + AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const override; + + Frame* frameForCurrentScale() const; + void inheritViewAttributes(const SVGViewElement&); + Ref<NodeList> collectIntersectionOrEnclosureList(SVGRect&, SVGElement*, bool (*checkFunction)(const SVGElement*, SVGRect&)); + + bool m_useCurrentView { false }; + SVGZoomAndPanType m_zoomAndPan { SVGZoomAndPanMagnify }; + Ref<SMILTimeContainer> m_timeContainer; + FloatPoint m_currentTranslate; + RefPtr<SVGViewSpec> m_viewSpec; +}; - PassRefPtr<NodeList> collectIntersectionOrEnclosureList(const FloatRect&, SVGElement*, CollectIntersectionOrEnclosure) const; +inline bool SVGSVGElement::useCurrentView() const +{ + return m_useCurrentView; +} - BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSVGElement) - DECLARE_ANIMATED_LENGTH(X, x) - DECLARE_ANIMATED_LENGTH(Y, y) - DECLARE_ANIMATED_LENGTH(Width, width) - DECLARE_ANIMATED_LENGTH(Height, height) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) - DECLARE_ANIMATED_RECT(ViewBox, viewBox) - DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) - END_DECLARE_ANIMATED_PROPERTIES +inline FloatPoint SVGSVGElement::currentTranslateValue() +{ + return m_currentTranslate; +} - virtual void documentWillSuspendForPageCache() override; - virtual void documentDidResumeFromPageCache() override; +inline SVGZoomAndPanType SVGSVGElement::zoomAndPan() const +{ + return m_zoomAndPan; +} - virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const override; +inline void SVGSVGElement::setZoomAndPan(unsigned short zoomAndPan) +{ + m_zoomAndPan = parseFromNumber(zoomAndPan); +} - bool m_useCurrentView; - SVGZoomAndPanType m_zoomAndPan; - RefPtr<SMILTimeContainer> m_timeContainer; - SVGPoint m_translation; - RefPtr<SVGViewSpec> m_viewSpec; -}; +inline SMILTimeContainer& SVGSVGElement::timeContainer() +{ + return m_timeContainer.get(); +} -NODE_TYPE_CASTS(SVGSVGElement) +inline bool SVGSVGElement::hasEmptyViewBox() const +{ + return viewBoxIsValid() && viewBox().isEmpty(); +} } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGSVGElement.idl b/Source/WebCore/svg/SVGSVGElement.idl index eb6fe370a..e665d47e2 100644 --- a/Source/WebCore/svg/SVGSVGElement.idl +++ b/Source/WebCore/svg/SVGSVGElement.idl @@ -20,56 +20,58 @@ * Boston, MA 02110-1301, USA. */ -// TODO: no css::ViewCSS available! -// TODO: Fix SVGSVGElement inheritance (css::DocumentCSS)! -// TODO: no events::DocumentEvent available! -[ - Conditional=SVG, -] interface SVGSVGElement : SVGGraphicsElement { +// FIXME: no css::ViewCSS available! +// FIXME: Fix SVGSVGElement inheritance (css::DocumentCSS)! +// FIXME: no events::DocumentEvent available! + +interface SVGSVGElement : SVGGraphicsElement { readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; readonly attribute SVGAnimatedLength width; readonly attribute SVGAnimatedLength height; - attribute DOMString contentScriptType; - attribute DOMString contentStyleType; - readonly attribute SVGRect viewport; - readonly attribute float pixelUnitToMillimeterX; - readonly attribute float pixelUnitToMillimeterY; - readonly attribute float screenPixelToMillimeterX; - readonly attribute float screenPixelToMillimeterY; + attribute DOMString contentScriptType; + attribute DOMString contentStyleType; + [NewObject] readonly attribute SVGRect viewport; + readonly attribute unrestricted float pixelUnitToMillimeterX; + readonly attribute unrestricted float pixelUnitToMillimeterY; + readonly attribute unrestricted float screenPixelToMillimeterX; + readonly attribute unrestricted float screenPixelToMillimeterY; readonly attribute boolean useCurrentView; readonly attribute SVGViewSpec currentView; - attribute float currentScale; - readonly attribute SVGPoint currentTranslate; + attribute unrestricted float currentScale; + [NewObject] readonly attribute SVGPoint currentTranslate; - unsigned long suspendRedraw([Default=Undefined] optional unsigned long maxWaitMilliseconds); - void unsuspendRedraw([Default=Undefined] optional unsigned long suspendHandleId); + unsigned long suspendRedraw(optional unsigned long maxWaitMilliseconds = 0); + void unsuspendRedraw(optional unsigned long suspendHandleId = 0); void unsuspendRedrawAll(); void forceRedraw(); void pauseAnimations(); void unpauseAnimations(); boolean animationsPaused(); - float getCurrentTime(); - void setCurrentTime([Default=Undefined] optional float seconds); - NodeList getIntersectionList([Default=Undefined] optional SVGRect rect, - [Default=Undefined] optional SVGElement referenceElement); - NodeList getEnclosureList([Default=Undefined] optional SVGRect rect, - [Default=Undefined] optional SVGElement referenceElement); - boolean checkIntersection([Default=Undefined] optional SVGElement element, - [Default=Undefined] optional SVGRect rect); - boolean checkEnclosure([Default=Undefined] optional SVGElement element, - [Default=Undefined] optional SVGRect rect); + unrestricted float getCurrentTime(); + void setCurrentTime(optional unrestricted float seconds = NaN); + + // FIXME: referenceElement should not be optional. + NodeList getIntersectionList(SVGRect rect, optional SVGElement? referenceElement = null); + + // FIXME: referenceElement should not be optional. + NodeList getEnclosureList(SVGRect rect, optional SVGElement? referenceElement = null); + + boolean checkIntersection(SVGElement? element, SVGRect rect); // element should not be nullable. + boolean checkEnclosure(SVGElement? element, SVGRect rect); // element should not be nullable. + void deselectAll(); - SVGNumber createSVGNumber(); - SVGLength createSVGLength(); - SVGAngle createSVGAngle(); - SVGPoint createSVGPoint(); - SVGMatrix createSVGMatrix(); - SVGRect createSVGRect(); - SVGTransform createSVGTransform(); - SVGTransform createSVGTransformFromMatrix([Default=Undefined] optional SVGMatrix matrix); - Element getElementById([Default=Undefined] optional DOMString elementId); + [NewObject] SVGNumber createSVGNumber(); + [NewObject] SVGLength createSVGLength(); + [NewObject] SVGAngle createSVGAngle(); + [NewObject] SVGPoint createSVGPoint(); + [NewObject] SVGMatrix createSVGMatrix(); + [NewObject] SVGRect createSVGRect(); + [NewObject] SVGTransform createSVGTransform(); + [NewObject] SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix); + + Element getElementById([RequiresExistingAtomicString] DOMString elementId); }; SVGSVGElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGScriptElement.cpp b/Source/WebCore/svg/SVGScriptElement.cpp index a53fbd5ea..d6649fa10 100644 --- a/Source/WebCore/svg/SVGScriptElement.cpp +++ b/Source/WebCore/svg/SVGScriptElement.cpp @@ -19,17 +19,11 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGScriptElement.h" -#include "Attribute.h" #include "Document.h" #include "Event.h" -#include "EventNames.h" -#include "HTMLNames.h" #include "SVGAnimatedStaticPropertyTearOff.h" -#include "SVGElementInstance.h" #include "XLinkNames.h" namespace WebCore { @@ -45,93 +39,55 @@ END_REGISTER_ANIMATED_PROPERTIES inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document& document, bool wasInsertedByParser, bool alreadyStarted) : SVGElement(tagName, document) - , ScriptElement(this, wasInsertedByParser, alreadyStarted) - , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) + , ScriptElement(*this, wasInsertedByParser, alreadyStarted) + , m_svgLoadEventTimer(*this, &SVGElement::svgLoadEventTimerFired) { ASSERT(hasTagName(SVGNames::scriptTag)); registerAnimatedPropertiesForSVGScriptElement(); } -PassRefPtr<SVGScriptElement> SVGScriptElement::create(const QualifiedName& tagName, Document& document, bool insertedByParser) -{ - return adoptRef(new SVGScriptElement(tagName, document, insertedByParser, false)); -} - -bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGScriptElement> SVGScriptElement::create(const QualifiedName& tagName, Document& document, bool insertedByParser) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGURIReference::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::typeAttr); - supportedAttributes.add(HTMLNames::onerrorAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGScriptElement(tagName, document, insertedByParser, false)); } void SVGScriptElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - - if (name == SVGNames::typeAttr) - return; - - if (name == HTMLNames::onerrorAttr) { - setAttributeEventListener(eventNames().errorEvent, name, value); - return; - } - - if (SVGURIReference::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr) - return; + InstanceInvalidationGuard guard(*this); if (SVGURIReference::isKnownAttribute(attrName)) { handleSourceAttribute(href()); return; } - if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName)) - return; - - ASSERT_NOT_REACHED(); + SVGExternalResourcesRequired::handleAttributeChange(this, attrName); + SVGElement::svgAttributeChanged(attrName); } Node::InsertionNotificationRequest SVGScriptElement::insertedInto(ContainerNode& rootParent) { SVGElement::insertedInto(rootParent); - if (rootParent.inDocument()) + if (rootParent.isConnected()) SVGExternalResourcesRequired::insertedIntoDocument(this); - return shouldNotifySubtreeInsertions(rootParent) ? InsertionShouldCallDidNotifySubtreeInsertions : InsertionDone; + return shouldCallFinishedInsertingSubtree(rootParent) ? InsertionShouldCallFinishedInsertingSubtree : InsertionDone; } -void SVGScriptElement::didNotifySubtreeInsertions(ContainerNode* node) +void SVGScriptElement::finishedInsertingSubtree() { - ScriptElement::didNotifySubtreeInsertions(node); + ScriptElement::finishedInsertingSubtree(); } void SVGScriptElement::childrenChanged(const ChildChange& change) { SVGElement::childrenChanged(change); - ScriptElement::childrenChanged(); + ScriptElement::childrenChanged(change); } bool SVGScriptElement::isURLAttribute(const Attribute& attribute) const @@ -182,12 +138,17 @@ String SVGScriptElement::eventAttributeValue() const return String(); } -bool SVGScriptElement::asyncAttributeValue() const +bool SVGScriptElement::hasAsyncAttribute() const { return false; } -bool SVGScriptElement::deferAttributeValue() const +bool SVGScriptElement::hasDeferAttribute() const +{ + return false; +} + +bool SVGScriptElement::hasNoModuleAttribute() const { return false; } @@ -197,21 +158,16 @@ bool SVGScriptElement::hasSourceAttribute() const return hasAttribute(XLinkNames::hrefAttr); } -PassRefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren() +Ref<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument) { - return adoptRef(new SVGScriptElement(tagQName(), document(), false, alreadyStarted())); + return adoptRef(*new SVGScriptElement(tagQName(), targetDocument, false, alreadyStarted())); } #ifndef NDEBUG -bool SVGScriptElement::isAnimatableAttribute(const QualifiedName& name) const +bool SVGScriptElement::filterOutAnimatableAttribute(const QualifiedName& name) const { - if (name == SVGNames::typeAttr) - return false; - - return SVGElement::isAnimatableAttribute(name); + return name == SVGNames::typeAttr; } #endif } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGScriptElement.h b/Source/WebCore/svg/SVGScriptElement.h index 7dce93b15..23277f777 100644 --- a/Source/WebCore/svg/SVGScriptElement.h +++ b/Source/WebCore/svg/SVGScriptElement.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2008-2017 Apple Inc. 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 @@ -18,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGScriptElement_h -#define SVGScriptElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedString.h" #include "SVGElement.h" @@ -31,66 +30,61 @@ namespace WebCore { -class SVGScriptElement final : public SVGElement - , public SVGURIReference - , public SVGExternalResourcesRequired - , public ScriptElement { +class SVGScriptElement final : public SVGElement, public SVGURIReference, public SVGExternalResourcesRequired, public ScriptElement { public: - static PassRefPtr<SVGScriptElement> create(const QualifiedName&, Document&, bool wasInsertedByParser); + static Ref<SVGScriptElement> create(const QualifiedName&, Document&, bool wasInsertedByParser); -#ifndef NDEBUG - virtual bool isAnimatableAttribute(const QualifiedName&) const override; -#endif + using SVGElement::ref; + using SVGElement::deref; private: SVGScriptElement(const QualifiedName&, Document&, bool wasInsertedByParser, bool alreadyStarted); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void didNotifySubtreeInsertions(ContainerNode*) override; - virtual void childrenChanged(const ChildChange&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + InsertionNotificationRequest insertedInto(ContainerNode&) final; + void finishedInsertingSubtree() final; + void childrenChanged(const ChildChange&) final; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual bool isURLAttribute(const Attribute&) const override; - virtual void finishParsingChildren() override; + void svgAttributeChanged(const QualifiedName&) final; + bool isURLAttribute(const Attribute&) const final; + void finishParsingChildren() final; - virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override; + void addSubresourceAttributeURLs(ListHashSet<URL>&) const final; - virtual bool haveLoadedRequiredResources() override { return SVGExternalResourcesRequired::haveLoadedRequiredResources(); } + bool haveLoadedRequiredResources() final { return SVGExternalResourcesRequired::haveLoadedRequiredResources(); } - virtual String sourceAttributeValue() const override; - virtual String charsetAttributeValue() const override; - virtual String typeAttributeValue() const override; - virtual String languageAttributeValue() const override; - virtual String forAttributeValue() const override; - virtual String eventAttributeValue() const override; - virtual bool asyncAttributeValue() const override; - virtual bool deferAttributeValue() const override; - virtual bool hasSourceAttribute() const override; + String sourceAttributeValue() const final; + String charsetAttributeValue() const final; + String typeAttributeValue() const final; + String languageAttributeValue() const final; + String forAttributeValue() const final; + String eventAttributeValue() const final; + bool hasAsyncAttribute() const final; + bool hasDeferAttribute() const final; + bool hasNoModuleAttribute() const final; + bool hasSourceAttribute() const final; - virtual void dispatchLoadEvent() override { SVGExternalResourcesRequired::dispatchLoadEvent(this); } + void dispatchLoadEvent() final { SVGExternalResourcesRequired::dispatchLoadEvent(this); } - virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() override; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + Ref<Element> cloneElementWithoutAttributesAndChildren(Document&) final; + bool rendererIsNeeded(const RenderStyle&) final { return false; } // SVGExternalResourcesRequired - virtual void setHaveFiredLoadEvent(bool haveFiredLoadEvent) override { ScriptElement::setHaveFiredLoadEvent(haveFiredLoadEvent); } - virtual bool isParserInserted() const override { return ScriptElement::isParserInserted(); } - virtual bool haveFiredLoadEvent() const override { return ScriptElement::haveFiredLoadEvent(); } - virtual Timer<SVGElement>* svgLoadEventTimer() override { return &m_svgLoadEventTimer; } + void setHaveFiredLoadEvent(bool haveFiredLoadEvent) final { ScriptElement::setHaveFiredLoadEvent(haveFiredLoadEvent); } + bool isParserInserted() const final { return ScriptElement::isParserInserted(); } + bool haveFiredLoadEvent() const final { return ScriptElement::haveFiredLoadEvent(); } + Timer* svgLoadEventTimer() final { return &m_svgLoadEventTimer; } + +#ifndef NDEBUG + bool filterOutAnimatableAttribute(const QualifiedName&) const final; +#endif BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGScriptElement) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES - Timer<SVGElement> m_svgLoadEventTimer; + Timer m_svgLoadEventTimer; }; -NODE_TYPE_CASTS(SVGScriptElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGScriptElement.idl b/Source/WebCore/svg/SVGScriptElement.idl index 49db3ae51..ef60d4212 100644 --- a/Source/WebCore/svg/SVGScriptElement.idl +++ b/Source/WebCore/svg/SVGScriptElement.idl @@ -23,10 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGScriptElement : SVGElement { - [TreatNullAs=NullString, Reflect] attribute DOMString type; +interface SVGScriptElement : SVGElement { + [Reflect] attribute DOMString type; }; SVGScriptElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGSetElement.cpp b/Source/WebCore/svg/SVGSetElement.cpp index 9816afe98..9ae8ebe84 100644 --- a/Source/WebCore/svg/SVGSetElement.cpp +++ b/Source/WebCore/svg/SVGSetElement.cpp @@ -19,22 +19,22 @@ */ #include "config.h" -#if ENABLE(SVG) #include "SVGSetElement.h" + #include "SVGNames.h" namespace WebCore { inline SVGSetElement::SVGSetElement(const QualifiedName& tagName, Document& document) - : SVGAnimateElement(tagName, document) + : SVGAnimateElementBase(tagName, document) { setAnimationMode(ToAnimation); ASSERT(hasTagName(SVGNames::setTag)); } -PassRefPtr<SVGSetElement> SVGSetElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGSetElement> SVGSetElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGSetElement(tagName, document)); + return adoptRef(*new SVGSetElement(tagName, document)); } void SVGSetElement::updateAnimationMode() @@ -44,7 +44,3 @@ void SVGSetElement::updateAnimationMode() } } - -// vim:ts=4:noet -#endif // ENABLE(SVG) - diff --git a/Source/WebCore/svg/SVGSetElement.h b/Source/WebCore/svg/SVGSetElement.h index a82186643..1fe688b3c 100644 --- a/Source/WebCore/svg/SVGSetElement.h +++ b/Source/WebCore/svg/SVGSetElement.h @@ -18,27 +18,20 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGSetElement_h -#define SVGSetElement_h -#if ENABLE(SVG) +#pragma once -#include "SVGAnimateElement.h" +#include "SVGAnimateElementBase.h" namespace WebCore { // SVGAnimateElement implements superset of the functionality. -class SVGSetElement final : public SVGAnimateElement { +class SVGSetElement final : public SVGAnimateElementBase { public: - static PassRefPtr<SVGSetElement> create(const QualifiedName&, Document&); + static Ref<SVGSetElement> create(const QualifiedName&, Document&); private: SVGSetElement(const QualifiedName&, Document&); - virtual void updateAnimationMode() override; + void updateAnimationMode() override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGSetElement.idl b/Source/WebCore/svg/SVGSetElement.idl index f53cb921c..322ed53d9 100644 --- a/Source/WebCore/svg/SVGSetElement.idl +++ b/Source/WebCore/svg/SVGSetElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGSetElement : SVGAnimationElement { +interface SVGSetElement : SVGAnimationElement { }; diff --git a/Source/WebCore/svg/SVGStopElement.cpp b/Source/WebCore/svg/SVGStopElement.cpp index 54f91936d..acf73a848 100644 --- a/Source/WebCore/svg/SVGStopElement.cpp +++ b/Source/WebCore/svg/SVGStopElement.cpp @@ -19,15 +19,11 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGStopElement.h" -#include "Attribute.h" #include "Document.h" #include "RenderSVGGradientStop.h" #include "RenderSVGResource.h" -#include "SVGElementInstance.h" #include "SVGGradientElement.h" #include "SVGNames.h" @@ -49,26 +45,13 @@ inline SVGStopElement::SVGStopElement(const QualifiedName& tagName, Document& do registerAnimatedPropertiesForSVGStopElement(); } -PassRefPtr<SVGStopElement> SVGStopElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGStopElement(tagName, document)); -} - -bool SVGStopElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGStopElement> SVGStopElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - supportedAttributes.add(SVGNames::offsetAttr); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGStopElement(tagName, document)); } void SVGStopElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::offsetAttr) { if (value.endsWith('%')) setOffsetBaseValue(value.string().left(value.length() - 1).toFloat() / 100.0f); @@ -77,30 +60,25 @@ void SVGStopElement::parseAttribute(const QualifiedName& name, const AtomicStrin return; } - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); } void SVGStopElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::offsetAttr) { - if (auto renderer = this->renderer()) + if (auto renderer = this->renderer()) { + InstanceInvalidationGuard guard(*this); RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } return; } - ASSERT_NOT_REACHED(); + SVGElement::svgAttributeChanged(attrName); } -RenderPtr<RenderElement> SVGStopElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGStopElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGGradientStop>(*this, std::move(style)); + return createRenderer<RenderSVGGradientStop>(*this, WTFMove(style)); } bool SVGStopElement::rendererIsNeeded(const RenderStyle&) @@ -110,7 +88,7 @@ bool SVGStopElement::rendererIsNeeded(const RenderStyle&) Color SVGStopElement::stopColorIncludingOpacity() const { - RenderStyle* style = renderer() ? &renderer()->style() : nullptr; + auto* style = renderer() ? &renderer()->style() : nullptr; // FIXME: This check for null style exists to address Bug WK 90814, a rare crash condition in // which the renderer or style is null. This entire class is scheduled for removal (Bug WK 86941) // and we will tolerate this null check until then. @@ -122,5 +100,3 @@ Color SVGStopElement::stopColorIncludingOpacity() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGStopElement.h b/Source/WebCore/svg/SVGStopElement.h index 00f92acc7..37fb9771b 100644 --- a/Source/WebCore/svg/SVGStopElement.h +++ b/Source/WebCore/svg/SVGStopElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGStopElement_h -#define SVGStopElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedNumber.h" #include "SVGElement.h" @@ -29,30 +27,24 @@ namespace WebCore { class SVGStopElement final : public SVGElement { public: - static PassRefPtr<SVGStopElement> create(const QualifiedName&, Document&); + static Ref<SVGStopElement> create(const QualifiedName&, Document&); Color stopColorIncludingOpacity() const; private: SVGStopElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + void svgAttributeChanged(const QualifiedName&) final; - virtual bool isGradientStop() const override { return true; } + bool isGradientStop() const final { return true; } - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool rendererIsNeeded(const RenderStyle&) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; + bool rendererIsNeeded(const RenderStyle&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGStopElement) DECLARE_ANIMATED_NUMBER(Offset, offset) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGStopElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGStopElement.idl b/Source/WebCore/svg/SVGStopElement.idl index 8411974f0..6a4d37d88 100644 --- a/Source/WebCore/svg/SVGStopElement.idl +++ b/Source/WebCore/svg/SVGStopElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGStopElement : SVGElement { +interface SVGStopElement : SVGElement { readonly attribute SVGAnimatedNumber offset; }; diff --git a/Source/WebCore/svg/SVGStringList.h b/Source/WebCore/svg/SVGStringList.h index 5463cc22a..7fe7f00fc 100644 --- a/Source/WebCore/svg/SVGStringList.h +++ b/Source/WebCore/svg/SVGStringList.h @@ -1,60 +1,58 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGStringList_h -#define SVGStringList_h +#pragma once -#if ENABLE(SVG) -#include "QualifiedName.h" -#include "SVGPropertyTraits.h" -#include <wtf/Vector.h> +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGListPropertyTearOff.h" +#include "SVGStringListValues.h" namespace WebCore { -class SVGElement; - -class SVGStringList : public Vector<String> { +class SVGStringList final : public SVGStaticListPropertyTearOff<SVGStringListValues> { public: - SVGStringList(const QualifiedName& attributeName) - : m_attributeName(attributeName) + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<SVGStringListValues>; + using ListWrapperCache = AnimatedListPropertyTearOff::ListWrapperCache; + + static Ref<SVGStringList> create(SVGElement& contextElement, SVGStringListValues& values) { + return adoptRef(*new SVGStringList(&contextElement, values)); } - void reset(const String&); - void parse(const String&, UChar delimiter = ','); - - // Only used by SVGStringListPropertyTearOff. - void commitChange(SVGElement* contextElement); - - String valueAsString() const; + static Ref<SVGStringList> create(AnimatedListPropertyTearOff&, SVGPropertyRole, SVGStringListValues& values, ListWrapperCache&) + { + // FIXME: Find a way to remove this. It's only needed to keep Windows compiling. + ASSERT_NOT_REACHED(); + return adoptRef(*new SVGStringList(nullptr, values)); + } private: - const QualifiedName& m_attributeName; -}; - -template<> -struct SVGPropertyTraits<SVGStringList> { - typedef String ListItemType; + SVGStringList(SVGElement* contextElement, SVGStringListValues& values) + : SVGStaticListPropertyTearOff<SVGStringListValues>(contextElement, values) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGStringList.idl b/Source/WebCore/svg/SVGStringList.idl index 2b87ca2c7..f52c75ca6 100644 --- a/Source/WebCore/svg/SVGStringList.idl +++ b/Source/WebCore/svg/SVGStringList.idl @@ -23,17 +23,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGStringList { +interface SVGStringList { readonly attribute unsigned long numberOfItems; - [RaisesException] void clear(); - [StrictTypeChecking, RaisesException] DOMString initialize(DOMString item); - [StrictTypeChecking, RaisesException] DOMString getItem(unsigned long index); - [StrictTypeChecking, RaisesException] DOMString insertItemBefore(DOMString item, unsigned long index); - [StrictTypeChecking, RaisesException] DOMString replaceItem(DOMString item, unsigned long index); - [StrictTypeChecking, RaisesException] DOMString removeItem(unsigned long index); - [StrictTypeChecking, RaisesException] DOMString appendItem(DOMString item); + [MayThrowException] void clear(); + [MayThrowException] DOMString initialize(DOMString item); + [MayThrowException] DOMString getItem(unsigned long index); + [MayThrowException] DOMString insertItemBefore(DOMString item, unsigned long index); + [MayThrowException] DOMString replaceItem(DOMString item, unsigned long index); + [MayThrowException] DOMString removeItem(unsigned long index); + [MayThrowException] DOMString appendItem(DOMString item); }; - diff --git a/Source/WebCore/svg/SVGStringList.cpp b/Source/WebCore/svg/SVGStringListValues.cpp index e738cf596..3ff898a91 100644 --- a/Source/WebCore/svg/SVGStringList.cpp +++ b/Source/WebCore/svg/SVGStringListValues.cpp @@ -19,9 +19,7 @@ */ #include "config.h" - -#if ENABLE(SVG) -#include "SVGStringList.h" +#include "SVGStringListValues.h" #include "SVGElement.h" #include "SVGParserUtilities.h" @@ -29,14 +27,13 @@ namespace WebCore { -void SVGStringList::commitChange(SVGElement* contextElement) +void SVGStringListValues::commitChange(SVGElement& contextElement) { - ASSERT(contextElement); - contextElement->invalidateSVGAttributes(); - contextElement->svgAttributeChanged(m_attributeName); + contextElement.invalidateSVGAttributes(); + contextElement.svgAttributeChanged(m_attributeName); } -void SVGStringList::reset(const String& string) +void SVGStringListValues::reset(const String& string) { parse(string, ' '); @@ -45,12 +42,13 @@ void SVGStringList::reset(const String& string) append(emptyString()); } -void SVGStringList::parse(const String& data, UChar delimiter) +void SVGStringListValues::parse(const String& data, UChar delimiter) { // TODO : more error checking/reporting clear(); - const UChar* ptr = data.deprecatedCharacters(); + auto upconvertedCharacters = StringView(data).upconvertedCharacters(); + const UChar* ptr = upconvertedCharacters; const UChar* end = ptr + data.length(); while (ptr < end) { const UChar* start = ptr; @@ -63,7 +61,7 @@ void SVGStringList::parse(const String& data, UChar delimiter) } } -String SVGStringList::valueAsString() const +String SVGStringListValues::valueAsString() const { StringBuilder builder; @@ -79,5 +77,3 @@ String SVGStringList::valueAsString() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGStringListValues.h b/Source/WebCore/svg/SVGStringListValues.h new file mode 100644 index 000000000..89651c7af --- /dev/null +++ b/Source/WebCore/svg/SVGStringListValues.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@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. + */ + +#pragma once + +#include "QualifiedName.h" +#include "SVGPropertyTraits.h" +#include <wtf/Vector.h> + +namespace WebCore { + +class SVGElement; +class SVGStringList; + +template<typename T> +class SVGPropertyTearOff; + +class SVGStringListValues final : public Vector<String> { +public: + SVGStringListValues(const QualifiedName& attributeName) + : m_attributeName(attributeName) + { + } + + void reset(const String&); + void parse(const String&, UChar delimiter = ','); + + // Only used by SVGStringList. + void commitChange(SVGElement& contextElement); + + String valueAsString() const; + +private: + const QualifiedName& m_attributeName; +}; + +template<> struct SVGPropertyTraits<SVGStringListValues> { + using ListItemType = String; + using ListItemTearOff = SVGPropertyTearOff<String>; + using ListPropertyTearOff = SVGStringList; +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGStyleElement.cpp b/Source/WebCore/svg/SVGStyleElement.cpp index dcc8699c7..8f8f9ef80 100644 --- a/Source/WebCore/svg/SVGStyleElement.cpp +++ b/Source/WebCore/svg/SVGStyleElement.cpp @@ -21,14 +21,10 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGStyleElement.h" -#include "Attribute.h" #include "CSSStyleSheet.h" #include "Document.h" -#include "ExceptionCode.h" #include "SVGNames.h" #include <wtf/StdLibExtras.h> @@ -37,19 +33,19 @@ namespace WebCore { inline SVGStyleElement::SVGStyleElement(const QualifiedName& tagName, Document& document, bool createdByParser) : SVGElement(tagName, document) , m_styleSheetOwner(document, createdByParser) - , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) + , m_svgLoadEventTimer(*this, &SVGElement::svgLoadEventTimerFired) { ASSERT(hasTagName(SVGNames::styleTag)); } SVGStyleElement::~SVGStyleElement() { - m_styleSheetOwner.clearDocumentData(document(), *this); + m_styleSheetOwner.clearDocumentData(*this); } -PassRefPtr<SVGStyleElement> SVGStyleElement::create(const QualifiedName& tagName, Document& document, bool createdByParser) +Ref<SVGStyleElement> SVGStyleElement::create(const QualifiedName& tagName, Document& document, bool createdByParser) { - return adoptRef(new SVGStyleElement(tagName, document, createdByParser)); + return adoptRef(*new SVGStyleElement(tagName, document, createdByParser)); } bool SVGStyleElement::disabled() const @@ -65,56 +61,35 @@ void SVGStyleElement::setDisabled(bool setDisabled) const AtomicString& SVGStyleElement::type() const { - DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("text/css", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> defaultValue("text/css", AtomicString::ConstructFromLiteral); const AtomicString& n = getAttribute(SVGNames::typeAttr); - return n.isNull() ? defaultValue : n; + return n.isNull() ? defaultValue.get() : n; } -void SVGStyleElement::setType(const AtomicString& type, ExceptionCode&) +void SVGStyleElement::setType(const AtomicString& type) { setAttribute(SVGNames::typeAttr, type); } const AtomicString& SVGStyleElement::media() const { - DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("all", AtomicString::ConstructFromLiteral)); - const AtomicString& n = fastGetAttribute(SVGNames::mediaAttr); - return n.isNull() ? defaultValue : n; + static NeverDestroyed<const AtomicString> defaultValue("all", AtomicString::ConstructFromLiteral); + const AtomicString& n = attributeWithoutSynchronization(SVGNames::mediaAttr); + return n.isNull() ? defaultValue.get() : n; } -void SVGStyleElement::setMedia(const AtomicString& media, ExceptionCode&) +void SVGStyleElement::setMedia(const AtomicString& media) { - setAttribute(SVGNames::mediaAttr, media); + setAttributeWithoutSynchronization(SVGNames::mediaAttr, media); } String SVGStyleElement::title() const { - return fastGetAttribute(SVGNames::titleAttr); -} - -void SVGStyleElement::setTitle(const AtomicString& title, ExceptionCode&) -{ - setAttribute(SVGNames::titleAttr, title); -} - -bool SVGStyleElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGLangSpace::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::titleAttr); - supportedAttributes.add(SVGNames::mediaAttr); - supportedAttributes.add(SVGNames::typeAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return attributeWithoutSynchronization(SVGNames::titleAttr); } void SVGStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } if (name == SVGNames::titleAttr) { if (sheet()) sheet()->setTitle(value); @@ -128,10 +103,8 @@ void SVGStyleElement::parseAttribute(const QualifiedName& name, const AtomicStri m_styleSheetOwner.setMedia(value); return; } - if (SVGLangSpace::parseAttribute(name, value)) - return; - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); } void SVGStyleElement::finishParsingChildren() @@ -142,17 +115,18 @@ void SVGStyleElement::finishParsingChildren() Node::InsertionNotificationRequest SVGStyleElement::insertedInto(ContainerNode& rootParent) { - SVGElement::insertedInto(rootParent); - if (rootParent.inDocument()) - m_styleSheetOwner.insertedIntoDocument(document(), *this); - return InsertionDone; + bool wasInDocument = isConnected(); + auto result = SVGElement::insertedInto(rootParent); + if (rootParent.isConnected() && !wasInDocument) + m_styleSheetOwner.insertedIntoDocument(*this); + return result; } void SVGStyleElement::removedFrom(ContainerNode& rootParent) { SVGElement::removedFrom(rootParent); - if (rootParent.inDocument()) - m_styleSheetOwner.removedFromDocument(document(), *this); + if (rootParent.isConnected() && !isConnected()) + m_styleSheetOwner.removedFromDocument(*this); } void SVGStyleElement::childrenChanged(const ChildChange& change) @@ -162,5 +136,3 @@ void SVGStyleElement::childrenChanged(const ChildChange& change) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGStyleElement.h b/Source/WebCore/svg/SVGStyleElement.h index e583a32fd..701dad7e6 100644 --- a/Source/WebCore/svg/SVGStyleElement.h +++ b/Source/WebCore/svg/SVGStyleElement.h @@ -19,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGStyleElement_h -#define SVGStyleElement_h +#pragma once -#if ENABLE(SVG) #include "InlineStyleSheetOwner.h" #include "SVGElement.h" @@ -30,7 +28,7 @@ namespace WebCore { class SVGStyleElement final : public SVGElement { public: - static PassRefPtr<SVGStyleElement> create(const QualifiedName&, Document&, bool createdByParser); + static Ref<SVGStyleElement> create(const QualifiedName&, Document&, bool createdByParser); virtual ~SVGStyleElement(); CSSStyleSheet* sheet() const { return m_styleSheetOwner.sheet(); } @@ -39,39 +37,32 @@ public: void setDisabled(bool); const AtomicString& type() const; - void setType(const AtomicString&, ExceptionCode&); + void setType(const AtomicString&); const AtomicString& media() const; - void setMedia(const AtomicString&, ExceptionCode&); - - String title() const override; - void setTitle(const AtomicString&, ExceptionCode&); + void setMedia(const AtomicString&); private: SVGStyleElement(const QualifiedName&, Document&, bool createdByParser); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - virtual void childrenChanged(const ChildChange&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; + InsertionNotificationRequest insertedInto(ContainerNode&) final; + void removedFrom(ContainerNode&) final; + void childrenChanged(const ChildChange&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } - virtual void finishParsingChildren() override; + void finishParsingChildren() final; virtual bool isLoading() const { return m_styleSheetOwner.isLoading(); } - virtual bool sheetLoaded() override { return m_styleSheetOwner.sheetLoaded(document()); } - virtual void startLoadingDynamicSheet() override { m_styleSheetOwner.startLoadingDynamicSheet(document()); } - virtual Timer<SVGElement>* svgLoadEventTimer() override { return &m_svgLoadEventTimer; } + bool sheetLoaded() final { return m_styleSheetOwner.sheetLoaded(*this); } + void startLoadingDynamicSheet() final { m_styleSheetOwner.startLoadingDynamicSheet(*this); } + Timer* svgLoadEventTimer() final { return &m_svgLoadEventTimer; } + + String title() const final; InlineStyleSheetOwner m_styleSheetOwner; - Timer<SVGElement> m_svgLoadEventTimer; + Timer m_svgLoadEventTimer; }; -NODE_TYPE_CASTS(SVGStyleElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGStyleElement_h diff --git a/Source/WebCore/svg/SVGStyleElement.idl b/Source/WebCore/svg/SVGStyleElement.idl index c18839226..5201f33ad 100644 --- a/Source/WebCore/svg/SVGStyleElement.idl +++ b/Source/WebCore/svg/SVGStyleElement.idl @@ -24,12 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGStyleElement : SVGElement { - attribute boolean disabled; - [SetterRaisesException] attribute DOMString type; - [SetterRaisesException] attribute DOMString media; - [SetterRaisesException] attribute DOMString title; +interface SVGStyleElement : SVGElement { + attribute boolean disabled; + attribute DOMString type; + attribute DOMString media; + [Reflect] attribute DOMString title; }; - diff --git a/Source/WebCore/svg/SVGSwitchElement.cpp b/Source/WebCore/svg/SVGSwitchElement.cpp index 25ce517cd..a40571ac9 100644 --- a/Source/WebCore/svg/SVGSwitchElement.cpp +++ b/Source/WebCore/svg/SVGSwitchElement.cpp @@ -19,8 +19,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGSwitchElement.h" #include "ElementIterator.h" @@ -44,9 +42,9 @@ inline SVGSwitchElement::SVGSwitchElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGSwitchElement(); } -PassRefPtr<SVGSwitchElement> SVGSwitchElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGSwitchElement> SVGSwitchElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGSwitchElement(tagName, document)); + return adoptRef(*new SVGSwitchElement(tagName, document)); } bool SVGSwitchElement::childShouldCreateRenderer(const Node& child) const @@ -62,11 +60,9 @@ bool SVGSwitchElement::childShouldCreateRenderer(const Node& child) const return false; } -RenderPtr<RenderElement> SVGSwitchElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGSwitchElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGTransformableContainer>(*this, std::move(style)); + return createRenderer<RenderSVGTransformableContainer>(*this, WTFMove(style)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGSwitchElement.h b/Source/WebCore/svg/SVGSwitchElement.h index 284568b79..0ff011b44 100644 --- a/Source/WebCore/svg/SVGSwitchElement.h +++ b/Source/WebCore/svg/SVGSwitchElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGSwitchElement_h -#define SVGSwitchElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGExternalResourcesRequired.h" #include "SVGGraphicsElement.h" @@ -31,23 +29,19 @@ namespace WebCore { class SVGSwitchElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - static PassRefPtr<SVGSwitchElement> create(const QualifiedName&, Document&); + static Ref<SVGSwitchElement> create(const QualifiedName&, Document&); private: SVGSwitchElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } + bool isValid() const final { return SVGTests::isValid(); } - virtual bool childShouldCreateRenderer(const Node&) const override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; + bool childShouldCreateRenderer(const Node&) const final; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSwitchElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGSwitchElement.idl b/Source/WebCore/svg/SVGSwitchElement.idl index 941075552..9b2a1df23 100644 --- a/Source/WebCore/svg/SVGSwitchElement.idl +++ b/Source/WebCore/svg/SVGSwitchElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGSwitchElement : SVGGraphicsElement { +interface SVGSwitchElement : SVGGraphicsElement { }; SVGSwitchElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGSymbolElement.cpp b/Source/WebCore/svg/SVGSymbolElement.cpp index ca9d770ce..051bdc539 100644 --- a/Source/WebCore/svg/SVGSymbolElement.cpp +++ b/Source/WebCore/svg/SVGSymbolElement.cpp @@ -19,12 +19,9 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGSymbolElement.h" #include "RenderSVGHiddenContainer.h" -#include "SVGElementInstance.h" #include "SVGFitToViewBox.h" #include "SVGNames.h" @@ -49,51 +46,27 @@ inline SVGSymbolElement::SVGSymbolElement(const QualifiedName& tagName, Document registerAnimatedPropertiesForSVGSymbolElement(); } -PassRefPtr<SVGSymbolElement> SVGSymbolElement::create(const QualifiedName& tagName, Document& document) -{ - return adoptRef(new SVGSymbolElement(tagName, document)); -} - -bool SVGSymbolElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGSymbolElement> SVGSymbolElement::create(const QualifiedName& tagName, Document& document) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - SVGFitToViewBox::addSupportedAttributes(supportedAttributes); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return adoptRef(*new SVGSymbolElement(tagName, document)); } void SVGSymbolElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - - if (SVGLangSpace::parseAttribute(name, value)) - return; - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - if (SVGFitToViewBox::parseAttribute(this, name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGFitToViewBox::parseAttribute(this, name, value); } void SVGSymbolElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGElement::svgAttributeChanged(attrName); + if (attrName == SVGNames::viewBoxAttr) { + InstanceInvalidationGuard guard(*this); + updateRelativeLengthsInformation(); return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - // Every other property change is ignored. - if (attrName == SVGNames::viewBoxAttr) - updateRelativeLengthsInformation(); + SVGElement::svgAttributeChanged(attrName); } bool SVGSymbolElement::selfHasRelativeLengths() const @@ -101,11 +74,9 @@ bool SVGSymbolElement::selfHasRelativeLengths() const return hasAttribute(SVGNames::viewBoxAttr); } -RenderPtr<RenderElement> SVGSymbolElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGSymbolElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGHiddenContainer>(*this, std::move(style)); + return createRenderer<RenderSVGHiddenContainer>(*this, WTFMove(style)); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGSymbolElement.h b/Source/WebCore/svg/SVGSymbolElement.h index 8bacaf537..57857f0dc 100644 --- a/Source/WebCore/svg/SVGSymbolElement.h +++ b/Source/WebCore/svg/SVGSymbolElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGSymbolElement_h -#define SVGSymbolElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedPreserveAspectRatio.h" #include "SVGAnimatedRect.h" @@ -35,28 +33,22 @@ class SVGSymbolElement final : public SVGElement, public SVGExternalResourcesRequired, public SVGFitToViewBox { public: - static PassRefPtr<SVGSymbolElement> create(const QualifiedName&, Document&); + static Ref<SVGSymbolElement> create(const QualifiedName&, Document&); private: SVGSymbolElement(const QualifiedName&, Document&); - virtual bool supportsFocus() const override { return true; } + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSymbolElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) DECLARE_ANIMATED_RECT(ViewBox, viewBox) DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) END_DECLARE_ANIMATED_PROPERTIES }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGSymbolElement.idl b/Source/WebCore/svg/SVGSymbolElement.idl index 75b991369..4d6a67888 100644 --- a/Source/WebCore/svg/SVGSymbolElement.idl +++ b/Source/WebCore/svg/SVGSymbolElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGSymbolElement : SVGElement { +interface SVGSymbolElement : SVGElement { }; SVGSymbolElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGTRefElement.cpp b/Source/WebCore/svg/SVGTRefElement.cpp index 012974bfc..a4ff46ab0 100644 --- a/Source/WebCore/svg/SVGTRefElement.cpp +++ b/Source/WebCore/svg/SVGTRefElement.cpp @@ -20,20 +20,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTRefElement.h" #include "EventListener.h" #include "EventNames.h" -#include "ExceptionCodePlaceholder.h" #include "MutationEvent.h" #include "RenderSVGInline.h" #include "RenderSVGInlineText.h" #include "RenderSVGResource.h" #include "ShadowRoot.h" #include "SVGDocument.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "StyleInheritedData.h" #include "Text.h" @@ -49,57 +45,55 @@ BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTRefElement) REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextPositioningElement) END_REGISTER_ANIMATED_PROPERTIES -PassRefPtr<SVGTRefElement> SVGTRefElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGTRefElement> SVGTRefElement::create(const QualifiedName& tagName, Document& document) { - RefPtr<SVGTRefElement> element = adoptRef(new SVGTRefElement(tagName, document)); + Ref<SVGTRefElement> element = adoptRef(*new SVGTRefElement(tagName, document)); element->ensureUserAgentShadowRoot(); - return element.release(); + return element; } -class SVGTRefTargetEventListener : public EventListener { +class SVGTRefTargetEventListener final : public EventListener { public: - static PassRefPtr<SVGTRefTargetEventListener> create(SVGTRefElement* trefElement) + static Ref<SVGTRefTargetEventListener> create(SVGTRefElement& trefElement) { - return adoptRef(new SVGTRefTargetEventListener(trefElement)); + return adoptRef(*new SVGTRefTargetEventListener(trefElement)); } static const SVGTRefTargetEventListener* cast(const EventListener* listener) { - return listener->type() == SVGTRefTargetEventListenerType - ? static_cast<const SVGTRefTargetEventListener*>(listener) : 0; + return listener->type() == SVGTRefTargetEventListenerType ? static_cast<const SVGTRefTargetEventListener*>(listener) : nullptr; } - void attach(PassRefPtr<Element> target); + void attach(RefPtr<Element>&& target); void detach(); bool isAttached() const { return m_target.get(); } private: - SVGTRefTargetEventListener(SVGTRefElement* trefElement); + explicit SVGTRefTargetEventListener(SVGTRefElement& trefElement); - virtual void handleEvent(ScriptExecutionContext*, Event*) override; - virtual bool operator==(const EventListener&) override; + void handleEvent(ScriptExecutionContext*, Event*) final; + bool operator==(const EventListener&) const final; - SVGTRefElement* m_trefElement; + SVGTRefElement& m_trefElement; RefPtr<Element> m_target; }; -SVGTRefTargetEventListener::SVGTRefTargetEventListener(SVGTRefElement* trefElement) +SVGTRefTargetEventListener::SVGTRefTargetEventListener(SVGTRefElement& trefElement) : EventListener(SVGTRefTargetEventListenerType) , m_trefElement(trefElement) - , m_target(0) + , m_target(nullptr) { - ASSERT(m_trefElement); } -void SVGTRefTargetEventListener::attach(PassRefPtr<Element> target) +void SVGTRefTargetEventListener::attach(RefPtr<Element>&& target) { ASSERT(!isAttached()); ASSERT(target.get()); - ASSERT(target->inDocument()); + ASSERT(target->isConnected()); - target->addEventListener(eventNames().DOMSubtreeModifiedEvent, this, false); - target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this, false); - m_target = target; + target->addEventListener(eventNames().DOMSubtreeModifiedEvent, *this, false); + target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, *this, false); + m_target = WTFMove(target); } void SVGTRefTargetEventListener::detach() @@ -107,15 +101,15 @@ void SVGTRefTargetEventListener::detach() if (!isAttached()) return; - m_target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this, false); - m_target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this, false); - m_target.clear(); + m_target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, *this, false); + m_target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, *this, false); + m_target = nullptr; } -bool SVGTRefTargetEventListener::operator==(const EventListener& listener) +bool SVGTRefTargetEventListener::operator==(const EventListener& listener) const { if (const SVGTRefTargetEventListener* targetListener = SVGTRefTargetEventListener::cast(&listener)) - return m_trefElement == targetListener->m_trefElement; + return &m_trefElement == &targetListener->m_trefElement; return false; } @@ -123,15 +117,15 @@ void SVGTRefTargetEventListener::handleEvent(ScriptExecutionContext*, Event* eve { ASSERT(isAttached()); - if (event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement != event->target()) - m_trefElement->updateReferencedText(m_target.get()); + if (event->type() == eventNames().DOMSubtreeModifiedEvent && &m_trefElement != event->target()) + m_trefElement.updateReferencedText(m_target.get()); else if (event->type() == eventNames().DOMNodeRemovedFromDocumentEvent) - m_trefElement->detachTarget(); + m_trefElement.detachTarget(); } inline SVGTRefElement::SVGTRefElement(const QualifiedName& tagName, Document& document) : SVGTextPositioningElement(tagName, document) - , m_targetListener(SVGTRefTargetEventListener::create(this)) + , m_targetListener(SVGTRefTargetEventListener::create(*this)) { ASSERT(hasTagName(SVGNames::trefTag)); registerAnimatedPropertiesForSVGTRefElement(); @@ -151,10 +145,10 @@ void SVGTRefElement::updateReferencedText(Element* target) ASSERT(shadowRoot()); ShadowRoot* root = shadowRoot(); if (!root->firstChild()) - root->appendChild(Text::create(document(), textContent), ASSERT_NO_EXCEPTION); + root->appendChild(Text::create(document(), textContent)); else { ASSERT(root->firstChild()->isTextNode()); - root->firstChild()->setTextContent(textContent, ASSERT_NO_EXCEPTION); + root->firstChild()->setTextContent(textContent); } } @@ -168,61 +162,40 @@ void SVGTRefElement::detachTarget() ASSERT(shadowRoot()); Node* container = shadowRoot()->firstChild(); if (container) - container->setTextContent(emptyContent, IGNORE_EXCEPTION); + container->setTextContent(emptyContent); - if (!inDocument()) + if (!isConnected()) return; // Mark the referenced ID as pending. String id; SVGURIReference::targetElementFromIRIString(href(), document(), &id); if (!id.isEmpty()) - document().accessSVGExtensions()->addPendingResource(id, this); -} - -bool SVGTRefElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - SVGURIReference::addSupportedAttributes(supportedAttributes); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + document().accessSVGExtensions().addPendingResource(id, this); } void SVGTRefElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGTextPositioningElement::parseAttribute(name, value); - return; - } - - if (SVGURIReference::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGTextPositioningElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); } void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGTextPositioningElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (SVGURIReference::isKnownAttribute(attrName)) { + InstanceInvalidationGuard guard(*this); buildPendingResource(); if (auto renderer = this->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } - ASSERT_NOT_REACHED(); + SVGTextPositioningElement::svgAttributeChanged(attrName); } -RenderPtr<RenderElement> SVGTRefElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGTRefElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGInline>(*this, std::move(style)); + return createRenderer<RenderSVGInline>(*this, WTFMove(style)); } bool SVGTRefElement::childShouldCreateRenderer(const Node& child) const @@ -245,13 +218,18 @@ bool SVGTRefElement::rendererIsNeeded(const RenderStyle& style) return false; } +void SVGTRefElement::clearTarget() +{ + m_targetListener->detach(); +} + void SVGTRefElement::buildPendingResource() { // Remove any existing event listener. m_targetListener->detach(); // If we're not yet in a document, this function will be called again from insertedInto(). - if (!inDocument()) + if (!isConnected()) return; String id; @@ -260,7 +238,7 @@ void SVGTRefElement::buildPendingResource() if (id.isEmpty()) return; - document().accessSVGExtensions()->addPendingResource(id, this); + document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); return; } @@ -270,7 +248,7 @@ void SVGTRefElement::buildPendingResource() // expects every element instance to have an associated shadow tree element - which is not the // case when we land here from SVGUseElement::buildShadowTree(). if (!isInShadowTree()) - m_targetListener->attach(target); + m_targetListener->attach(target.copyRef()); updateReferencedText(target.get()); } @@ -278,18 +256,21 @@ void SVGTRefElement::buildPendingResource() Node::InsertionNotificationRequest SVGTRefElement::insertedInto(ContainerNode& rootParent) { SVGElement::insertedInto(rootParent); - if (rootParent.inDocument()) - buildPendingResource(); + if (rootParent.isConnected()) + return InsertionShouldCallFinishedInsertingSubtree; return InsertionDone; } +void SVGTRefElement::finishedInsertingSubtree() +{ + buildPendingResource(); +} + void SVGTRefElement::removedFrom(ContainerNode& rootParent) { SVGElement::removedFrom(rootParent); - if (rootParent.inDocument()) + if (rootParent.isConnected()) m_targetListener->detach(); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTRefElement.h b/Source/WebCore/svg/SVGTRefElement.h index 1f588892a..f720cf2f7 100644 --- a/Source/WebCore/svg/SVGTRefElement.h +++ b/Source/WebCore/svg/SVGTRefElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTRefElement_h -#define SVGTRefElement_h +#pragma once -#if ENABLE(SVG) #include "SVGTextPositioningElement.h" #include "SVGURIReference.h" @@ -29,10 +27,9 @@ namespace WebCore { class SVGTRefTargetEventListener; -class SVGTRefElement final : public SVGTextPositioningElement, - public SVGURIReference { +class SVGTRefElement final : public SVGTextPositioningElement, public SVGURIReference { public: - static PassRefPtr<SVGTRefElement> create(const QualifiedName&, Document&); + static Ref<SVGTRefElement> create(const QualifiedName&, Document&); private: friend class SVGTRefTargetEventListener; @@ -40,31 +37,30 @@ private: SVGTRefElement(const QualifiedName&, Document&); virtual ~SVGTRefElement(); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool childShouldCreateRenderer(const Node&) const override; - virtual bool rendererIsNeeded(const RenderStyle&) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool childShouldCreateRenderer(const Node&) const override; + bool rendererIsNeeded(const RenderStyle&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; + void finishedInsertingSubtree() override; + + void clearTarget() override; void updateReferencedText(Element*); void detachTarget(); - virtual void buildPendingResource() override; + void buildPendingResource() override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTRefElement) - DECLARE_ANIMATED_STRING(Href, href) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) END_DECLARE_ANIMATED_PROPERTIES - RefPtr<SVGTRefTargetEventListener> m_targetListener; + Ref<SVGTRefTargetEventListener> m_targetListener; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGTRefElement.idl b/Source/WebCore/svg/SVGTRefElement.idl index c63d10794..f9d910ead 100644 --- a/Source/WebCore/svg/SVGTRefElement.idl +++ b/Source/WebCore/svg/SVGTRefElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGTRefElement : SVGTextPositioningElement { +interface SVGTRefElement : SVGTextPositioningElement { }; SVGTRefElement implements SVGURIReference; diff --git a/Source/WebCore/svg/SVGTSpanElement.cpp b/Source/WebCore/svg/SVGTSpanElement.cpp index f93455cea..16127e879 100644 --- a/Source/WebCore/svg/SVGTSpanElement.cpp +++ b/Source/WebCore/svg/SVGTSpanElement.cpp @@ -19,8 +19,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTSpanElement.h" #include "RenderInline.h" @@ -35,14 +33,14 @@ inline SVGTSpanElement::SVGTSpanElement(const QualifiedName& tagName, Document& ASSERT(hasTagName(SVGNames::tspanTag)); } -PassRefPtr<SVGTSpanElement> SVGTSpanElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGTSpanElement> SVGTSpanElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGTSpanElement(tagName, document)); + return adoptRef(*new SVGTSpanElement(tagName, document)); } -RenderPtr<RenderElement> SVGTSpanElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGTSpanElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGTSpan>(*this, std::move(style)); + return createRenderer<RenderSVGTSpan>(*this, WTFMove(style)); } bool SVGTSpanElement::childShouldCreateRenderer(const Node& child) const @@ -75,5 +73,3 @@ bool SVGTSpanElement::rendererIsNeeded(const RenderStyle& style) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTSpanElement.h b/Source/WebCore/svg/SVGTSpanElement.h index 69f03ed4a..2b0a736df 100644 --- a/Source/WebCore/svg/SVGTSpanElement.h +++ b/Source/WebCore/svg/SVGTSpanElement.h @@ -18,27 +18,22 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTSpanElement_h -#define SVGTSpanElement_h +#pragma once -#if ENABLE(SVG) #include "SVGTextPositioningElement.h" namespace WebCore { class SVGTSpanElement final : public SVGTextPositioningElement { public: - static PassRefPtr<SVGTSpanElement> create(const QualifiedName&, Document&); + static Ref<SVGTSpanElement> create(const QualifiedName&, Document&); private: SVGTSpanElement(const QualifiedName&, Document&); - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool childShouldCreateRenderer(const Node&) const override; - virtual bool rendererIsNeeded(const RenderStyle&) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool childShouldCreateRenderer(const Node&) const override; + bool rendererIsNeeded(const RenderStyle&) override; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGTSpanElement.idl b/Source/WebCore/svg/SVGTSpanElement.idl index fa9f7f1d4..92d9754c1 100644 --- a/Source/WebCore/svg/SVGTSpanElement.idl +++ b/Source/WebCore/svg/SVGTSpanElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGTSpanElement : SVGTextPositioningElement { +interface SVGTSpanElement : SVGTextPositioningElement { }; diff --git a/Source/WebCore/svg/SVGTests.cpp b/Source/WebCore/svg/SVGTests.cpp index 1daa76a6c..e44c334f1 100644 --- a/Source/WebCore/svg/SVGTests.cpp +++ b/Source/WebCore/svg/SVGTests.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2015-2016 Apple Inc. All right reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,17 +20,15 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTests.h" -#include "Attribute.h" #include "DOMImplementation.h" #include "HTMLNames.h" #include "Language.h" #include "SVGElement.h" #include "SVGNames.h" #include "SVGStringList.h" +#include <wtf/NeverDestroyed.h> #if ENABLE(MATHML) #include "MathMLNames.h" @@ -37,189 +36,233 @@ namespace WebCore { -// Define custom non-animated property 'requiredFeatures'. -const SVGPropertyInfo* SVGTests::requiredFeaturesPropertyInfo() -{ - static const SVGPropertyInfo* s_propertyInfo = 0; - if (!s_propertyInfo) { - s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, - PropertyIsReadWrite, - SVGNames::requiredFeaturesAttr, - SVGNames::requiredFeaturesAttr.localName(), - &SVGElement::synchronizeRequiredFeatures, - 0); - } - return s_propertyInfo; +using namespace SVGNames; + +static const HashSet<String, ASCIICaseInsensitiveHash>& supportedSVGFeatures() +{ + static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> features = [] { + static const char* const features10[] = { +#if ENABLE(SVG_FONTS) + "dom", + "dom.svg", + "dom.svg.static", + "svg", + "svg.static", +#endif + }; + static const char* const features11[] = { + "animation", + "basegraphicsattribute", + "basicclip", + "basicfilter", + "basicpaintattribute", + "basicstructure", + "basictext", + "clip", + "conditionalprocessing", + "containerattribute", + "coreattribute", + "cursor", + "documenteventsattribute", + "extensibility", + "externalresourcesrequired", + "filter", + "gradient", + "graphicaleventsattribute", + "graphicsattribute", + "hyperlinking", + "image", + "marker", + "mask", + "opacityattribute", + "paintattribute", + "pattern", + "script", + "shape", + "structure", + "style", + "svg-animation", + "svgdom-animation", + "text", + "view", + "viewportattribute", + "xlinkattribute", +#if ENABLE(SVG_FONTS) + "basicfont", + "font", + "svg", + "svg-static", + "svgdom", + "svgdom-static", +#endif + }; + HashSet<String, ASCIICaseInsensitiveHash> set; + for (auto& feature : features10) + set.add(makeString("org.w3c.", feature)); + for (auto& feature : features11) + set.add(makeString("http://www.w3.org/tr/svg11/feature#", feature)); + return set; + }(); + return features; } -// Define custom non-animated property 'requiredExtensions'. -const SVGPropertyInfo* SVGTests::requiredExtensionsPropertyInfo() +SVGTests::SVGTests() + : m_requiredFeatures(requiredFeaturesAttr) + , m_requiredExtensions(requiredExtensionsAttr) + , m_systemLanguage(systemLanguageAttr) { - static const SVGPropertyInfo* s_propertyInfo = 0; - if (!s_propertyInfo) { - s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, - PropertyIsReadWrite, - SVGNames::requiredExtensionsAttr, - SVGNames::requiredExtensionsAttr.localName(), - &SVGElement::synchronizeRequiredExtensions, - 0); - } - return s_propertyInfo; } -// Define custom non-animated property 'systemLanguage'. -const SVGPropertyInfo* SVGTests::systemLanguagePropertyInfo() +static SVGPropertyInfo createSVGTestPropertyInfo(const QualifiedName& attributeName, SVGPropertyInfo::SynchronizeProperty synchronizeFunction) { - static const SVGPropertyInfo* s_propertyInfo = 0; - if (!s_propertyInfo) { - s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, - PropertyIsReadWrite, - SVGNames::systemLanguageAttr, - SVGNames::systemLanguageAttr.localName(), - &SVGElement::synchronizeSystemLanguage, - 0); - } - return s_propertyInfo; + return { AnimatedUnknown, PropertyIsReadWrite, attributeName, attributeName.localName(), synchronizeFunction, nullptr }; } -SVGTests::SVGTests() - : m_requiredFeatures(SVGNames::requiredFeaturesAttr) - , m_requiredExtensions(SVGNames::requiredExtensionsAttr) - , m_systemLanguage(SVGNames::systemLanguageAttr) +static SVGAttributeToPropertyMap createSVGTextAttributeToPropertyMap() { + typedef NeverDestroyed<const SVGPropertyInfo> Info; + + SVGAttributeToPropertyMap map; + + static Info requiredFeatures = createSVGTestPropertyInfo(requiredFeaturesAttr, SVGElement::synchronizeRequiredFeatures); + map.addProperty(requiredFeatures.get()); + + static Info requiredExtensions = createSVGTestPropertyInfo(requiredExtensionsAttr, SVGElement::synchronizeRequiredExtensions); + map.addProperty(requiredExtensions.get()); + + static Info systemLanguage = createSVGTestPropertyInfo(systemLanguageAttr, SVGElement::synchronizeSystemLanguage); + map.addProperty(systemLanguage.get()); + + return map; } -SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap() +const SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap() { - DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, map, ()); - if (!map.isEmpty()) - return map; - map.addProperty(requiredFeaturesPropertyInfo()); - map.addProperty(requiredExtensionsPropertyInfo()); - map.addProperty(systemLanguagePropertyInfo()); + static NeverDestroyed<SVGAttributeToPropertyMap> map = createSVGTextAttributeToPropertyMap(); return map; } -bool SVGTests::hasExtension(const String& extension) const +bool SVGTests::hasExtension(const String& extension) { // We recognize XHTML and MathML, as implemented in Gecko and suggested in the SVG Tiny recommendation (http://www.w3.org/TR/SVG11/struct.html#RequiredExtensionsAttribute). #if ENABLE(MATHML) - return extension == HTMLNames::xhtmlNamespaceURI || extension == MathMLNames::mathmlNamespaceURI; -#else - return extension == HTMLNames::xhtmlNamespaceURI; + if (extension == MathMLNames::mathmlNamespaceURI) + return true; #endif + return extension == HTMLNames::xhtmlNamespaceURI; } bool SVGTests::isValid() const { for (auto& feature : m_requiredFeatures.value) { - if (feature.isEmpty() || !DOMImplementation::hasFeature(feature, String())) + if (feature.isEmpty() || !supportedSVGFeatures().contains(feature)) return false; } - for (auto& language : m_systemLanguage.value) { if (language != defaultLanguage().substring(0, 2)) return false; } - for (auto& extension : m_requiredExtensions.value) { if (!hasExtension(extension)) return false; } - return true; } -bool SVGTests::parseAttribute(const QualifiedName& name, const AtomicString& value) +void SVGTests::parseAttribute(const QualifiedName& attributeName, const AtomicString& value) { - if (name == SVGNames::requiredFeaturesAttr) { + if (attributeName == requiredFeaturesAttr) m_requiredFeatures.value.reset(value); - return true; - } - if (name == SVGNames::requiredExtensionsAttr) { + if (attributeName == requiredExtensionsAttr) m_requiredExtensions.value.reset(value); - return true; - } - if (name == SVGNames::systemLanguageAttr) { + if (attributeName == systemLanguageAttr) m_systemLanguage.value.reset(value); - return true; - } - - return false; } -bool SVGTests::isKnownAttribute(const QualifiedName& attrName) +bool SVGTests::isKnownAttribute(const QualifiedName& attributeName) { - return attrName == SVGNames::requiredFeaturesAttr - || attrName == SVGNames::requiredExtensionsAttr - || attrName == SVGNames::systemLanguageAttr; + return attributeName == requiredFeaturesAttr + || attributeName == requiredExtensionsAttr + || attributeName == systemLanguageAttr; } -bool SVGTests::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attrName) +bool SVGTests::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attributeName) { ASSERT(targetElement); - if (!isKnownAttribute(attrName)) + if (!isKnownAttribute(attributeName)) return false; - if (!targetElement->inDocument()) + if (!targetElement->isConnected()) return true; - - targetElement->setNeedsStyleRecalc(ReconstructRenderTree); - + targetElement->invalidateStyleAndRenderersForSubtree(); return true; } void SVGTests::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) { - supportedAttributes.add(SVGNames::requiredFeaturesAttr); - supportedAttributes.add(SVGNames::requiredExtensionsAttr); - supportedAttributes.add(SVGNames::systemLanguageAttr); + supportedAttributes.add(requiredFeaturesAttr); + supportedAttributes.add(requiredExtensionsAttr); + supportedAttributes.add(systemLanguageAttr); } -void SVGTests::synchronizeRequiredFeatures(SVGElement* contextElement) +void SVGTests::synchronizeAttribute(SVGElement& contextElement, SVGSynchronizableAnimatedProperty<SVGStringListValues>& property, const QualifiedName& attributeName) { - ASSERT(contextElement); - if (!m_requiredFeatures.shouldSynchronize) + if (!property.shouldSynchronize) return; - AtomicString value(m_requiredFeatures.value.valueAsString()); - m_requiredFeatures.synchronize(contextElement, requiredFeaturesPropertyInfo()->attributeName, value); + m_requiredFeatures.synchronize(&contextElement, attributeName, property.value.valueAsString()); } -void SVGTests::synchronizeRequiredExtensions(SVGElement* contextElement) +void SVGTests::synchronizeRequiredFeatures(SVGElement& contextElement) { - ASSERT(contextElement); - if (!m_requiredExtensions.shouldSynchronize) - return; - AtomicString value(m_requiredExtensions.value.valueAsString()); - m_requiredExtensions.synchronize(contextElement, requiredExtensionsPropertyInfo()->attributeName, value); + synchronizeAttribute(contextElement, m_requiredFeatures, requiredFeaturesAttr); } -void SVGTests::synchronizeSystemLanguage(SVGElement* contextElement) +void SVGTests::synchronizeRequiredExtensions(SVGElement& contextElement) { - ASSERT(contextElement); - if (!m_systemLanguage.shouldSynchronize) - return; - AtomicString value(m_systemLanguage.value.valueAsString()); - m_systemLanguage.synchronize(contextElement, systemLanguagePropertyInfo()->attributeName, value); + synchronizeAttribute(contextElement, m_requiredExtensions, requiredExtensionsAttr); } -SVGStringList& SVGTests::requiredFeatures() +void SVGTests::synchronizeSystemLanguage(SVGElement& contextElement) +{ + synchronizeAttribute(contextElement, m_systemLanguage, systemLanguageAttr); +} + +Ref<SVGStringList> SVGTests::requiredFeatures(SVGElement& contextElement) { m_requiredFeatures.shouldSynchronize = true; - return m_requiredFeatures.value; + return SVGStringList::create(contextElement, m_requiredFeatures.value); } -SVGStringList& SVGTests::requiredExtensions() +Ref<SVGStringList> SVGTests::requiredExtensions(SVGElement& contextElement) { m_requiredExtensions.shouldSynchronize = true; - return m_requiredExtensions.value; + return SVGStringList::create(contextElement, m_requiredExtensions.value); } -SVGStringList& SVGTests::systemLanguage() +Ref<SVGStringList> SVGTests::systemLanguage(SVGElement& contextElement) { m_systemLanguage.shouldSynchronize = true; - return m_systemLanguage.value; + return SVGStringList::create(contextElement, m_systemLanguage.value); } +bool SVGTests::hasFeatureForLegacyBindings(const String& feature, const String& version) +{ + // FIXME: This function is here only to be exposed in the Objective-C and GObject bindings for both Node and DOMImplementation. + // It's likely that we can just remove this and instead have the bindings return true unconditionally. + // This is what the DOMImplementation function now does in JavaScript as is now suggested in the DOM specification. + // The behavior implemented below is quirky, but preserves what WebKit has done for at least the last few years. + + bool hasSVG10FeaturePrefix = feature.startsWith("org.w3c.dom.svg", false) || feature.startsWith("org.w3c.svg", false); + bool hasSVG11FeaturePrefix = feature.startsWith("http://www.w3.org/tr/svg", false); + + // We don't even try to handle feature names that don't look like the SVG ones, so just return true for all of those. + if (!(hasSVG10FeaturePrefix || hasSVG11FeaturePrefix)) + return true; + + // If the version number matches the style of the feature name, then use the set to see if the feature is supported. + if (version.isEmpty() || (hasSVG10FeaturePrefix && version == "1.0") || (hasSVG11FeaturePrefix && version == "1.1")) + return supportedSVGFeatures().contains(feature); + + return false; } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGTests.h b/Source/WebCore/svg/SVGTests.h index 5394355e2..d99ac2240 100644 --- a/Source/WebCore/svg/SVGTests.h +++ b/Source/WebCore/svg/SVGTests.h @@ -18,58 +18,49 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTests_h -#define SVGTests_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyMacros.h" -#include "SVGStringList.h" +#include "SVGStringListValues.h" namespace WebCore { -class Attribute; -class QualifiedName; class SVGElement; +class SVGStringList; class SVGTests { public: - SVGStringList& requiredFeatures(); - SVGStringList& requiredExtensions(); - SVGStringList& systemLanguage(); - - bool hasExtension(const String&) const; + static bool hasExtension(const String&); bool isValid() const; - bool parseAttribute(const QualifiedName&, const AtomicString&); - bool isKnownAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&); + + static bool isKnownAttribute(const QualifiedName&); + static void addSupportedAttributes(HashSet<QualifiedName>&); + + static bool handleAttributeChange(SVGElement*, const QualifiedName&); - void addSupportedAttributes(HashSet<QualifiedName>&); - bool handleAttributeChange(SVGElement*, const QualifiedName&); + static const SVGAttributeToPropertyMap& attributeToPropertyMap(); - static SVGAttributeToPropertyMap& attributeToPropertyMap(); + WEBCORE_EXPORT static bool hasFeatureForLegacyBindings(const String& feature, const String& version); protected: SVGTests(); - void synchronizeRequiredFeatures(SVGElement* contextElement); - void synchronizeRequiredExtensions(SVGElement* contextElement); - void synchronizeSystemLanguage(SVGElement* contextElement); + Ref<SVGStringList> requiredFeatures(SVGElement&); + Ref<SVGStringList> requiredExtensions(SVGElement&); + Ref<SVGStringList> systemLanguage(SVGElement&); -private: - // Custom 'requiredFeatures' property - static const SVGPropertyInfo* requiredFeaturesPropertyInfo(); - SVGSynchronizableAnimatedProperty<SVGStringList> m_requiredFeatures; + void synchronizeRequiredFeatures(SVGElement&); + void synchronizeRequiredExtensions(SVGElement&); + void synchronizeSystemLanguage(SVGElement&); - // Custom 'requiredExtensions' property - static const SVGPropertyInfo* requiredExtensionsPropertyInfo(); - SVGSynchronizableAnimatedProperty<SVGStringList> m_requiredExtensions; +private: + void synchronizeAttribute(SVGElement& contextElement, SVGSynchronizableAnimatedProperty<SVGStringListValues>&, const QualifiedName& attributeName); - // Custom 'systemLanguage' property - static const SVGPropertyInfo* systemLanguagePropertyInfo(); - SVGSynchronizableAnimatedProperty<SVGStringList> m_systemLanguage; + SVGSynchronizableAnimatedProperty<SVGStringListValues> m_requiredFeatures; + SVGSynchronizableAnimatedProperty<SVGStringListValues> m_requiredExtensions; + SVGSynchronizableAnimatedProperty<SVGStringListValues> m_systemLanguage; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGTests_h diff --git a/Source/WebCore/svg/SVGTests.idl b/Source/WebCore/svg/SVGTests.idl index e7301f499..a44f073e9 100644 --- a/Source/WebCore/svg/SVGTests.idl +++ b/Source/WebCore/svg/SVGTests.idl @@ -26,14 +26,12 @@ [ NoInterfaceObject, - Conditional=SVG, - ObjCProtocol, SuppressToJSObject, ] interface SVGTests { - readonly attribute SVGStringList requiredFeatures; - readonly attribute SVGStringList requiredExtensions; - readonly attribute SVGStringList systemLanguage; + [NewObject] readonly attribute SVGStringList requiredFeatures; + [NewObject] readonly attribute SVGStringList requiredExtensions; + [NewObject] readonly attribute SVGStringList systemLanguage; - boolean hasExtension([Default=Undefined] optional DOMString extension); + // FIXME: Using "undefined" as default parameter value is wrong. + boolean hasExtension(optional DOMString extension = "undefined"); }; - diff --git a/Source/WebCore/svg/SVGTextContentElement.cpp b/Source/WebCore/svg/SVGTextContentElement.cpp index ef9920eff..12f1dcbf3 100644 --- a/Source/WebCore/svg/SVGTextContentElement.cpp +++ b/Source/WebCore/svg/SVGTextContentElement.cpp @@ -19,8 +19,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTextContentElement.h" #include "CSSPropertyNames.h" @@ -31,17 +29,19 @@ #include "RenderSVGResource.h" #include "RenderSVGText.h" #include "SVGDocumentExtensions.h" -#include "SVGElementInstance.h" #include "SVGNames.h" +#include "SVGPoint.h" +#include "SVGRect.h" #include "SVGTextQuery.h" #include "XMLNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { // Define custom animated property 'textLength'. const SVGPropertyInfo* SVGTextContentElement::textLengthPropertyInfo() { - static const SVGPropertyInfo* s_propertyInfo = 0; + static const SVGPropertyInfo* s_propertyInfo = nullptr; if (!s_propertyInfo) { s_propertyInfo = new SVGPropertyInfo(AnimatedLength, PropertyIsReadWrite, @@ -76,30 +76,29 @@ SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Docum void SVGTextContentElement::synchronizeTextLength(SVGElement* contextElement) { ASSERT(contextElement); - SVGTextContentElement* ownerType = toSVGTextContentElement(contextElement); - if (!ownerType->m_textLength.shouldSynchronize) + SVGTextContentElement& ownerType = downcast<SVGTextContentElement>(*contextElement); + if (!ownerType.m_textLength.shouldSynchronize) return; - AtomicString value(SVGPropertyTraits<SVGLength>::toString(ownerType->m_specifiedTextLength)); - ownerType->m_textLength.synchronize(ownerType, textLengthPropertyInfo()->attributeName, value); + AtomicString value(SVGPropertyTraits<SVGLengthValue>::toString(ownerType.m_specifiedTextLength)); + ownerType.m_textLength.synchronize(&ownerType, textLengthPropertyInfo()->attributeName, value); } -PassRefPtr<SVGAnimatedProperty> SVGTextContentElement::lookupOrCreateTextLengthWrapper(SVGElement* contextElement) +Ref<SVGAnimatedProperty> SVGTextContentElement::lookupOrCreateTextLengthWrapper(SVGElement* contextElement) { ASSERT(contextElement); - SVGTextContentElement* ownerType = toSVGTextContentElement(contextElement); - return SVGAnimatedProperty::lookupOrCreateWrapper<SVGTextContentElement, SVGAnimatedLength, SVGLength> - (ownerType, textLengthPropertyInfo(), ownerType->m_textLength.value); + SVGTextContentElement& ownerType = downcast<SVGTextContentElement>(*contextElement); + return SVGAnimatedProperty::lookupOrCreateWrapper<SVGTextContentElement, SVGAnimatedLength, SVGLengthValue> + (&ownerType, textLengthPropertyInfo(), ownerType.m_textLength.value); } -PassRefPtr<SVGAnimatedLength> SVGTextContentElement::textLengthAnimated() +Ref<SVGAnimatedLength> SVGTextContentElement::textLengthAnimated() { - DEFINE_STATIC_LOCAL(SVGLength, defaultTextLength, (LengthModeOther)); + static NeverDestroyed<SVGLengthValue> defaultTextLength(LengthModeOther); if (m_specifiedTextLength == defaultTextLength) - m_textLength.value.newValueSpecifiedUnits(LengthTypeNumber, getComputedTextLength(), ASSERT_NO_EXCEPTION); + m_textLength.value.newValueSpecifiedUnits(LengthTypeNumber, getComputedTextLength()); m_textLength.shouldSynchronize = true; - return static_pointer_cast<SVGAnimatedLength>(lookupOrCreateTextLengthWrapper(this)); - + return static_reference_cast<SVGAnimatedLength>(lookupOrCreateTextLengthWrapper(this)); } unsigned SVGTextContentElement::getNumberOfChars() @@ -114,83 +113,61 @@ float SVGTextContentElement::getComputedTextLength() return SVGTextQuery(renderer()).textLength(); } -float SVGTextContentElement::getSubStringLength(unsigned charnum, unsigned nchars, ExceptionCode& ec) +ExceptionOr<float> SVGTextContentElement::getSubStringLength(unsigned charnum, unsigned nchars) { - document().updateLayoutIgnorePendingStylesheets(); - unsigned numberOfChars = getNumberOfChars(); - if (charnum >= numberOfChars) { - ec = INDEX_SIZE_ERR; - return 0.0f; - } + if (charnum >= numberOfChars) + return Exception { INDEX_SIZE_ERR }; + nchars = std::min(nchars, numberOfChars - charnum); return SVGTextQuery(renderer()).subStringLength(charnum, nchars); } -SVGPoint SVGTextContentElement::getStartPositionOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<Ref<SVGPoint>> SVGTextContentElement::getStartPositionOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return SVGPoint(); - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; - return SVGTextQuery(renderer()).startPositionOfCharacter(charnum); + return SVGPoint::create(SVGTextQuery(renderer()).startPositionOfCharacter(charnum)); } -SVGPoint SVGTextContentElement::getEndPositionOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<Ref<SVGPoint>> SVGTextContentElement::getEndPositionOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return SVGPoint(); - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; - return SVGTextQuery(renderer()).endPositionOfCharacter(charnum); + return SVGPoint::create(SVGTextQuery(renderer()).endPositionOfCharacter(charnum)); } -FloatRect SVGTextContentElement::getExtentOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<Ref<SVGRect>> SVGTextContentElement::getExtentOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return FloatRect(); - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; - return SVGTextQuery(renderer()).extentOfCharacter(charnum); + return SVGRect::create(SVGTextQuery(renderer()).extentOfCharacter(charnum)); } -float SVGTextContentElement::getRotationOfChar(unsigned charnum, ExceptionCode& ec) +ExceptionOr<float> SVGTextContentElement::getRotationOfChar(unsigned charnum) { - document().updateLayoutIgnorePendingStylesheets(); - - if (charnum > getNumberOfChars()) { - ec = INDEX_SIZE_ERR; - return 0.0f; - } + if (charnum > getNumberOfChars()) + return Exception { INDEX_SIZE_ERR }; return SVGTextQuery(renderer()).rotationOfCharacter(charnum); } -int SVGTextContentElement::getCharNumAtPosition(const SVGPoint& point) +int SVGTextContentElement::getCharNumAtPosition(SVGPoint& point) { document().updateLayoutIgnorePendingStylesheets(); - return SVGTextQuery(renderer()).characterNumberAtPosition(point); + return SVGTextQuery(renderer()).characterNumberAtPosition(point.propertyReference()); } -void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, ExceptionCode& ec) +ExceptionOr<void> SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars) { unsigned numberOfChars = getNumberOfChars(); - if (charnum >= numberOfChars) { - ec = INDEX_SIZE_ERR; - return; - } + if (charnum >= numberOfChars) + return Exception { INDEX_SIZE_ERR }; - if (nchars > numberOfChars - charnum) - nchars = numberOfChars - charnum; + nchars = std::min(nchars, numberOfChars - charnum); ASSERT(document().frame()); @@ -207,18 +184,20 @@ void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, E end = end.next(); selection.setSelection(VisibleSelection(start, end)); + + return { }; } bool SVGTextContentElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGLangSpace::addSupportedAttributes(supportedAttributes); SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::lengthAdjustAttr); - supportedAttributes.add(SVGNames::textLengthAttr); + supportedAttributes.get().add(SVGNames::lengthAdjustAttr); + supportedAttributes.get().add(SVGNames::textLengthAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } bool SVGTextContentElement::isPresentationAttribute(const QualifiedName& name) const @@ -230,36 +209,32 @@ bool SVGTextContentElement::isPresentationAttribute(const QualifiedName& name) c void SVGTextContentElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style) { - if (!isSupportedAttribute(name)) - SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style); - else if (name.matches(XMLNames::spaceAttr)) { - DEFINE_STATIC_LOCAL(const AtomicString, preserveString, ("preserve", AtomicString::ConstructFromLiteral)); - - if (value == preserveString) + if (name.matches(XMLNames::spaceAttr)) { + if (value == "preserve") addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValuePre); else addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValueNowrap); + return; } + + SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style); } void SVGTextContentElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::lengthAdjustAttr) { - SVGLengthAdjustType propertyValue = SVGPropertyTraits<SVGLengthAdjustType>::fromString(value); + if (name == SVGNames::lengthAdjustAttr) { + auto propertyValue = SVGPropertyTraits<SVGLengthAdjustType>::fromString(value); if (propertyValue > 0) setLengthAdjustBaseValue(propertyValue); - } else if (name == SVGNames::textLengthAttr) { - m_textLength.value = SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths); - } else if (SVGExternalResourcesRequired::parseAttribute(name, value)) { - } else if (SVGLangSpace::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + } else if (name == SVGNames::textLengthAttr) + m_textLength.value = SVGLengthValue::construct(LengthModeOther, value, parseError, ForbidNegativeLengths); reportAttributeParsingError(parseError, name, value); + + SVGGraphicsElement::parseAttribute(name, value); + SVGExternalResourcesRequired::parseAttribute(name, value); } void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName) @@ -269,13 +244,13 @@ void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (attrName == SVGNames::textLengthAttr) m_specifiedTextLength = m_textLength.value; - if (auto renderer = this->renderer()) + if (auto renderer = this->renderer()) { + InstanceInvalidationGuard guard(*this); RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } } bool SVGTextContentElement::selfHasRelativeLengths() const @@ -289,20 +264,18 @@ bool SVGTextContentElement::selfHasRelativeLengths() const SVGTextContentElement* SVGTextContentElement::elementFromRenderer(RenderObject* renderer) { if (!renderer) - return 0; + return nullptr; if (!renderer->isSVGText() && !renderer->isSVGInline()) - return 0; + return nullptr; - SVGElement* element = toSVGElement(renderer->node()); + SVGElement* element = downcast<SVGElement>(renderer->node()); ASSERT(element); - if (!element->isTextContent()) - return 0; + if (!is<SVGTextContentElement>(*element)) + return nullptr; - return toSVGTextContentElement(element); + return downcast<SVGTextContentElement>(element); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTextContentElement.h b/Source/WebCore/svg/SVGTextContentElement.h index af3ddf363..7d2cb1b26 100644 --- a/Source/WebCore/svg/SVGTextContentElement.h +++ b/Source/WebCore/svg/SVGTextContentElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTextContentElement_h -#define SVGTextContentElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedEnumeration.h" #include "SVGAnimatedLength.h" @@ -36,8 +34,7 @@ enum SVGLengthAdjustType { SVGLengthAdjustSpacingAndGlyphs }; -template<> -struct SVGPropertyTraits<SVGLengthAdjustType> { +template<> struct SVGPropertyTraits<SVGLengthAdjustType> { static unsigned highestEnumValue() { return SVGLengthAdjustSpacingAndGlyphs; } static String toString(SVGLengthAdjustType type) @@ -46,9 +43,9 @@ struct SVGPropertyTraits<SVGLengthAdjustType> { case SVGLengthAdjustUnknown: return emptyString(); case SVGLengthAdjustSpacing: - return "spacing"; + return ASCIILiteral("spacing"); case SVGLengthAdjustSpacingAndGlyphs: - return "spacingAndGlyphs"; + return ASCIILiteral("spacingAndGlyphs"); } ASSERT_NOT_REACHED(); @@ -67,7 +64,6 @@ struct SVGPropertyTraits<SVGLengthAdjustType> { class SVGTextContentElement : public SVGGraphicsElement, public SVGExternalResourcesRequired { public: - // Forward declare enumerations in the W3C naming scheme, for IDL generation. enum { LENGTHADJUST_UNKNOWN = SVGLengthAdjustUnknown, LENGTHADJUST_SPACING = SVGLengthAdjustSpacing, @@ -76,56 +72,54 @@ public: unsigned getNumberOfChars(); float getComputedTextLength(); - float getSubStringLength(unsigned charnum, unsigned nchars, ExceptionCode&); - SVGPoint getStartPositionOfChar(unsigned charnum, ExceptionCode&); - SVGPoint getEndPositionOfChar(unsigned charnum, ExceptionCode&); - FloatRect getExtentOfChar(unsigned charnum, ExceptionCode&); - float getRotationOfChar(unsigned charnum, ExceptionCode&); - int getCharNumAtPosition(const SVGPoint&); - void selectSubString(unsigned charnum, unsigned nchars, ExceptionCode&); + ExceptionOr<float> getSubStringLength(unsigned charnum, unsigned nchars); + ExceptionOr<Ref<SVGPoint>> getStartPositionOfChar(unsigned charnum); + ExceptionOr<Ref<SVGPoint>> getEndPositionOfChar(unsigned charnum); + ExceptionOr<Ref<SVGRect>> getExtentOfChar(unsigned charnum); + ExceptionOr<float> getRotationOfChar(unsigned charnum); + int getCharNumAtPosition(SVGPoint&); + ExceptionOr<void> selectSubString(unsigned charnum, unsigned nchars); static SVGTextContentElement* elementFromRenderer(RenderObject*); // textLength is not declared using the standard DECLARE_ANIMATED_LENGTH macro // as its getter needs special handling (return getComputedTextLength(), instead of m_textLength). - SVGLength& specifiedTextLength() { return m_specifiedTextLength; } - PassRefPtr<SVGAnimatedLength> textLengthAnimated(); + SVGLengthValue& specifiedTextLength() { return m_specifiedTextLength; } + Ref<SVGAnimatedLength> textLengthAnimated(); static const SVGPropertyInfo* textLengthPropertyInfo(); protected: SVGTextContentElement(const QualifiedName&, Document&); - virtual bool isValid() const override { return SVGTests::isValid(); } + bool isValid() const override { return SVGTests::isValid(); } - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual bool isPresentationAttribute(const QualifiedName&) const override; - virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + bool isPresentationAttribute(const QualifiedName&) const override; + void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override; + void svgAttributeChanged(const QualifiedName&) override; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const override; private: - virtual bool isTextContent() const override final { return true; } + bool isTextContent() const final { return true; } + + static bool isSupportedAttribute(const QualifiedName&); // Custom 'textLength' property static void synchronizeTextLength(SVGElement* contextElement); - static PassRefPtr<SVGAnimatedProperty> lookupOrCreateTextLengthWrapper(SVGElement* contextElement); - mutable SVGSynchronizableAnimatedProperty<SVGLength> m_textLength; - SVGLength m_specifiedTextLength; + static Ref<SVGAnimatedProperty> lookupOrCreateTextLengthWrapper(SVGElement* contextElement); + mutable SVGSynchronizableAnimatedProperty<SVGLengthValue> m_textLength; + SVGLengthValue m_specifiedTextLength; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextContentElement) DECLARE_ANIMATED_ENUMERATION(LengthAdjust, lengthAdjust, SVGLengthAdjustType) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) END_DECLARE_ANIMATED_PROPERTIES }; -void isSVGTextContentElement(const SVGTextContentElement&); // Catch unnecessary runtime check of type known at compile time. -inline bool isSVGTextContentElement(const SVGElement& element) { return element.isTextContent(); } -inline bool isSVGTextContentElement(const Node& node) { return node.isSVGElement() && toSVGElement(node).isTextContent(); } -NODE_TYPE_CASTS(SVGTextContentElement) - } // namespace WebCore -#endif // ENABLE(SVG) -#endif +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGTextContentElement) + static bool isType(const WebCore::SVGElement& element) { return element.isTextContent(); } + static bool isType(const WebCore::Node& node) { return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/SVGTextContentElement.idl b/Source/WebCore/svg/SVGTextContentElement.idl index 63f3c6037..629e8ab13 100644 --- a/Source/WebCore/svg/SVGTextContentElement.idl +++ b/Source/WebCore/svg/SVGTextContentElement.idl @@ -23,28 +23,24 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGTextContentElement : SVGGraphicsElement { +interface SVGTextContentElement : SVGGraphicsElement { // lengthAdjust Types - const unsigned short LENGTHADJUST_UNKNOWN = 0; - const unsigned short LENGTHADJUST_SPACING = 1; + const unsigned short LENGTHADJUST_UNKNOWN = 0; + const unsigned short LENGTHADJUST_SPACING = 1; const unsigned short LENGTHADJUST_SPACINGANDGLYPHS = 2; - readonly attribute SVGAnimatedLength textLength; + readonly attribute SVGAnimatedLength textLength; readonly attribute SVGAnimatedEnumeration lengthAdjust; long getNumberOfChars(); - float getComputedTextLength(); - [RaisesException] float getSubStringLength([Default=Undefined,IsIndex] optional unsigned long offset, - [Default=Undefined,IsIndex] optional unsigned long length); - [RaisesException] SVGPoint getStartPositionOfChar([Default=Undefined,IsIndex] optional unsigned long offset); - [RaisesException] SVGPoint getEndPositionOfChar([Default=Undefined,IsIndex] optional unsigned long offset); - [RaisesException] SVGRect getExtentOfChar([Default=Undefined,IsIndex] optional unsigned long offset); - [RaisesException] float getRotationOfChar([Default=Undefined,IsIndex] optional unsigned long offset); - long getCharNumAtPosition([Default=Undefined] optional SVGPoint point); - [RaisesException] void selectSubString([Default=Undefined,IsIndex] optional unsigned long offset, - [Default=Undefined,IsIndex] optional unsigned long length); + unrestricted float getComputedTextLength(); + [MayThrowException] unrestricted float getSubStringLength(optional unsigned long offset = 0, optional unsigned long length = 0); + [MayThrowException, NewObject] SVGPoint getStartPositionOfChar(optional unsigned long offset = 0); + [MayThrowException, NewObject] SVGPoint getEndPositionOfChar(optional unsigned long offset = 0); + [MayThrowException, NewObject] SVGRect getExtentOfChar(optional unsigned long offset = 0); + [MayThrowException] unrestricted float getRotationOfChar(optional unsigned long offset = 0); + long getCharNumAtPosition(SVGPoint point); + [MayThrowException] void selectSubString(optional unsigned long offset = 0, optional unsigned long length = 0); }; // FIXME: SVGTextContentElement is not supposed to implement SVGExternalResourcesRequired. diff --git a/Source/WebCore/svg/SVGTextElement.cpp b/Source/WebCore/svg/SVGTextElement.cpp index bdd931f4b..c55cbc46b 100644 --- a/Source/WebCore/svg/SVGTextElement.cpp +++ b/Source/WebCore/svg/SVGTextElement.cpp @@ -19,14 +19,10 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTextElement.h" -#include "Attribute.h" #include "RenderSVGResource.h" #include "RenderSVGText.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "SVGRenderStyle.h" #include "SVGTSpanElement.h" @@ -39,9 +35,9 @@ inline SVGTextElement::SVGTextElement(const QualifiedName& tagName, Document& do ASSERT(hasTagName(SVGNames::textTag)); } -PassRefPtr<SVGTextElement> SVGTextElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGTextElement> SVGTextElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGTextElement(tagName, document)); + return adoptRef(*new SVGTextElement(tagName, document)); } // We override SVGGraphics::animatedLocalTransform() so that the transform-origin @@ -49,14 +45,14 @@ PassRefPtr<SVGTextElement> SVGTextElement::create(const QualifiedName& tagName, AffineTransform SVGTextElement::animatedLocalTransform() const { AffineTransform matrix; - RenderStyle* style = renderer() ? &renderer()->style() : nullptr; + auto* style = renderer() ? &renderer()->style() : nullptr; // if CSS property was set, use that, otherwise fallback to attribute (if set) if (style && style->hasTransform()) { TransformationMatrix t; // For now, the transform-origin is not taken into account // Also, any percentage values will not be taken into account - style->applyTransform(t, IntSize(0, 0), RenderStyle::ExcludeTransformOrigin); + style->applyTransform(t, FloatRect(0, 0, 0, 0), RenderStyle::ExcludeTransformOrigin); // Flatten any 3D transform matrix = t.toAffineTransform(); } else @@ -68,9 +64,9 @@ AffineTransform SVGTextElement::animatedLocalTransform() const return matrix; } -RenderPtr<RenderElement> SVGTextElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGTextElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGText>(*this, std::move(style)); + return createRenderer<RenderSVGText>(*this, WTFMove(style)); } bool SVGTextElement::childShouldCreateRenderer(const Node& child) const @@ -89,5 +85,3 @@ bool SVGTextElement::childShouldCreateRenderer(const Node& child) const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTextElement.h b/Source/WebCore/svg/SVGTextElement.h index 48519bf62..a375c52db 100644 --- a/Source/WebCore/svg/SVGTextElement.h +++ b/Source/WebCore/svg/SVGTextElement.h @@ -18,32 +18,23 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTextElement_h -#define SVGTextElement_h +#pragma once -#if ENABLE(SVG) #include "SVGTextPositioningElement.h" namespace WebCore { class SVGTextElement final : public SVGTextPositioningElement { public: - static PassRefPtr<SVGTextElement> create(const QualifiedName&, Document&); + static Ref<SVGTextElement> create(const QualifiedName&, Document&); - virtual AffineTransform animatedLocalTransform() const override; + AffineTransform animatedLocalTransform() const override; private: SVGTextElement(const QualifiedName&, Document&); - virtual bool supportsFocus() const override { return true; } - - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool childShouldCreateRenderer(const Node&) const override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool childShouldCreateRenderer(const Node&) const override; }; -NODE_TYPE_CASTS(SVGTextElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGTextElement.idl b/Source/WebCore/svg/SVGTextElement.idl index d4caea7a1..ce82c08f6 100644 --- a/Source/WebCore/svg/SVGTextElement.idl +++ b/Source/WebCore/svg/SVGTextElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGTextElement : SVGTextPositioningElement { +interface SVGTextElement : SVGTextPositioningElement { }; diff --git a/Source/WebCore/svg/SVGTextPathElement.cpp b/Source/WebCore/svg/SVGTextPathElement.cpp index 4138366ad..3cd2b8e7c 100644 --- a/Source/WebCore/svg/SVGTextPathElement.cpp +++ b/Source/WebCore/svg/SVGTextPathElement.cpp @@ -19,16 +19,13 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTextPathElement.h" -#include "Attribute.h" #include "RenderSVGResource.h" #include "RenderSVGTextPath.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "XLinkNames.h" +#include <wtf/NeverDestroyed.h> namespace WebCore { @@ -56,9 +53,9 @@ inline SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Docu registerAnimatedPropertiesForSVGTextPathElement(); } -PassRefPtr<SVGTextPathElement> SVGTextPathElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGTextPathElement> SVGTextPathElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGTextPathElement(tagName, document)); + return adoptRef(*new SVGTextPathElement(tagName, document)); } SVGTextPathElement::~SVGTextPathElement() @@ -68,29 +65,27 @@ SVGTextPathElement::~SVGTextPathElement() void SVGTextPathElement::clearResourceReferences() { - document().accessSVGExtensions()->removeAllTargetReferencesForElement(this); + document().accessSVGExtensions().removeAllTargetReferencesForElement(this); } bool SVGTextPathElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { SVGURIReference::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::startOffsetAttr); - supportedAttributes.add(SVGNames::methodAttr); - supportedAttributes.add(SVGNames::spacingAttr); + supportedAttributes.get().add(SVGNames::startOffsetAttr); + supportedAttributes.get().add(SVGNames::methodAttr); + supportedAttributes.get().add(SVGNames::spacingAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGTextContentElement::parseAttribute(name, value); - else if (name == SVGNames::startOffsetAttr) - setStartOffsetBaseValue(SVGLength::construct(LengthModeOther, value, parseError)); + if (name == SVGNames::startOffsetAttr) + setStartOffsetBaseValue(SVGLengthValue::construct(LengthModeOther, value, parseError)); else if (name == SVGNames::methodAttr) { SVGTextPathMethodType propertyValue = SVGPropertyTraits<SVGTextPathMethodType>::fromString(value); if (propertyValue > 0) @@ -99,11 +94,12 @@ void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicS SVGTextPathSpacingType propertyValue = SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value); if (propertyValue > 0) setSpacingBaseValue(propertyValue); - } else if (SVGURIReference::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + } reportAttributeParsingError(parseError, name, value); + + SVGTextContentElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); } void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName) @@ -113,7 +109,7 @@ void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName) return; } - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); if (SVGURIReference::isKnownAttribute(attrName)) { buildPendingResource(); @@ -127,9 +123,9 @@ void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); } -RenderPtr<RenderElement> SVGTextPathElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGTextPathElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGTextPath>(*this, std::move(style)); + return createRenderer<RenderSVGTextPath>(*this, WTFMove(style)); } bool SVGTextPathElement::childShouldCreateRenderer(const Node& child) const @@ -156,38 +152,42 @@ bool SVGTextPathElement::rendererIsNeeded(const RenderStyle& style) void SVGTextPathElement::buildPendingResource() { clearResourceReferences(); - if (!inDocument()) + if (!isConnected()) return; String id; Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id); if (!target) { // Do not register as pending if we are already pending this resource. - if (document().accessSVGExtensions()->isPendingResource(this, id)) + if (document().accessSVGExtensions().isPendingResource(this, id)) return; if (!id.isEmpty()) { - document().accessSVGExtensions()->addPendingResource(id, this); + document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); } } else if (target->hasTagName(SVGNames::pathTag)) { // Register us with the target in the dependencies map. Any change of hrefElement // that leads to relayout/repainting now informs us, so we can react to it. - document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target)); + document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target)); } } Node::InsertionNotificationRequest SVGTextPathElement::insertedInto(ContainerNode& rootParent) { SVGTextContentElement::insertedInto(rootParent); + return InsertionShouldCallFinishedInsertingSubtree; +} + +void SVGTextPathElement::finishedInsertingSubtree() +{ buildPendingResource(); - return InsertionDone; } void SVGTextPathElement::removedFrom(ContainerNode& rootParent) { SVGTextContentElement::removedFrom(rootParent); - if (rootParent.inDocument()) + if (rootParent.isConnected()) clearResourceReferences(); } @@ -198,5 +198,3 @@ bool SVGTextPathElement::selfHasRelativeLengths() const } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTextPathElement.h b/Source/WebCore/svg/SVGTextPathElement.h index db65b58ed..d16204e13 100644 --- a/Source/WebCore/svg/SVGTextPathElement.h +++ b/Source/WebCore/svg/SVGTextPathElement.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTextPathElement_h -#define SVGTextPathElement_h +#pragma once -#if ENABLE(SVG) #include "SVGNames.h" #include "SVGTextContentElement.h" #include "SVGURIReference.h" @@ -49,9 +47,9 @@ struct SVGPropertyTraits<SVGTextPathMethodType> { case SVGTextPathMethodUnknown: return emptyString(); case SVGTextPathMethodAlign: - return "align"; + return ASCIILiteral("align"); case SVGTextPathMethodStretch: - return "stretch"; + return ASCIILiteral("stretch"); } ASSERT_NOT_REACHED(); @@ -78,9 +76,9 @@ struct SVGPropertyTraits<SVGTextPathSpacingType> { case SVGTextPathSpacingUnknown: return emptyString(); case SVGTextPathSpacingAuto: - return "auto"; + return ASCIILiteral("auto"); case SVGTextPathSpacingExact: - return "exact"; + return ASCIILiteral("exact"); } ASSERT_NOT_REACHED(); @@ -110,8 +108,11 @@ public: TEXTPATH_SPACINGTYPE_EXACT = SVGTextPathSpacingExact }; - static PassRefPtr<SVGTextPathElement> create(const QualifiedName&, Document&); - + static Ref<SVGTextPathElement> create(const QualifiedName&, Document&); + +protected: + void finishedInsertingSubtree() override; + private: SVGTextPathElement(const QualifiedName&, Document&); @@ -119,31 +120,26 @@ private: void clearResourceReferences(); - virtual void buildPendingResource() override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + void buildPendingResource() override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + static bool isSupportedAttribute(const QualifiedName&); + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual bool childShouldCreateRenderer(const Node&) const override; - virtual bool rendererIsNeeded(const RenderStyle&) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool childShouldCreateRenderer(const Node&) const override; + bool rendererIsNeeded(const RenderStyle&) override; - virtual bool selfHasRelativeLengths() const override; + bool selfHasRelativeLengths() const override; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextPathElement) DECLARE_ANIMATED_LENGTH(StartOffset, startOffset) DECLARE_ANIMATED_ENUMERATION(Method, method, SVGTextPathMethodType) DECLARE_ANIMATED_ENUMERATION(Spacing, spacing, SVGTextPathSpacingType) - DECLARE_ANIMATED_STRING(Href, href) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) END_DECLARE_ANIMATED_PROPERTIES }; -NODE_TYPE_CASTS(SVGTextPathElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGTextPathElement.idl b/Source/WebCore/svg/SVGTextPathElement.idl index b0e02e2b4..097cd93b1 100644 --- a/Source/WebCore/svg/SVGTextPathElement.idl +++ b/Source/WebCore/svg/SVGTextPathElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGTextPathElement : SVGTextContentElement { +interface SVGTextPathElement : SVGTextContentElement { // textPath Method Types const unsigned short TEXTPATH_METHODTYPE_UNKNOWN = 0; const unsigned short TEXTPATH_METHODTYPE_ALIGN = 1; diff --git a/Source/WebCore/svg/SVGTextPositioningElement.cpp b/Source/WebCore/svg/SVGTextPositioningElement.cpp index 82e7063c5..c3678b4ee 100644 --- a/Source/WebCore/svg/SVGTextPositioningElement.cpp +++ b/Source/WebCore/svg/SVGTextPositioningElement.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> + * Copyright (C) 2014 Adobe Systems Incorporated. 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 @@ -19,17 +20,18 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTextPositioningElement.h" -#include "Attribute.h" +#include "RenderSVGInline.h" #include "RenderSVGResource.h" #include "RenderSVGText.h" -#include "SVGElementInstance.h" -#include "SVGLengthList.h" +#include "SVGAltGlyphElement.h" +#include "SVGLengthListValues.h" #include "SVGNames.h" -#include "SVGNumberList.h" +#include "SVGNumberListValues.h" +#include "SVGTRefElement.h" +#include "SVGTSpanElement.h" +#include "SVGTextElement.h" namespace WebCore { @@ -55,28 +57,10 @@ SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagNam registerAnimatedPropertiesForSVGTextPositioningElement(); } -bool SVGTextPositioningElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::dxAttr); - supportedAttributes.add(SVGNames::dyAttr); - supportedAttributes.add(SVGNames::rotateAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); -} - void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGTextContentElement::parseAttribute(name, value); - return; - } - if (name == SVGNames::xAttr) { - SVGLengthList newList; + SVGLengthListValues newList; newList.parse(value, LengthModeWidth); detachAnimatedXListWrappers(newList.size()); setXBaseValue(newList); @@ -84,7 +68,7 @@ void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const } if (name == SVGNames::yAttr) { - SVGLengthList newList; + SVGLengthListValues newList; newList.parse(value, LengthModeHeight); detachAnimatedYListWrappers(newList.size()); setYBaseValue(newList); @@ -92,7 +76,7 @@ void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const } if (name == SVGNames::dxAttr) { - SVGLengthList newList; + SVGLengthListValues newList; newList.parse(value, LengthModeWidth); detachAnimatedDxListWrappers(newList.size()); setDxBaseValue(newList); @@ -100,7 +84,7 @@ void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const } if (name == SVGNames::dyAttr) { - SVGLengthList newList; + SVGLengthListValues newList; newList.parse(value, LengthModeHeight); detachAnimatedDyListWrappers(newList.size()); setDyBaseValue(newList); @@ -108,70 +92,68 @@ void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const } if (name == SVGNames::rotateAttr) { - SVGNumberList newList; + SVGNumberListValues newList; newList.parse(value); detachAnimatedRotateListWrappers(newList.size()); setRotateBaseValue(newList); return; } - ASSERT_NOT_REACHED(); + SVGTextContentElement::parseAttribute(name, value); } -void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName) +void SVGTextPositioningElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style) { - if (!isSupportedAttribute(attrName)) { - SVGTextContentElement::svgAttributeChanged(attrName); + if (name == SVGNames::xAttr || name == SVGNames::yAttr) return; - } + SVGTextContentElement::collectStyleForPresentationAttribute(name, value, style); +} - SVGElementInstance::InvalidationGuard invalidationGuard(this); +bool SVGTextPositioningElement::isPresentationAttribute(const QualifiedName& name) const +{ + if (name == SVGNames::xAttr || name == SVGNames::yAttr) + return false; + return SVGTextContentElement::isPresentationAttribute(name); +} - bool updateRelativeLengths = attrName == SVGNames::xAttr - || attrName == SVGNames::yAttr - || attrName == SVGNames::dxAttr - || attrName == SVGNames::dyAttr; +void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName) +{ + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr || attrName == SVGNames::rotateAttr) { + InstanceInvalidationGuard guard(*this); - if (updateRelativeLengths) - updateRelativeLengthsInformation(); + if (attrName != SVGNames::rotateAttr) + updateRelativeLengthsInformation(); - auto renderer = this->renderer(); - if (!renderer) - return; + if (auto renderer = this->renderer()) { + if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*renderer)) + textAncestor->setNeedsPositioningValuesUpdate(); + RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); + } - if (updateRelativeLengths || attrName == SVGNames::rotateAttr) { - if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(renderer)) - textRenderer->setNeedsPositioningValuesUpdate(); - RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } - ASSERT_NOT_REACHED(); + SVGTextContentElement::svgAttributeChanged(attrName); } -SVGTextPositioningElement* SVGTextPositioningElement::elementFromRenderer(RenderObject* renderer) +SVGTextPositioningElement* SVGTextPositioningElement::elementFromRenderer(RenderBoxModelObject& renderer) { - if (!renderer) - return 0; + if (!is<RenderSVGText>(renderer) && !is<RenderSVGInline>(renderer)) + return nullptr; - if (!renderer->isSVGText() && !renderer->isSVGInline()) - return 0; + ASSERT(renderer.element()); + SVGElement& element = downcast<SVGElement>(*renderer.element()); - Node* node = renderer->node(); - ASSERT(node); - ASSERT(node->isSVGElement()); - - if (!node->hasTagName(SVGNames::textTag) - && !node->hasTagName(SVGNames::tspanTag) + if (!is<SVGTextElement>(element) + && !is<SVGTSpanElement>(element) #if ENABLE(SVG_FONTS) - && !node->hasTagName(SVGNames::altGlyphTag) + && !is<SVGAltGlyphElement>(element) #endif - && !node->hasTagName(SVGNames::trefTag)) - return 0; + && !is<SVGTRefElement>(element)) + return nullptr; - return static_cast<SVGTextPositioningElement*>(node); + // FIXME: This should use downcast<>(). + return &static_cast<SVGTextPositioningElement&>(element); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTextPositioningElement.h b/Source/WebCore/svg/SVGTextPositioningElement.h index 02c59c60b..7d9d967cc 100644 --- a/Source/WebCore/svg/SVGTextPositioningElement.h +++ b/Source/WebCore/svg/SVGTextPositioningElement.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTextPositioningElement_h -#define SVGTextPositioningElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedLengthList.h" #include "SVGAnimatedNumberList.h" #include "SVGTextContentElement.h" @@ -30,14 +28,17 @@ namespace WebCore { class SVGTextPositioningElement : public SVGTextContentElement { public: - static SVGTextPositioningElement* elementFromRenderer(RenderObject*); + static SVGTextPositioningElement* elementFromRenderer(RenderBoxModelObject&); protected: SVGTextPositioningElement(const QualifiedName&, Document&); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + +private: + bool isPresentationAttribute(const QualifiedName&) const final; + void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final; BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextPositioningElement) DECLARE_ANIMATED_LENGTH_LIST(X, x) @@ -49,6 +50,3 @@ protected: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGTextPositioningElement.idl b/Source/WebCore/svg/SVGTextPositioningElement.idl index 7c3afdfe6..2a018641c 100644 --- a/Source/WebCore/svg/SVGTextPositioningElement.idl +++ b/Source/WebCore/svg/SVGTextPositioningElement.idl @@ -23,9 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGTextPositioningElement : SVGTextContentElement { +interface SVGTextPositioningElement : SVGTextContentElement { readonly attribute SVGAnimatedLengthList x; readonly attribute SVGAnimatedLengthList y; readonly attribute SVGAnimatedLengthList dx; diff --git a/Source/WebCore/svg/SVGTitleElement.cpp b/Source/WebCore/svg/SVGTitleElement.cpp index d805b857a..a43292cf0 100644 --- a/Source/WebCore/svg/SVGTitleElement.cpp +++ b/Source/WebCore/svg/SVGTitleElement.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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 @@ -19,11 +20,11 @@ */ #include "config.h" -#if ENABLE(SVG) #include "SVGTitleElement.h" #include "Document.h" #include "SVGNames.h" +#include "Text.h" namespace WebCore { @@ -33,38 +34,33 @@ inline SVGTitleElement::SVGTitleElement(const QualifiedName& tagName, Document& ASSERT(hasTagName(SVGNames::titleTag)); } -PassRefPtr<SVGTitleElement> SVGTitleElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGTitleElement> SVGTitleElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGTitleElement(tagName, document)); + return adoptRef(*new SVGTitleElement(tagName, document)); } Node::InsertionNotificationRequest SVGTitleElement::insertedInto(ContainerNode& rootParent) { SVGElement::insertedInto(rootParent); - if (!rootParent.inDocument()) + if (!rootParent.isConnected()) return InsertionDone; - // FIXME: It's possible to register SVGTitleElement to an HTMLDocument. - if (firstChild()) - // FIXME: does SVG have a title text direction? - document().setTitleElement(StringWithDirection(textContent(), LTR), this); + + if (firstChild() && document().isSVGDocument()) + document().titleElementAdded(*this); return InsertionDone; } void SVGTitleElement::removedFrom(ContainerNode& rootParent) { SVGElement::removedFrom(rootParent); - if (rootParent.inDocument()) - document().removeTitle(this); + if (rootParent.isConnected() && document().isSVGDocument()) + document().titleElementRemoved(*this); } void SVGTitleElement::childrenChanged(const ChildChange& change) { SVGElement::childrenChanged(change); - if (inDocument()) - // FIXME: does SVG have title text direction? - document().setTitleElement(StringWithDirection(textContent(), LTR), this); + document().titleElementTextChanged(*this); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTitleElement.h b/Source/WebCore/svg/SVGTitleElement.h index 81c621e7a..9afa2cc45 100644 --- a/Source/WebCore/svg/SVGTitleElement.h +++ b/Source/WebCore/svg/SVGTitleElement.h @@ -18,9 +18,7 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTitleElement_h -#define SVGTitleElement_h -#if ENABLE(SVG) +#pragma once #include "SVGElement.h" #include "SVGNames.h" @@ -29,23 +27,16 @@ namespace WebCore { class SVGTitleElement final : public SVGElement { public: - static PassRefPtr<SVGTitleElement> create(const QualifiedName&, Document&); + static Ref<SVGTitleElement> create(const QualifiedName&, Document&); private: SVGTitleElement(const QualifiedName&, Document&); - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - virtual void childrenChanged(const ChildChange&) override; + InsertionNotificationRequest insertedInto(ContainerNode&) final; + void removedFrom(ContainerNode&) final; + void childrenChanged(const ChildChange&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGTitleElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGTitleElement.idl b/Source/WebCore/svg/SVGTitleElement.idl index 8b506c9ef..2865cc20a 100644 --- a/Source/WebCore/svg/SVGTitleElement.idl +++ b/Source/WebCore/svg/SVGTitleElement.idl @@ -23,8 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGTitleElement : SVGElement { +interface SVGTitleElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGToOTFFontConversion.cpp b/Source/WebCore/svg/SVGToOTFFontConversion.cpp new file mode 100644 index 000000000..c708c5af4 --- /dev/null +++ b/Source/WebCore/svg/SVGToOTFFontConversion.cpp @@ -0,0 +1,1599 @@ +/* + * Copyright (C) 2014-2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SVGToOTFFontConversion.h" + +#if ENABLE(SVG_FONTS) + +#include "CSSStyleDeclaration.h" +#include "ElementChildIterator.h" +#include "Glyph.h" +#include "SVGFontElement.h" +#include "SVGFontFaceElement.h" +#include "SVGGlyphElement.h" +#include "SVGHKernElement.h" +#include "SVGMissingGlyphElement.h" +#include "SVGPathParser.h" +#include "SVGPathStringSource.h" +#include "SVGVKernElement.h" + +namespace WebCore { + +template <typename V> +static inline void append32(V& result, uint32_t value) +{ + result.append(value >> 24); + result.append(value >> 16); + result.append(value >> 8); + result.append(value); +} + +class SVGToOTFFontConverter { +public: + SVGToOTFFontConverter(const SVGFontElement&); + bool convertSVGToOTFFont(); + + Vector<char> releaseResult() + { + return WTFMove(m_result); + } + + bool error() const + { + return m_error; + } + +private: + struct GlyphData { + GlyphData(Vector<char>&& charString, const SVGGlyphElement* glyphElement, float horizontalAdvance, float verticalAdvance, FloatRect boundingBox, const String& codepoints) + : boundingBox(boundingBox) + , charString(charString) + , codepoints(codepoints) + , glyphElement(glyphElement) + , horizontalAdvance(horizontalAdvance) + , verticalAdvance(verticalAdvance) + { + } + FloatRect boundingBox; + Vector<char> charString; + String codepoints; + const SVGGlyphElement* glyphElement; + float horizontalAdvance; + float verticalAdvance; + }; + + class Placeholder { + public: + Placeholder(SVGToOTFFontConverter& converter, size_t baseOfOffset) + : m_converter(converter) + , m_baseOfOffset(baseOfOffset) + , m_location(m_converter.m_result.size()) + { + m_converter.append16(0); + } + + Placeholder(Placeholder&& other) + : m_converter(other.m_converter) + , m_baseOfOffset(other.m_baseOfOffset) + , m_location(other.m_location) +#if !ASSERT_DISABLED + , m_active(other.m_active) +#endif + { +#if !ASSERT_DISABLED + other.m_active = false; +#endif + } + + void populate() + { + ASSERT(m_active); + size_t delta = m_converter.m_result.size() - m_baseOfOffset; + ASSERT(delta < std::numeric_limits<uint16_t>::max()); + m_converter.overwrite16(m_location, delta); +#if !ASSERT_DISABLED + m_active = false; +#endif + } + + ~Placeholder() + { + ASSERT(!m_active); + } + + private: + SVGToOTFFontConverter& m_converter; + const size_t m_baseOfOffset; + const size_t m_location; +#if !ASSERT_DISABLED + bool m_active = { true }; +#endif + }; + + struct KerningData { + KerningData(uint16_t glyph1, uint16_t glyph2, int16_t adjustment) + : glyph1(glyph1) + , glyph2(glyph2) + , adjustment(adjustment) + { + } + uint16_t glyph1; + uint16_t glyph2; + int16_t adjustment; + }; + + Placeholder placeholder(size_t baseOfOffset) + { + return Placeholder(*this, baseOfOffset); + } + + void append32(uint32_t value) + { + WebCore::append32(m_result, value); + } + + void append32BitCode(const char code[4]) + { + m_result.append(code[0]); + m_result.append(code[1]); + m_result.append(code[2]); + m_result.append(code[3]); + } + + void append16(uint16_t value) + { + m_result.append(value >> 8); + m_result.append(value); + } + + void grow(size_t delta) + { + m_result.grow(m_result.size() + delta); + } + + void overwrite32(unsigned location, uint32_t value) + { + ASSERT(m_result.size() >= location + 4); + m_result[location] = value >> 24; + m_result[location + 1] = value >> 16; + m_result[location + 2] = value >> 8; + m_result[location + 3] = value; + } + + void overwrite16(unsigned location, uint16_t value) + { + ASSERT(m_result.size() >= location + 2); + m_result[location] = value >> 8; + m_result[location + 1] = value; + } + + static const size_t headerSize = 12; + static const size_t directoryEntrySize = 16; + + uint32_t calculateChecksum(size_t startingOffset, size_t endingOffset) const; + + void processGlyphElement(const SVGElement& glyphOrMissingGlyphElement, const SVGGlyphElement*, float defaultHorizontalAdvance, float defaultVerticalAdvance, const String& codepoints, std::optional<FloatRect>& boundingBox); + + typedef void (SVGToOTFFontConverter::*FontAppendingFunction)(); + void appendTable(const char identifier[4], FontAppendingFunction); + void appendFormat12CMAPTable(const Vector<std::pair<UChar32, Glyph>>& codepointToGlyphMappings); + void appendFormat4CMAPTable(const Vector<std::pair<UChar32, Glyph>>& codepointToGlyphMappings); + void appendCMAPTable(); + void appendGSUBTable(); + void appendHEADTable(); + void appendHHEATable(); + void appendHMTXTable(); + void appendVHEATable(); + void appendVMTXTable(); + void appendKERNTable(); + void appendMAXPTable(); + void appendNAMETable(); + void appendOS2Table(); + void appendPOSTTable(); + void appendCFFTable(); + void appendVORGTable(); + + void appendLigatureGlyphs(); + static bool compareCodepointsLexicographically(const GlyphData&, const GlyphData&); + + void appendValidCFFString(const String&); + + Vector<char> transcodeGlyphPaths(float width, const SVGElement& glyphOrMissingGlyphElement, std::optional<FloatRect>& boundingBox) const; + + void addCodepointRanges(const UnicodeRanges&, HashSet<Glyph>& glyphSet) const; + void addCodepoints(const HashSet<String>& codepoints, HashSet<Glyph>& glyphSet) const; + void addGlyphNames(const HashSet<String>& glyphNames, HashSet<Glyph>& glyphSet) const; + void addKerningPair(Vector<KerningData>&, const SVGKerningPair&) const; + template<typename T> size_t appendKERNSubtable(bool (T::*buildKerningPair)(SVGKerningPair&) const, uint16_t coverage); + size_t finishAppendingKERNSubtable(Vector<KerningData>, uint16_t coverage); + + void appendLigatureSubtable(size_t subtableRecordLocation); + void appendArabicReplacementSubtable(size_t subtableRecordLocation, const char arabicForm[]); + void appendScriptSubtable(unsigned featureCount); + Vector<Glyph, 1> glyphsForCodepoint(UChar32) const; + Glyph firstGlyph(const Vector<Glyph, 1>&, UChar32) const; + + template<typename T> T scaleUnitsPerEm(T value) const + { + return value * s_outputUnitsPerEm / m_inputUnitsPerEm; + } + + Vector<GlyphData> m_glyphs; + HashMap<String, Glyph> m_glyphNameToIndexMap; // SVG 1.1: "It is recommended that glyph names be unique within a font." + HashMap<String, Vector<Glyph, 1>> m_codepointsToIndicesMap; + Vector<char> m_result; + Vector<char, 17> m_emptyGlyphCharString; + FloatRect m_boundingBox; + const SVGFontElement& m_fontElement; + const SVGFontFaceElement* m_fontFaceElement; + const SVGMissingGlyphElement* m_missingGlyphElement; + String m_fontFamily; + float m_advanceWidthMax; + float m_advanceHeightMax; + float m_minRightSideBearing; + static const unsigned s_outputUnitsPerEm = 1000; + unsigned m_inputUnitsPerEm; + int m_lineGap; + int m_xHeight; + int m_capHeight; + int m_ascent; + int m_descent; + unsigned m_featureCountGSUB; + unsigned m_tablesAppendedCount; + char m_weight; + bool m_italic; + bool m_error { false }; +}; + +static uint16_t roundDownToPowerOfTwo(uint16_t x) +{ + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + return (x >> 1) + 1; +} + +static uint16_t integralLog2(uint16_t x) +{ + uint16_t result = 0; + while (x >>= 1) + ++result; + return result; +} + +void SVGToOTFFontConverter::appendFormat12CMAPTable(const Vector<std::pair<UChar32, Glyph>>& mappings) +{ + // Braindead scheme: One segment for each character + ASSERT(m_glyphs.size() < 0xFFFF); + auto subtableLocation = m_result.size(); + append32(12 << 16); // Format 12 + append32(0); // Placeholder for byte length + append32(0); // Language independent + append32(0); // Placeholder for nGroups + for (auto& mapping : mappings) { + append32(mapping.first); // startCharCode + append32(mapping.first); // endCharCode + append32(mapping.second); // startGlyphCode + } + overwrite32(subtableLocation + 4, m_result.size() - subtableLocation); + overwrite32(subtableLocation + 12, mappings.size()); +} + +void SVGToOTFFontConverter::appendFormat4CMAPTable(const Vector<std::pair<UChar32, Glyph>>& bmpMappings) +{ + auto subtableLocation = m_result.size(); + append16(4); // Format 4 + append16(0); // Placeholder for length in bytes + append16(0); // Language independent + uint16_t segCount = bmpMappings.size() + 1; + append16(clampTo<uint16_t>(2 * segCount)); // segCountX2: "2 x segCount" + uint16_t originalSearchRange = roundDownToPowerOfTwo(segCount); + uint16_t searchRange = clampTo<uint16_t>(2 * originalSearchRange); // searchRange: "2 x (2**floor(log2(segCount)))" + append16(searchRange); + append16(integralLog2(originalSearchRange)); // entrySelector: "log2(searchRange/2)" + append16(clampTo<uint16_t>((2 * segCount) - searchRange)); // rangeShift: "2 x segCount - searchRange" + + // Ending character codes + for (auto& mapping : bmpMappings) + append16(mapping.first); // startCharCode + append16(0xFFFF); + + append16(0); // reserved + + // Starting character codes + for (auto& mapping : bmpMappings) + append16(mapping.first); // startCharCode + append16(0xFFFF); + + // idDelta + for (auto& mapping : bmpMappings) + append16(static_cast<uint16_t>(mapping.second) - static_cast<uint16_t>(mapping.first)); // startCharCode + append16(0x0001); + + // idRangeOffset + for (size_t i = 0; i < bmpMappings.size(); ++i) + append16(0); // startCharCode + append16(0); + + // Fonts strive to hold 2^16 glyphs, but with the current encoding scheme, we write 8 bytes per codepoint into this subtable. + // Because the size of this subtable must be represented as a 16-bit number, we are limiting the number of glyphs we support to 2^13. + // FIXME: If we hit this limit in the wild, use a more compact encoding scheme for this subtable. + overwrite16(subtableLocation + 2, clampTo<uint16_t>(m_result.size() - subtableLocation)); +} + +void SVGToOTFFontConverter::appendCMAPTable() +{ + auto startingOffset = m_result.size(); + append16(0); + append16(3); // Number of subtables + + append16(0); // Unicode + append16(3); // Unicode version 2.2+ + append32(28); // Byte offset of subtable + + append16(3); // Microsoft + append16(1); // Unicode BMP + auto format4OffsetLocation = m_result.size(); + append32(0); // Byte offset of subtable + + append16(3); // Microsoft + append16(10); // Unicode + append32(28); // Byte offset of subtable + + Vector<std::pair<UChar32, Glyph>> mappings; + UChar32 previousCodepoint = std::numeric_limits<UChar32>::max(); + for (size_t i = 0; i < m_glyphs.size(); ++i) { + auto& glyph = m_glyphs[i]; + UChar32 codepoint; + auto codePoints = StringView(glyph.codepoints).codePoints(); + auto iterator = codePoints.begin(); + if (iterator == codePoints.end()) + codepoint = 0; + else { + codepoint = *iterator; + ++iterator; + // Don't map ligatures here. + if (iterator != codePoints.end() || codepoint == previousCodepoint) + continue; + } + + mappings.append(std::make_pair(codepoint, Glyph(i))); + previousCodepoint = codepoint; + } + + appendFormat12CMAPTable(mappings); + + Vector<std::pair<UChar32, Glyph>> bmpMappings; + for (auto& mapping : mappings) { + if (mapping.first < 0x10000) + bmpMappings.append(mapping); + } + overwrite32(format4OffsetLocation, m_result.size() - startingOffset); + appendFormat4CMAPTable(bmpMappings); +} + +void SVGToOTFFontConverter::appendHEADTable() +{ + append32(0x00010000); // Version + append32(0x00010000); // Revision + append32(0); // Checksum placeholder; to be overwritten by the caller. + append32(0x5F0F3CF5); // Magic number. + append16((1 << 9) | 1); + + append16(s_outputUnitsPerEm); + append32(0); // First half of creation date + append32(0); // Last half of creation date + append32(0); // First half of modification date + append32(0); // Last half of modification date + append16(clampTo<int16_t>(m_boundingBox.x())); + append16(clampTo<int16_t>(m_boundingBox.y())); + append16(clampTo<int16_t>(m_boundingBox.maxX())); + append16(clampTo<int16_t>(m_boundingBox.maxY())); + append16((m_italic ? 1 << 1 : 0) | (m_weight >= 7 ? 1 : 0)); + append16(3); // Smallest readable size in pixels + append16(0); // Might contain LTR or RTL glyphs + append16(0); // Short offsets in the 'loca' table. However, CFF fonts don't have a 'loca' table so this is irrelevant + append16(0); // Glyph data format +} + +// Assumption: T2 can hold every value that a T1 can hold. +template<typename T1, typename T2> static inline T1 clampTo(T2 x) +{ + x = std::min(x, static_cast<T2>(std::numeric_limits<T1>::max())); + x = std::max(x, static_cast<T2>(std::numeric_limits<T1>::min())); + return static_cast<T1>(x); +} + +void SVGToOTFFontConverter::appendHHEATable() +{ + append32(0x00010000); // Version + append16(clampTo<int16_t>(m_ascent)); + append16(clampTo<int16_t>(-m_descent)); + // WebKit SVG font rendering has hard coded the line gap to be 1/10th of the font size since 2008 (see r29719). + append16(clampTo<int16_t>(m_lineGap)); + append16(clampTo<uint16_t>(m_advanceWidthMax)); + append16(clampTo<int16_t>(m_boundingBox.x())); // Minimum left side bearing + append16(clampTo<int16_t>(m_minRightSideBearing)); // Minimum right side bearing + append16(clampTo<int16_t>(m_boundingBox.maxX())); // X maximum extent + // Since WebKit draws the caret and ignores the following values, it doesn't matter what we set them to. + append16(1); // Vertical caret + append16(0); // Vertical caret + append16(0); // "Set value to 0 for non-slanted fonts" + append32(0); // Reserved + append32(0); // Reserved + append16(0); // Current format + append16(m_glyphs.size()); // Number of advance widths in HMTX table +} + +void SVGToOTFFontConverter::appendHMTXTable() +{ + for (auto& glyph : m_glyphs) { + append16(clampTo<uint16_t>(glyph.horizontalAdvance)); + append16(clampTo<int16_t>(glyph.boundingBox.x())); + } +} + +void SVGToOTFFontConverter::appendMAXPTable() +{ + append32(0x00010000); // Version + append16(m_glyphs.size()); + append16(0xFFFF); // Maximum number of points in non-compound glyph + append16(0xFFFF); // Maximum number of contours in non-compound glyph + append16(0xFFFF); // Maximum number of points in compound glyph + append16(0xFFFF); // Maximum number of contours in compound glyph + append16(2); // Maximum number of zones + append16(0); // Maximum number of points used in zone 0 + append16(0); // Maximum number of storage area locations + append16(0); // Maximum number of function definitions + append16(0); // Maximum number of instruction definitions + append16(0); // Maximum stack depth + append16(0); // Maximum size of instructions + append16(m_glyphs.size()); // Maximum number of glyphs referenced at top level + append16(0); // No compound glyphs +} + +void SVGToOTFFontConverter::appendNAMETable() +{ + append16(0); // Format selector + append16(1); // Number of name records in table + append16(18); // Offset in bytes to the beginning of name character strings + + append16(0); // Unicode + append16(3); // Unicode version 2.0 or later + append16(0); // Language + append16(1); // Name identifier. 1 = Font family + append16(m_fontFamily.length() * 2); + append16(0); // Offset into name data + + for (auto codeUnit : StringView(m_fontFamily).codeUnits()) + append16(codeUnit); +} + +void SVGToOTFFontConverter::appendOS2Table() +{ + int16_t averageAdvance = s_outputUnitsPerEm; + bool ok; + int value = m_fontElement.attributeWithoutSynchronization(SVGNames::horiz_adv_xAttr).toInt(&ok); + if (!ok && m_missingGlyphElement) + value = m_missingGlyphElement->attributeWithoutSynchronization(SVGNames::horiz_adv_xAttr).toInt(&ok); + value = scaleUnitsPerEm(value); + if (ok) + averageAdvance = clampTo<int16_t>(value); + + append16(2); // Version + append16(clampTo<int16_t>(averageAdvance)); + append16(clampTo<uint16_t>(m_weight)); // Weight class + append16(5); // Width class + append16(0); // Protected font + // WebKit handles these superscripts and subscripts + append16(0); // Subscript X Size + append16(0); // Subscript Y Size + append16(0); // Subscript X Offset + append16(0); // Subscript Y Offset + append16(0); // Superscript X Size + append16(0); // Superscript Y Size + append16(0); // Superscript X Offset + append16(0); // Superscript Y Offset + append16(0); // Strikeout width + append16(0); // Strikeout Position + append16(0); // No classification + + unsigned numPanoseBytes = 0; + const unsigned panoseSize = 10; + char panoseBytes[panoseSize]; + if (m_fontFaceElement) { + Vector<String> segments; + m_fontFaceElement->attributeWithoutSynchronization(SVGNames::panose_1Attr).string().split(' ', segments); + if (segments.size() == panoseSize) { + for (auto& segment : segments) { + bool ok; + int value = segment.toInt(&ok); + if (ok && value >= 0 && value <= 0xFF) + panoseBytes[numPanoseBytes++] = value; + } + } + } + if (numPanoseBytes != panoseSize) + memset(panoseBytes, 0, panoseSize); + m_result.append(panoseBytes, panoseSize); + + for (int i = 0; i < 4; ++i) + append32(0); // "Bit assignments are pending. Set to 0" + append32(0x544B4257); // Font Vendor. "WBKT" + append16((m_weight >= 7 ? 1 << 5 : 0) | (m_italic ? 1 : 0)); // Font Patterns. + append16(0); // First unicode index + append16(0xFFFF); // Last unicode index + append16(clampTo<int16_t>(m_ascent)); // Typographical ascender + append16(clampTo<int16_t>(-m_descent)); // Typographical descender + append16(clampTo<int16_t>(m_lineGap)); // Typographical line gap + append16(clampTo<uint16_t>(m_ascent)); // Windows-specific ascent + append16(clampTo<uint16_t>(m_descent)); // Windows-specific descent + append32(0xFF10FC07); // Bitmask for supported codepages (Part 1). Report all pages as supported. + append32(0x0000FFFF); // Bitmask for supported codepages (Part 2). Report all pages as supported. + append16(clampTo<int16_t>(m_xHeight)); // x-height + append16(clampTo<int16_t>(m_capHeight)); // Cap-height + append16(0); // Default char + append16(' '); // Break character + append16(3); // Maximum context needed to perform font features + append16(3); // Smallest optical point size + append16(0xFFFF); // Largest optical point size +} + +void SVGToOTFFontConverter::appendPOSTTable() +{ + append32(0x00030000); // Format. Printing is undefined + append32(0); // Italic angle in degrees + append16(0); // Underline position + append16(0); // Underline thickness + append32(0); // Monospaced + append32(0); // "Minimum memory usage when a TrueType font is downloaded as a Type 42 font" + append32(0); // "Maximum memory usage when a TrueType font is downloaded as a Type 42 font" + append32(0); // "Minimum memory usage when a TrueType font is downloaded as a Type 1 font" + append32(0); // "Maximum memory usage when a TrueType font is downloaded as a Type 1 font" +} + +static bool isValidStringForCFF(const String& string) +{ + for (auto c : StringView(string).codeUnits()) { + if (c < 33 || c > 126) + return false; + } + return true; +} + +void SVGToOTFFontConverter::appendValidCFFString(const String& string) +{ + ASSERT(isValidStringForCFF(string)); + for (auto c : StringView(string).codeUnits()) + m_result.append(c); +} + +void SVGToOTFFontConverter::appendCFFTable() +{ + auto startingOffset = m_result.size(); + + // Header + m_result.append(1); // Major version + m_result.append(0); // Minor version + m_result.append(4); // Header size + m_result.append(4); // Offsets within CFF table are 4 bytes long + + // Name INDEX + String fontName; + if (m_fontFaceElement) { + // FIXME: fontFamily() here might not be quite what we want. + String potentialFontName = m_fontFamily; + if (isValidStringForCFF(potentialFontName)) + fontName = potentialFontName; + } + append16(1); // INDEX contains 1 element + m_result.append(4); // Offsets in this INDEX are 4 bytes long + append32(1); // 1-index offset of name data + append32(fontName.length() + 1); // 1-index offset just past end of name data + appendValidCFFString(fontName); + + String weight; + if (m_fontFaceElement) { + auto& potentialWeight = m_fontFaceElement->attributeWithoutSynchronization(SVGNames::font_weightAttr); + if (isValidStringForCFF(potentialWeight)) + weight = potentialWeight; + } + + bool hasWeight = !weight.isNull(); + + const char operand32Bit = 29; + const char fullNameKey = 2; + const char familyNameKey = 3; + const char weightKey = 4; + const char fontBBoxKey = 5; + const char charsetIndexKey = 15; + const char charstringsIndexKey = 17; + const char privateDictIndexKey = 18; + const uint32_t userDefinedStringStartIndex = 391; + const unsigned sizeOfTopIndex = 56 + (hasWeight ? 6 : 0); + + // Top DICT INDEX. + append16(1); // INDEX contains 1 element + m_result.append(4); // Offsets in this INDEX are 4 bytes long + append32(1); // 1-index offset of DICT data + append32(1 + sizeOfTopIndex); // 1-index offset just past end of DICT data + + // DICT information +#if !ASSERT_DISABLED + unsigned topDictStart = m_result.size(); +#endif + m_result.append(operand32Bit); + append32(userDefinedStringStartIndex); + m_result.append(fullNameKey); + m_result.append(operand32Bit); + append32(userDefinedStringStartIndex); + m_result.append(familyNameKey); + if (hasWeight) { + m_result.append(operand32Bit); + append32(userDefinedStringStartIndex + 2); + m_result.append(weightKey); + } + m_result.append(operand32Bit); + append32(clampTo<int32_t>(m_boundingBox.x())); + m_result.append(operand32Bit); + append32(clampTo<int32_t>(m_boundingBox.y())); + m_result.append(operand32Bit); + append32(clampTo<int32_t>(m_boundingBox.width())); + m_result.append(operand32Bit); + append32(clampTo<int32_t>(m_boundingBox.height())); + m_result.append(fontBBoxKey); + m_result.append(operand32Bit); + unsigned charsetOffsetLocation = m_result.size(); + append32(0); // Offset of Charset info. Will be overwritten later. + m_result.append(charsetIndexKey); + m_result.append(operand32Bit); + unsigned charstringsOffsetLocation = m_result.size(); + append32(0); // Offset of CharStrings INDEX. Will be overwritten later. + m_result.append(charstringsIndexKey); + m_result.append(operand32Bit); + append32(0); // 0-sized private dict + m_result.append(operand32Bit); + append32(0); // no location for private dict + m_result.append(privateDictIndexKey); // Private dict size and offset + ASSERT(m_result.size() == topDictStart + sizeOfTopIndex); + + // String INDEX + String unknownCharacter = ASCIILiteral("UnknownChar"); + append16(2 + (hasWeight ? 1 : 0)); // Number of elements in INDEX + m_result.append(4); // Offsets in this INDEX are 4 bytes long + uint32_t offset = 1; + append32(offset); + offset += fontName.length(); + append32(offset); + offset += unknownCharacter.length(); + append32(offset); + if (hasWeight) { + offset += weight.length(); + append32(offset); + } + appendValidCFFString(fontName); + appendValidCFFString(unknownCharacter); + appendValidCFFString(weight); + + append16(0); // Empty subroutine INDEX + + // Charset info + overwrite32(charsetOffsetLocation, m_result.size() - startingOffset); + m_result.append(0); + for (Glyph i = 1; i < m_glyphs.size(); ++i) + append16(userDefinedStringStartIndex + 1); + + // CharStrings INDEX + overwrite32(charstringsOffsetLocation, m_result.size() - startingOffset); + append16(m_glyphs.size()); + m_result.append(4); // Offsets in this INDEX are 4 bytes long + offset = 1; + append32(offset); + for (auto& glyph : m_glyphs) { + offset += glyph.charString.size(); + append32(offset); + } + for (auto& glyph : m_glyphs) + m_result.appendVector(glyph.charString); +} + +Glyph SVGToOTFFontConverter::firstGlyph(const Vector<Glyph, 1>& v, UChar32 codepoint) const +{ +#if ASSERT_DISABLED + UNUSED_PARAM(codepoint); +#endif + ASSERT(!v.isEmpty()); + if (v.isEmpty()) + return 0; +#if !ASSERT_DISABLED + auto codePoints = StringView(m_glyphs[v[0]].codepoints).codePoints(); + auto codePointsIterator = codePoints.begin(); + ASSERT(codePointsIterator != codePoints.end()); + ASSERT(codepoint == *codePointsIterator); +#endif + return v[0]; +} + +void SVGToOTFFontConverter::appendLigatureSubtable(size_t subtableRecordLocation) +{ + typedef std::pair<Vector<Glyph, 3>, Glyph> LigaturePair; + Vector<LigaturePair> ligaturePairs; + for (Glyph glyphIndex = 0; glyphIndex < m_glyphs.size(); ++glyphIndex) { + ligaturePairs.append(LigaturePair(Vector<Glyph, 3>(), glyphIndex)); + Vector<Glyph, 3>& ligatureGlyphs = ligaturePairs.last().first; + auto codePoints = StringView(m_glyphs[glyphIndex].codepoints).codePoints(); + // FIXME: https://bugs.webkit.org/show_bug.cgi?id=138592 This needs to be done in codepoint space, not glyph space + for (auto codePoint : codePoints) + ligatureGlyphs.append(firstGlyph(glyphsForCodepoint(codePoint), codePoint)); + if (ligatureGlyphs.size() < 2) + ligaturePairs.removeLast(); + } + if (ligaturePairs.size() > std::numeric_limits<uint16_t>::max()) + ligaturePairs.clear(); + std::sort(ligaturePairs.begin(), ligaturePairs.end(), [](auto& lhs, auto& rhs) { + return lhs.first[0] < rhs.first[0]; + }); + Vector<size_t> overlappingFirstGlyphSegmentLengths; + if (!ligaturePairs.isEmpty()) { + Glyph previousFirstGlyph = ligaturePairs[0].first[0]; + size_t segmentStart = 0; + for (size_t i = 0; i < ligaturePairs.size(); ++i) { + auto& ligaturePair = ligaturePairs[i]; + if (ligaturePair.first[0] != previousFirstGlyph) { + overlappingFirstGlyphSegmentLengths.append(i - segmentStart); + segmentStart = i; + previousFirstGlyph = ligaturePairs[0].first[0]; + } + } + overlappingFirstGlyphSegmentLengths.append(ligaturePairs.size() - segmentStart); + } + + overwrite16(subtableRecordLocation + 6, m_result.size() - subtableRecordLocation); + auto subtableLocation = m_result.size(); + append16(1); // Format 1 + append16(0); // Placeholder for offset to coverage table, relative to beginning of substitution table + append16(ligaturePairs.size()); // Number of LigatureSet tables + grow(overlappingFirstGlyphSegmentLengths.size() * 2); // Placeholder for offset to LigatureSet table + + Vector<size_t> ligatureSetTableLocations; + for (size_t i = 0; i < overlappingFirstGlyphSegmentLengths.size(); ++i) { + overwrite16(subtableLocation + 6 + 2 * i, m_result.size() - subtableLocation); + ligatureSetTableLocations.append(m_result.size()); + append16(overlappingFirstGlyphSegmentLengths[i]); // LigatureCount + grow(overlappingFirstGlyphSegmentLengths[i] * 2); // Placeholder for offset to Ligature table + } + ASSERT(ligatureSetTableLocations.size() == overlappingFirstGlyphSegmentLengths.size()); + + size_t ligaturePairIndex = 0; + for (size_t i = 0; i < overlappingFirstGlyphSegmentLengths.size(); ++i) { + for (size_t j = 0; j < overlappingFirstGlyphSegmentLengths[i]; ++j) { + overwrite16(ligatureSetTableLocations[i] + 2 + 2 * j, m_result.size() - ligatureSetTableLocations[i]); + auto& ligaturePair = ligaturePairs[ligaturePairIndex]; + append16(ligaturePair.second); + append16(ligaturePair.first.size()); + for (size_t k = 1; k < ligaturePair.first.size(); ++k) + append16(ligaturePair.first[k]); + ++ligaturePairIndex; + } + } + ASSERT(ligaturePairIndex == ligaturePairs.size()); + + // Coverage table + overwrite16(subtableLocation + 2, m_result.size() - subtableLocation); + append16(1); // CoverageFormat + append16(ligatureSetTableLocations.size()); // GlyphCount + ligaturePairIndex = 0; + for (auto segmentLength : overlappingFirstGlyphSegmentLengths) { + auto& ligaturePair = ligaturePairs[ligaturePairIndex]; + ASSERT(ligaturePair.first.size() > 1); + append16(ligaturePair.first[0]); + ligaturePairIndex += segmentLength; + } +} + +void SVGToOTFFontConverter::appendArabicReplacementSubtable(size_t subtableRecordLocation, const char arabicForm[]) +{ + Vector<std::pair<Glyph, Glyph>> arabicFinalReplacements; + for (auto& pair : m_codepointsToIndicesMap) { + for (auto glyphIndex : pair.value) { + auto& glyph = m_glyphs[glyphIndex]; + if (glyph.glyphElement && equalIgnoringASCIICase(glyph.glyphElement->attributeWithoutSynchronization(SVGNames::arabic_formAttr), arabicForm)) + arabicFinalReplacements.append(std::make_pair(pair.value[0], glyphIndex)); + } + } + if (arabicFinalReplacements.size() > std::numeric_limits<uint16_t>::max()) + arabicFinalReplacements.clear(); + + overwrite16(subtableRecordLocation + 6, m_result.size() - subtableRecordLocation); + auto subtableLocation = m_result.size(); + append16(2); // Format 2 + Placeholder toCoverageTable = placeholder(subtableLocation); + append16(arabicFinalReplacements.size()); // GlyphCount + for (auto& pair : arabicFinalReplacements) + append16(pair.second); + + toCoverageTable.populate(); + append16(1); // CoverageFormat + append16(arabicFinalReplacements.size()); // GlyphCount + for (auto& pair : arabicFinalReplacements) + append16(pair.first); +} + +void SVGToOTFFontConverter::appendScriptSubtable(unsigned featureCount) +{ + auto dfltScriptTableLocation = m_result.size(); + append16(0); // Placeholder for offset of default language system table, relative to beginning of Script table + append16(0); // Number of following language system tables + + // LangSys table + overwrite16(dfltScriptTableLocation, m_result.size() - dfltScriptTableLocation); + append16(0); // LookupOrder "= NULL ... reserved" + append16(0xFFFF); // No features are required + append16(featureCount); // Number of FeatureIndex values + for (uint16_t i = 0; i < featureCount; ++i) + append16(m_featureCountGSUB++); // Features indices +} + +void SVGToOTFFontConverter::appendGSUBTable() +{ + auto tableLocation = m_result.size(); + auto headerSize = 10; + + append32(0x00010000); // Version + append16(headerSize); // Offset to ScriptList + Placeholder toFeatureList = placeholder(tableLocation); + Placeholder toLookupList = placeholder(tableLocation); + ASSERT(tableLocation + headerSize == m_result.size()); + + // ScriptList + auto scriptListLocation = m_result.size(); + append16(2); // Number of ScriptRecords + append32BitCode("DFLT"); + append16(0); // Placeholder for offset of Script table, relative to beginning of ScriptList + append32BitCode("arab"); + append16(0); // Placeholder for offset of Script table, relative to beginning of ScriptList + + overwrite16(scriptListLocation + 6, m_result.size() - scriptListLocation); + appendScriptSubtable(1); + overwrite16(scriptListLocation + 12, m_result.size() - scriptListLocation); + appendScriptSubtable(4); + + const unsigned featureCount = 5; + + // FeatureList + toFeatureList.populate(); + auto featureListLocation = m_result.size(); + size_t featureListSize = 2 + 6 * featureCount; + size_t featureTableSize = 6; + append16(featureCount); // FeatureCount + append32BitCode("liga"); + append16(featureListSize + featureTableSize * 0); // Offset of feature table, relative to beginning of FeatureList table + append32BitCode("fina"); + append16(featureListSize + featureTableSize * 1); // Offset of feature table, relative to beginning of FeatureList table + append32BitCode("medi"); + append16(featureListSize + featureTableSize * 2); // Offset of feature table, relative to beginning of FeatureList table + append32BitCode("init"); + append16(featureListSize + featureTableSize * 3); // Offset of feature table, relative to beginning of FeatureList table + append32BitCode("rlig"); + append16(featureListSize + featureTableSize * 4); // Offset of feature table, relative to beginning of FeatureList table + ASSERT_UNUSED(featureListLocation, featureListLocation + featureListSize == m_result.size()); + + for (unsigned i = 0; i < featureCount; ++i) { + auto featureTableStart = m_result.size(); + append16(0); // FeatureParams "= NULL ... reserved" + append16(1); // LookupCount + append16(i); // LookupListIndex + ASSERT_UNUSED(featureTableStart, featureTableStart + featureTableSize == m_result.size()); + } + + // LookupList + toLookupList.populate(); + auto lookupListLocation = m_result.size(); + append16(featureCount); // LookupCount + for (unsigned i = 0; i < featureCount; ++i) + append16(0); // Placeholder for offset to feature table, relative to beginning of LookupList + size_t subtableRecordLocations[featureCount]; + for (unsigned i = 0; i < featureCount; ++i) { + subtableRecordLocations[i] = m_result.size(); + overwrite16(lookupListLocation + 2 + 2 * i, m_result.size() - lookupListLocation); + switch (i) { + case 4: + append16(3); // Type 3: "Replace one glyph with one of many glyphs" + break; + case 0: + append16(4); // Type 4: "Replace multiple glyphs with one glyph" + break; + default: + append16(1); // Type 1: "Replace one glyph with one glyph" + break; + } + append16(0); // LookupFlag + append16(1); // SubTableCount + append16(0); // Placeholder for offset to subtable, relative to beginning of Lookup table + } + + appendLigatureSubtable(subtableRecordLocations[0]); + appendArabicReplacementSubtable(subtableRecordLocations[1], "terminal"); + appendArabicReplacementSubtable(subtableRecordLocations[2], "medial"); + appendArabicReplacementSubtable(subtableRecordLocations[3], "initial"); + + // Manually append empty "rlig" subtable + overwrite16(subtableRecordLocations[4] + 6, m_result.size() - subtableRecordLocations[4]); + append16(1); // Format 1 + append16(6); // offset to coverage table, relative to beginning of substitution table + append16(0); // AlternateSetCount + append16(1); // CoverageFormat + append16(0); // GlyphCount +} + +void SVGToOTFFontConverter::appendVORGTable() +{ + append16(1); // Major version + append16(0); // Minor version + + bool ok; + int defaultVerticalOriginY = m_fontElement.attributeWithoutSynchronization(SVGNames::vert_origin_yAttr).toInt(&ok); + if (!ok && m_missingGlyphElement) + defaultVerticalOriginY = m_missingGlyphElement->attributeWithoutSynchronization(SVGNames::vert_origin_yAttr).toInt(); + defaultVerticalOriginY = scaleUnitsPerEm(defaultVerticalOriginY); + append16(clampTo<int16_t>(defaultVerticalOriginY)); + + auto tableSizeOffset = m_result.size(); + append16(0); // Place to write table size. + for (Glyph i = 0; i < m_glyphs.size(); ++i) { + if (auto* glyph = m_glyphs[i].glyphElement) { + if (int verticalOriginY = glyph->attributeWithoutSynchronization(SVGNames::vert_origin_yAttr).toInt()) { + append16(i); + append16(clampTo<int16_t>(scaleUnitsPerEm(verticalOriginY))); + } + } + } + ASSERT(!((m_result.size() - tableSizeOffset - 2) % 4)); + overwrite16(tableSizeOffset, (m_result.size() - tableSizeOffset - 2) / 4); +} + +void SVGToOTFFontConverter::appendVHEATable() +{ + float height = m_ascent + m_descent; + append32(0x00011000); // Version + append16(clampTo<int16_t>(height / 2)); // Vertical typographic ascender (vertical baseline to the right) + append16(clampTo<int16_t>(-static_cast<int>(height / 2))); // Vertical typographic descender + append16(clampTo<int16_t>(s_outputUnitsPerEm / 10)); // Vertical typographic line gap + // FIXME: m_unitsPerEm is almost certainly not correct + append16(clampTo<int16_t>(m_advanceHeightMax)); + append16(clampTo<int16_t>(s_outputUnitsPerEm - m_boundingBox.maxY())); // Minimum top side bearing + append16(clampTo<int16_t>(m_boundingBox.y())); // Minimum bottom side bearing + append16(clampTo<int16_t>(s_outputUnitsPerEm - m_boundingBox.y())); // Y maximum extent + // Since WebKit draws the caret and ignores the following values, it doesn't matter what we set them to. + append16(1); // Vertical caret + append16(0); // Vertical caret + append16(0); // "Set value to 0 for non-slanted fonts" + append32(0); // Reserved + append32(0); // Reserved + append16(0); // "Set to 0" + append16(m_glyphs.size()); // Number of advance heights in VMTX table +} + +void SVGToOTFFontConverter::appendVMTXTable() +{ + for (auto& glyph : m_glyphs) { + append16(clampTo<uint16_t>(glyph.verticalAdvance)); + append16(clampTo<int16_t>(s_outputUnitsPerEm - glyph.boundingBox.maxY())); // top side bearing + } +} + +static String codepointToString(UChar32 codepoint) +{ + UChar buffer[2]; + uint8_t length = 0; + UBool error = false; + U16_APPEND(buffer, length, 2, codepoint, error); + return error ? String() : String(buffer, length); +} + +Vector<Glyph, 1> SVGToOTFFontConverter::glyphsForCodepoint(UChar32 codepoint) const +{ + return m_codepointsToIndicesMap.get(codepointToString(codepoint)); +} + +void SVGToOTFFontConverter::addCodepointRanges(const UnicodeRanges& unicodeRanges, HashSet<Glyph>& glyphSet) const +{ + for (auto& unicodeRange : unicodeRanges) { + for (auto codepoint = unicodeRange.first; codepoint <= unicodeRange.second; ++codepoint) { + for (auto index : glyphsForCodepoint(codepoint)) + glyphSet.add(index); + } + } +} + +void SVGToOTFFontConverter::addCodepoints(const HashSet<String>& codepoints, HashSet<Glyph>& glyphSet) const +{ + for (auto& codepointString : codepoints) { + for (auto index : m_codepointsToIndicesMap.get(codepointString)) + glyphSet.add(index); + } +} + +void SVGToOTFFontConverter::addGlyphNames(const HashSet<String>& glyphNames, HashSet<Glyph>& glyphSet) const +{ + for (auto& glyphName : glyphNames) { + if (Glyph glyph = m_glyphNameToIndexMap.get(glyphName)) + glyphSet.add(glyph); + } +} + +void SVGToOTFFontConverter::addKerningPair(Vector<KerningData>& data, const SVGKerningPair& kerningPair) const +{ + HashSet<Glyph> glyphSet1; + HashSet<Glyph> glyphSet2; + + addCodepointRanges(kerningPair.unicodeRange1, glyphSet1); + addCodepointRanges(kerningPair.unicodeRange2, glyphSet2); + addGlyphNames(kerningPair.glyphName1, glyphSet1); + addGlyphNames(kerningPair.glyphName2, glyphSet2); + addCodepoints(kerningPair.unicodeName1, glyphSet1); + addCodepoints(kerningPair.unicodeName2, glyphSet2); + + // FIXME: Use table format 2 so we don't have to append each of these one by one. + for (auto& glyph1 : glyphSet1) { + for (auto& glyph2 : glyphSet2) + data.append(KerningData(glyph1, glyph2, clampTo<int16_t>(-scaleUnitsPerEm(kerningPair.kerning)))); + } +} + +template<typename T> inline size_t SVGToOTFFontConverter::appendKERNSubtable(bool (T::*buildKerningPair)(SVGKerningPair&) const, uint16_t coverage) +{ + Vector<KerningData> kerningData; + for (auto& element : childrenOfType<T>(m_fontElement)) { + SVGKerningPair kerningPair; + if ((element.*buildKerningPair)(kerningPair)) + addKerningPair(kerningData, kerningPair); + } + return finishAppendingKERNSubtable(WTFMove(kerningData), coverage); +} + +size_t SVGToOTFFontConverter::finishAppendingKERNSubtable(Vector<KerningData> kerningData, uint16_t coverage) +{ + std::sort(kerningData.begin(), kerningData.end(), [](auto& a, auto& b) { + return a.glyph1 < b.glyph1 || (a.glyph1 == b.glyph1 && a.glyph2 < b.glyph2); + }); + + size_t sizeOfKerningDataTable = 14 + 6 * kerningData.size(); + if (sizeOfKerningDataTable > std::numeric_limits<uint16_t>::max()) { + kerningData.clear(); + sizeOfKerningDataTable = 14; + } + + append16(0); // Version of subtable + append16(sizeOfKerningDataTable); // Length of this subtable + append16(coverage); // Table coverage bitfield + + uint16_t roundedNumKerningPairs = roundDownToPowerOfTwo(kerningData.size()); + + append16(kerningData.size()); + append16(roundedNumKerningPairs * 6); // searchRange: "The largest power of two less than or equal to the value of nPairs, multiplied by the size in bytes of an entry in the table." + append16(integralLog2(roundedNumKerningPairs)); // entrySelector: "log2 of the largest power of two less than or equal to the value of nPairs." + append16((kerningData.size() - roundedNumKerningPairs) * 6); // rangeShift: "The value of nPairs minus the largest power of two less than or equal to nPairs, + // and then multiplied by the size in bytes of an entry in the table." + + for (auto& kerningDataElement : kerningData) { + append16(kerningDataElement.glyph1); + append16(kerningDataElement.glyph2); + append16(kerningDataElement.adjustment); + } + + return sizeOfKerningDataTable; +} + +void SVGToOTFFontConverter::appendKERNTable() +{ + append16(0); // Version + append16(2); // Number of subtables + +#if !ASSERT_DISABLED + auto subtablesOffset = m_result.size(); +#endif + + size_t sizeOfHorizontalSubtable = appendKERNSubtable<SVGHKernElement>(&SVGHKernElement::buildHorizontalKerningPair, 1); + ASSERT_UNUSED(sizeOfHorizontalSubtable, subtablesOffset + sizeOfHorizontalSubtable == m_result.size()); + size_t sizeOfVerticalSubtable = appendKERNSubtable<SVGVKernElement>(&SVGVKernElement::buildVerticalKerningPair, 0); + ASSERT_UNUSED(sizeOfVerticalSubtable, subtablesOffset + sizeOfHorizontalSubtable + sizeOfVerticalSubtable == m_result.size()); + +#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 + // Work around a bug in Apple's font parser by adding some padding bytes. <rdar://problem/18401901> + for (int i = 0; i < 6; ++i) + m_result.append(0); +#endif +} + +template <typename V> +static void writeCFFEncodedNumber(V& vector, float number) +{ + vector.append(0xFF); + // Convert to 16.16 fixed-point + append32(vector, clampTo<int32_t>(number * 0x10000)); +} + +static const char rLineTo = 0x05; +static const char rrCurveTo = 0x08; +static const char endChar = 0x0e; +static const char rMoveTo = 0x15; + +class CFFBuilder final : public SVGPathConsumer { +public: + CFFBuilder(Vector<char>& cffData, float width, FloatPoint origin, float unitsPerEmScalar) + : m_cffData(cffData) + , m_unitsPerEmScalar(unitsPerEmScalar) + { + writeCFFEncodedNumber(m_cffData, std::floor(width)); // hmtx table can't encode fractional FUnit values, and the CFF table needs to agree with hmtx. + writeCFFEncodedNumber(m_cffData, origin.x()); + writeCFFEncodedNumber(m_cffData, origin.y()); + m_cffData.append(rMoveTo); + } + + std::optional<FloatRect> boundingBox() const + { + return m_boundingBox; + } + +private: + void updateBoundingBox(FloatPoint point) + { + if (!m_boundingBox) { + m_boundingBox = FloatRect(point, FloatSize()); + return; + } + m_boundingBox.value().extend(point); + } + + void writePoint(FloatPoint destination) + { + updateBoundingBox(destination); + + FloatSize delta = destination - m_current; + writeCFFEncodedNumber(m_cffData, delta.width()); + writeCFFEncodedNumber(m_cffData, delta.height()); + + m_current = destination; + } + + void moveTo(const FloatPoint& targetPoint, bool closed, PathCoordinateMode mode) final + { + if (closed && !m_cffData.isEmpty()) + closePath(); + + FloatPoint scaledTargetPoint = FloatPoint(targetPoint.x() * m_unitsPerEmScalar, targetPoint.y() * m_unitsPerEmScalar); + FloatPoint destination = mode == AbsoluteCoordinates ? scaledTargetPoint : m_current + scaledTargetPoint; + + writePoint(destination); + m_cffData.append(rMoveTo); + + m_startingPoint = m_current; + } + + void unscaledLineTo(const FloatPoint& targetPoint) + { + writePoint(targetPoint); + m_cffData.append(rLineTo); + } + + void lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode) final + { + FloatPoint scaledTargetPoint = FloatPoint(targetPoint.x() * m_unitsPerEmScalar, targetPoint.y() * m_unitsPerEmScalar); + FloatPoint destination = mode == AbsoluteCoordinates ? scaledTargetPoint : m_current + scaledTargetPoint; + + unscaledLineTo(destination); + } + + void curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& point3, PathCoordinateMode mode) final + { + FloatPoint scaledPoint1 = FloatPoint(point1.x() * m_unitsPerEmScalar, point1.y() * m_unitsPerEmScalar); + FloatPoint scaledPoint2 = FloatPoint(point2.x() * m_unitsPerEmScalar, point2.y() * m_unitsPerEmScalar); + FloatPoint scaledPoint3 = FloatPoint(point3.x() * m_unitsPerEmScalar, point3.y() * m_unitsPerEmScalar); + + if (mode == RelativeCoordinates) { + scaledPoint1 += m_current; + scaledPoint2 += m_current; + scaledPoint3 += m_current; + } + + writePoint(scaledPoint1); + writePoint(scaledPoint2); + writePoint(scaledPoint3); + m_cffData.append(rrCurveTo); + } + + void closePath() final + { + if (m_current != m_startingPoint) + unscaledLineTo(m_startingPoint); + } + + void incrementPathSegmentCount() final { } + bool continueConsuming() final { return true; } + + void lineToHorizontal(float, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void lineToVertical(float, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) final { ASSERT_NOT_REACHED(); } + + Vector<char>& m_cffData; + FloatPoint m_startingPoint; + FloatPoint m_current; + std::optional<FloatRect> m_boundingBox; + float m_unitsPerEmScalar; +}; + +Vector<char> SVGToOTFFontConverter::transcodeGlyphPaths(float width, const SVGElement& glyphOrMissingGlyphElement, std::optional<FloatRect>& boundingBox) const +{ + Vector<char> result; + + auto& dAttribute = glyphOrMissingGlyphElement.attributeWithoutSynchronization(SVGNames::dAttr); + if (dAttribute.isEmpty()) { + writeCFFEncodedNumber(result, width); + writeCFFEncodedNumber(result, 0); + writeCFFEncodedNumber(result, 0); + result.append(rMoveTo); + result.append(endChar); + return result; + } + + // FIXME: If we are vertical, use vert_origin_x and vert_origin_y + bool ok; + float horizontalOriginX = scaleUnitsPerEm(glyphOrMissingGlyphElement.attributeWithoutSynchronization(SVGNames::horiz_origin_xAttr).toFloat(&ok)); + if (!ok && m_fontFaceElement) + horizontalOriginX = scaleUnitsPerEm(m_fontFaceElement->horizontalOriginX()); + float horizontalOriginY = scaleUnitsPerEm(glyphOrMissingGlyphElement.attributeWithoutSynchronization(SVGNames::horiz_origin_yAttr).toFloat(&ok)); + if (!ok && m_fontFaceElement) + horizontalOriginY = scaleUnitsPerEm(m_fontFaceElement->horizontalOriginY()); + + CFFBuilder builder(result, width, FloatPoint(horizontalOriginX, horizontalOriginY), static_cast<float>(s_outputUnitsPerEm) / m_inputUnitsPerEm); + SVGPathStringSource source(dAttribute); + + ok = SVGPathParser::parse(source, builder); + if (!ok) + return { }; + + boundingBox = builder.boundingBox(); + + result.append(endChar); + return result; +} + +void SVGToOTFFontConverter::processGlyphElement(const SVGElement& glyphOrMissingGlyphElement, const SVGGlyphElement* glyphElement, float defaultHorizontalAdvance, float defaultVerticalAdvance, const String& codepoints, std::optional<FloatRect>& boundingBox) +{ + bool ok; + float horizontalAdvance = scaleUnitsPerEm(glyphOrMissingGlyphElement.attributeWithoutSynchronization(SVGNames::horiz_adv_xAttr).toFloat(&ok)); + if (!ok) + horizontalAdvance = defaultHorizontalAdvance; + m_advanceWidthMax = std::max(m_advanceWidthMax, horizontalAdvance); + float verticalAdvance = scaleUnitsPerEm(glyphOrMissingGlyphElement.attributeWithoutSynchronization(SVGNames::vert_adv_yAttr).toFloat(&ok)); + if (!ok) + verticalAdvance = defaultVerticalAdvance; + m_advanceHeightMax = std::max(m_advanceHeightMax, verticalAdvance); + + std::optional<FloatRect> glyphBoundingBox; + auto path = transcodeGlyphPaths(horizontalAdvance, glyphOrMissingGlyphElement, glyphBoundingBox); + if (!path.size()) { + // It's better to use a fallback font rather than use a font without all its glyphs. + m_error = true; + } + if (!boundingBox) + boundingBox = glyphBoundingBox; + else if (glyphBoundingBox) + boundingBox.value().unite(glyphBoundingBox.value()); + if (glyphBoundingBox) + m_minRightSideBearing = std::min(m_minRightSideBearing, horizontalAdvance - glyphBoundingBox.value().maxX()); + + m_glyphs.append(GlyphData(WTFMove(path), glyphElement, horizontalAdvance, verticalAdvance, glyphBoundingBox.value_or(FloatRect()), codepoints)); +} + +void SVGToOTFFontConverter::appendLigatureGlyphs() +{ + HashSet<UChar32> ligatureCodepoints; + HashSet<UChar32> nonLigatureCodepoints; + for (auto& glyph : m_glyphs) { + auto codePoints = StringView(glyph.codepoints).codePoints(); + auto codePointsIterator = codePoints.begin(); + if (codePointsIterator == codePoints.end()) + continue; + UChar32 codepoint = *codePointsIterator; + ++codePointsIterator; + if (codePointsIterator == codePoints.end()) + nonLigatureCodepoints.add(codepoint); + else { + ligatureCodepoints.add(codepoint); + for (; codePointsIterator != codePoints.end(); ++codePointsIterator) + ligatureCodepoints.add(*codePointsIterator); + } + } + + for (auto codepoint : nonLigatureCodepoints) + ligatureCodepoints.remove(codepoint); + for (auto codepoint : ligatureCodepoints) { + auto codepoints = codepointToString(codepoint); + if (!codepoints.isNull()) + m_glyphs.append(GlyphData(Vector<char>(m_emptyGlyphCharString), nullptr, s_outputUnitsPerEm, s_outputUnitsPerEm, FloatRect(), codepoints)); + } +} + +bool SVGToOTFFontConverter::compareCodepointsLexicographically(const GlyphData& data1, const GlyphData& data2) +{ + auto codePoints1 = StringView(data1.codepoints).codePoints(); + auto codePoints2 = StringView(data2.codepoints).codePoints(); + auto iterator1 = codePoints1.begin(); + auto iterator2 = codePoints2.begin(); + while (iterator1 != codePoints1.end() && iterator2 != codePoints2.end()) { + UChar32 codepoint1, codepoint2; + codepoint1 = *iterator1; + codepoint2 = *iterator2; + + if (codepoint1 < codepoint2) + return true; + if (codepoint1 > codepoint2) + return false; + + ++iterator1; + ++iterator2; + } + + if (iterator1 == codePoints1.end() && iterator2 == codePoints2.end()) { + bool firstIsIsolated = data1.glyphElement && equalLettersIgnoringASCIICase(data1.glyphElement->attributeWithoutSynchronization(SVGNames::arabic_formAttr), "isolated"); + bool secondIsIsolated = data2.glyphElement && equalLettersIgnoringASCIICase(data2.glyphElement->attributeWithoutSynchronization(SVGNames::arabic_formAttr), "isolated"); + return firstIsIsolated && !secondIsIsolated; + } + return iterator1 == codePoints1.end(); +} + +static void populateEmptyGlyphCharString(Vector<char, 17>& o, unsigned unitsPerEm) +{ + writeCFFEncodedNumber(o, unitsPerEm); + writeCFFEncodedNumber(o, 0); + writeCFFEncodedNumber(o, 0); + o.append(rMoveTo); + o.append(endChar); +} + +SVGToOTFFontConverter::SVGToOTFFontConverter(const SVGFontElement& fontElement) + : m_fontElement(fontElement) + , m_fontFaceElement(childrenOfType<SVGFontFaceElement>(m_fontElement).first()) + , m_missingGlyphElement(childrenOfType<SVGMissingGlyphElement>(m_fontElement).first()) + , m_advanceWidthMax(0) + , m_advanceHeightMax(0) + , m_minRightSideBearing(std::numeric_limits<float>::max()) + , m_featureCountGSUB(0) + , m_tablesAppendedCount(0) + , m_weight(5) + , m_italic(false) +{ + if (!m_fontFaceElement) { + m_inputUnitsPerEm = 1; + m_ascent = s_outputUnitsPerEm; + m_descent = 1; + m_xHeight = s_outputUnitsPerEm; + m_capHeight = m_ascent; + } else { + m_inputUnitsPerEm = m_fontFaceElement->unitsPerEm(); + m_ascent = scaleUnitsPerEm(m_fontFaceElement->ascent()); + m_descent = scaleUnitsPerEm(m_fontFaceElement->descent()); + m_xHeight = scaleUnitsPerEm(m_fontFaceElement->xHeight()); + m_capHeight = scaleUnitsPerEm(m_fontFaceElement->capHeight()); + + // Some platforms, including OS X, use 0 ascent and descent to mean that the platform should synthesize + // a value based on a heuristic. However, SVG fonts can legitimately have 0 for ascent or descent. + // Specifing a single FUnit gets us as close to 0 as we can without triggering the synthesis. + if (!m_ascent) + m_ascent = 1; + if (!m_descent) + m_descent = 1; + } + + float defaultHorizontalAdvance = m_fontFaceElement ? scaleUnitsPerEm(m_fontFaceElement->horizontalAdvanceX()) : 0; + float defaultVerticalAdvance = m_fontFaceElement ? scaleUnitsPerEm(m_fontFaceElement->verticalAdvanceY()) : 0; + + m_lineGap = s_outputUnitsPerEm / 10; + + populateEmptyGlyphCharString(m_emptyGlyphCharString, s_outputUnitsPerEm); + + std::optional<FloatRect> boundingBox; + if (m_missingGlyphElement) + processGlyphElement(*m_missingGlyphElement, nullptr, defaultHorizontalAdvance, defaultVerticalAdvance, String(), boundingBox); + else { + m_glyphs.append(GlyphData(Vector<char>(m_emptyGlyphCharString), nullptr, s_outputUnitsPerEm, s_outputUnitsPerEm, FloatRect(), String())); + boundingBox = FloatRect(0, 0, s_outputUnitsPerEm, s_outputUnitsPerEm); + } + + for (auto& glyphElement : childrenOfType<SVGGlyphElement>(m_fontElement)) { + auto& unicodeAttribute = glyphElement.attributeWithoutSynchronization(SVGNames::unicodeAttr); + if (!unicodeAttribute.isEmpty()) // If we can never actually trigger this glyph, ignore it completely + processGlyphElement(glyphElement, &glyphElement, defaultHorizontalAdvance, defaultVerticalAdvance, unicodeAttribute, boundingBox); + } + + m_boundingBox = boundingBox.value_or(FloatRect()); + +#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 + // <rdar://problem/20086223> Cocoa has a bug where glyph bounding boxes are not correctly respected for frustum culling. Work around this by + // inflating the font's bounding box + m_boundingBox.extend(FloatPoint(0, 0)); +#endif + + appendLigatureGlyphs(); + + if (m_glyphs.size() > std::numeric_limits<Glyph>::max()) { + m_glyphs.clear(); + return; + } + + std::sort(m_glyphs.begin(), m_glyphs.end(), &compareCodepointsLexicographically); + + for (Glyph i = 0; i < m_glyphs.size(); ++i) { + GlyphData& glyph = m_glyphs[i]; + if (glyph.glyphElement) { + auto& glyphName = glyph.glyphElement->attributeWithoutSynchronization(SVGNames::glyph_nameAttr); + if (!glyphName.isNull()) + m_glyphNameToIndexMap.add(glyphName, i); + } + if (m_codepointsToIndicesMap.isValidKey(glyph.codepoints)) { + auto& glyphVector = m_codepointsToIndicesMap.add(glyph.codepoints, Vector<Glyph>()).iterator->value; + // Prefer isolated arabic forms + if (glyph.glyphElement && equalLettersIgnoringASCIICase(glyph.glyphElement->attributeWithoutSynchronization(SVGNames::arabic_formAttr), "isolated")) + glyphVector.insert(0, i); + else + glyphVector.append(i); + } + } + + // FIXME: Handle commas. + if (m_fontFaceElement) { + Vector<String> segments; + m_fontFaceElement->attributeWithoutSynchronization(SVGNames::font_weightAttr).string().split(' ', segments); + for (auto& segment : segments) { + if (equalLettersIgnoringASCIICase(segment, "bold")) { + m_weight = 7; + break; + } + bool ok; + int value = segment.toInt(&ok); + if (ok && value >= 0 && value < 1000) { + m_weight = (value + 50) / 100; + break; + } + } + m_fontFaceElement->attributeWithoutSynchronization(SVGNames::font_styleAttr).string().split(' ', segments); + for (auto& segment : segments) { + if (equalLettersIgnoringASCIICase(segment, "italic") || equalLettersIgnoringASCIICase(segment, "oblique")) { + m_italic = true; + break; + } + } + } + + if (m_fontFaceElement) + m_fontFamily = m_fontFaceElement->fontFamily(); +} + +static inline bool isFourByteAligned(size_t x) +{ + return !(x & 3); +} + +uint32_t SVGToOTFFontConverter::calculateChecksum(size_t startingOffset, size_t endingOffset) const +{ + ASSERT(isFourByteAligned(endingOffset - startingOffset)); + uint32_t sum = 0; + for (size_t offset = startingOffset; offset < endingOffset; offset += 4) { + sum += static_cast<unsigned char>(m_result[offset + 3]) + | (static_cast<unsigned char>(m_result[offset + 2]) << 8) + | (static_cast<unsigned char>(m_result[offset + 1]) << 16) + | (static_cast<unsigned char>(m_result[offset]) << 24); + } + return sum; +} + +void SVGToOTFFontConverter::appendTable(const char identifier[4], FontAppendingFunction appendingFunction) +{ + size_t offset = m_result.size(); + ASSERT(isFourByteAligned(offset)); + (this->*appendingFunction)(); + size_t unpaddedSize = m_result.size() - offset; + while (!isFourByteAligned(m_result.size())) + m_result.append(0); + ASSERT(isFourByteAligned(m_result.size())); + size_t directoryEntryOffset = headerSize + m_tablesAppendedCount * directoryEntrySize; + m_result[directoryEntryOffset] = identifier[0]; + m_result[directoryEntryOffset + 1] = identifier[1]; + m_result[directoryEntryOffset + 2] = identifier[2]; + m_result[directoryEntryOffset + 3] = identifier[3]; + overwrite32(directoryEntryOffset + 4, calculateChecksum(offset, m_result.size())); + overwrite32(directoryEntryOffset + 8, offset); + overwrite32(directoryEntryOffset + 12, unpaddedSize); + ++m_tablesAppendedCount; +} + +bool SVGToOTFFontConverter::convertSVGToOTFFont() +{ + if (m_glyphs.isEmpty()) + return false; + + uint16_t numTables = 14; + uint16_t roundedNumTables = roundDownToPowerOfTwo(numTables); + uint16_t searchRange = roundedNumTables * 16; // searchRange: "(Maximum power of 2 <= numTables) x 16." + + m_result.append('O'); + m_result.append('T'); + m_result.append('T'); + m_result.append('O'); + append16(numTables); + append16(searchRange); + append16(integralLog2(roundedNumTables)); // entrySelector: "Log2(maximum power of 2 <= numTables)." + append16(numTables * 16 - searchRange); // rangeShift: "NumTables x 16-searchRange." + + ASSERT(m_result.size() == headerSize); + + // Leave space for the directory entries. + for (size_t i = 0; i < directoryEntrySize * numTables; ++i) + m_result.append(0); + + appendTable("CFF ", &SVGToOTFFontConverter::appendCFFTable); + appendTable("GSUB", &SVGToOTFFontConverter::appendGSUBTable); + appendTable("OS/2", &SVGToOTFFontConverter::appendOS2Table); + appendTable("VORG", &SVGToOTFFontConverter::appendVORGTable); + appendTable("cmap", &SVGToOTFFontConverter::appendCMAPTable); + auto headTableOffset = m_result.size(); + appendTable("head", &SVGToOTFFontConverter::appendHEADTable); + appendTable("hhea", &SVGToOTFFontConverter::appendHHEATable); + appendTable("hmtx", &SVGToOTFFontConverter::appendHMTXTable); + appendTable("kern", &SVGToOTFFontConverter::appendKERNTable); + appendTable("maxp", &SVGToOTFFontConverter::appendMAXPTable); + appendTable("name", &SVGToOTFFontConverter::appendNAMETable); + appendTable("post", &SVGToOTFFontConverter::appendPOSTTable); + appendTable("vhea", &SVGToOTFFontConverter::appendVHEATable); + appendTable("vmtx", &SVGToOTFFontConverter::appendVMTXTable); + + ASSERT(numTables == m_tablesAppendedCount); + + // checksumAdjustment: "To compute: set it to 0, calculate the checksum for the 'head' table and put it in the table directory, + // sum the entire font as uint32, then store B1B0AFBA - sum. The checksum for the 'head' table will now be wrong. That is OK." + overwrite32(headTableOffset + 8, 0xB1B0AFBAU - calculateChecksum(0, m_result.size())); + return true; +} + +std::optional<Vector<char>> convertSVGToOTFFont(const SVGFontElement& element) +{ + SVGToOTFFontConverter converter(element); + if (converter.error()) + return std::nullopt; + if (!converter.convertSVGToOTFFont()) + return std::nullopt; + return converter.releaseResult(); +} + +} + +#endif // ENABLE(SVG_FONTS) diff --git a/Source/WebCore/svg/SVGToOTFFontConversion.h b/Source/WebCore/svg/SVGToOTFFontConversion.h new file mode 100644 index 000000000..7756e4529 --- /dev/null +++ b/Source/WebCore/svg/SVGToOTFFontConversion.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <wtf/Optional.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class SVGFontElement; + +std::optional<Vector<char>> convertSVGToOTFFont(const SVGFontElement&); + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGTransform.cpp b/Source/WebCore/svg/SVGTransform.cpp index 5f9d56f46..59037945a 100644 --- a/Source/WebCore/svg/SVGTransform.cpp +++ b/Source/WebCore/svg/SVGTransform.cpp @@ -1,244 +1,38 @@ /* - * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTransform.h" -#include "FloatConversion.h" -#include "FloatPoint.h" -#include "FloatSize.h" -#include "SVGAngle.h" -#include "SVGSVGElement.h" -#include <wtf/MathExtras.h> -#include <wtf/text/StringBuilder.h> -#include <wtf/text/WTFString.h> +#include "SVGMatrixTearOff.h" namespace WebCore { -SVGTransform::SVGTransform() - : m_type(SVG_TRANSFORM_UNKNOWN) - , m_angle(0) +Ref<SVGMatrix> SVGTransform::matrix() { -} - -SVGTransform::SVGTransform(SVGTransformType type, ConstructionMode mode) - : m_type(type) - , m_angle(0) -{ - if (mode == ConstructZeroTransform) - m_matrix = AffineTransform(0, 0, 0, 0, 0, 0); -} - -SVGTransform::SVGTransform(const AffineTransform& matrix) - : m_type(SVG_TRANSFORM_MATRIX) - , m_angle(0) - , m_matrix(matrix) -{ -} - -void SVGTransform::setMatrix(const AffineTransform& matrix) -{ - m_type = SVG_TRANSFORM_MATRIX; - m_angle = 0; - m_matrix = matrix; -} - -void SVGTransform::updateSVGMatrix() -{ - // The underlying matrix has been changed, alter the transformation type. - // Spec: In case the matrix object is changed directly (i.e., without using the methods on the SVGTransform interface itself) - // then the type of the SVGTransform changes to SVG_TRANSFORM_MATRIX. - m_type = SVG_TRANSFORM_MATRIX; - m_angle = 0; -} - -void SVGTransform::setTranslate(float tx, float ty) -{ - m_type = SVG_TRANSFORM_TRANSLATE; - m_angle = 0; - - m_matrix.makeIdentity(); - m_matrix.translate(tx, ty); -} - -FloatPoint SVGTransform::translate() const -{ - return FloatPoint::narrowPrecision(m_matrix.e(), m_matrix.f()); -} - -void SVGTransform::setScale(float sx, float sy) -{ - m_type = SVG_TRANSFORM_SCALE; - m_angle = 0; - m_center = FloatPoint(); - - m_matrix.makeIdentity(); - m_matrix.scaleNonUniform(sx, sy); -} - -FloatSize SVGTransform::scale() const -{ - return FloatSize::narrowPrecision(m_matrix.a(), m_matrix.d()); -} - -void SVGTransform::setRotate(float angle, float cx, float cy) -{ - m_type = SVG_TRANSFORM_ROTATE; - m_angle = angle; - m_center = FloatPoint(cx, cy); - - // TODO: toString() implementation, which can show cx, cy (need to be stored?) - m_matrix.makeIdentity(); - m_matrix.translate(cx, cy); - m_matrix.rotate(angle); - m_matrix.translate(-cx, -cy); -} - -void SVGTransform::setSkewX(float angle) -{ - m_type = SVG_TRANSFORM_SKEWX; - m_angle = angle; - - m_matrix.makeIdentity(); - m_matrix.skewX(angle); -} - -void SVGTransform::setSkewY(float angle) -{ - m_type = SVG_TRANSFORM_SKEWY; - m_angle = angle; - - m_matrix.makeIdentity(); - m_matrix.skewY(angle); -} - -const String& SVGTransform::transformTypePrefixForParsing(SVGTransformType type) -{ - switch (type) { - case SVG_TRANSFORM_UNKNOWN: - return emptyString(); - case SVG_TRANSFORM_MATRIX: { - DEFINE_STATIC_LOCAL(String, matrixString, (ASCIILiteral("matrix("))); - return matrixString; - } - case SVG_TRANSFORM_TRANSLATE: { - DEFINE_STATIC_LOCAL(String, translateString, (ASCIILiteral("translate("))); - return translateString; - } - case SVG_TRANSFORM_SCALE: { - DEFINE_STATIC_LOCAL(String, scaleString, (ASCIILiteral("scale("))); - return scaleString; - } - case SVG_TRANSFORM_ROTATE: { - DEFINE_STATIC_LOCAL(String, rotateString, (ASCIILiteral("rotate("))); - return rotateString; - } - case SVG_TRANSFORM_SKEWX: { - DEFINE_STATIC_LOCAL(String, skewXString, (ASCIILiteral("skewX("))); - return skewXString; - } - case SVG_TRANSFORM_SKEWY: { - DEFINE_STATIC_LOCAL(String, skewYString, (ASCIILiteral("skewY("))); - return skewYString; - } - } - - ASSERT_NOT_REACHED(); - return emptyString(); -} - -String SVGTransform::valueAsString() const -{ - const String& prefix = transformTypePrefixForParsing(m_type); - switch (m_type) { - case SVG_TRANSFORM_UNKNOWN: - return prefix; - case SVG_TRANSFORM_MATRIX: { - StringBuilder builder; - builder.append(prefix); - builder.appendNumber(m_matrix.a()); - builder.append(' '); - builder.appendNumber(m_matrix.b()); - builder.append(' '); - builder.appendNumber(m_matrix.c()); - builder.append(' '); - builder.appendNumber(m_matrix.d()); - builder.append(' '); - builder.appendNumber(m_matrix.e()); - builder.append(' '); - builder.appendNumber(m_matrix.f()); - builder.append(')'); - return builder.toString(); - } - case SVG_TRANSFORM_TRANSLATE: { - StringBuilder builder; - builder.append(prefix); - builder.appendNumber(m_matrix.e()); - builder.append(' '); - builder.appendNumber(m_matrix.f()); - builder.append(')'); - return builder.toString(); - } - case SVG_TRANSFORM_SCALE: { - StringBuilder builder; - builder.append(prefix); - builder.appendNumber(m_matrix.xScale()); - builder.append(' '); - builder.appendNumber(m_matrix.yScale()); - builder.append(')'); - return builder.toString(); - } - case SVG_TRANSFORM_ROTATE: { - double angleInRad = deg2rad(m_angle); - double cosAngle = cos(angleInRad); - double sinAngle = sin(angleInRad); - float cx = narrowPrecisionToFloat(cosAngle != 1 ? (m_matrix.e() * (1 - cosAngle) - m_matrix.f() * sinAngle) / (1 - cosAngle) / 2 : 0); - float cy = narrowPrecisionToFloat(cosAngle != 1 ? (m_matrix.e() * sinAngle / (1 - cosAngle) + m_matrix.f()) / 2 : 0); - StringBuilder builder; - builder.append(prefix); - builder.appendNumber(m_angle); - if (cx || cy) { - builder.append(' '); - builder.appendNumber(cx); - builder.append(' '); - builder.appendNumber(cy); - } - builder.append(')'); - return builder.toString(); - } - case SVG_TRANSFORM_SKEWX: - case SVG_TRANSFORM_SKEWY: { - StringBuilder builder; - builder.append(prefix); - builder.appendNumber(m_angle); - builder.append(')'); - return builder.toString(); - } - } - - ASSERT_NOT_REACHED(); - return emptyString(); + return SVGMatrixTearOff::create(*this, propertyReference().svgMatrix()); } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTransform.h b/Source/WebCore/svg/SVGTransform.h index a03f9ed74..e817bd225 100644 --- a/Source/WebCore/svg/SVGTransform.h +++ b/Source/WebCore/svg/SVGTransform.h @@ -1,100 +1,154 @@ /* - * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> - * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> + * Copyright (C) 2016 Apple Inc. 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * This 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. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGTransform_h -#define SVGTransform_h +#pragma once -#if ENABLE(SVG) -#include "FloatPoint.h" +#include "ExceptionCode.h" #include "SVGMatrix.h" +#include "SVGPropertyTearOff.h" +#include "SVGTransformValue.h" namespace WebCore { -class FloatSize; - -class SVGTransform { +class SVGTransform : public SVGPropertyTearOff<SVGTransformValue> { public: - enum SVGTransformType { - SVG_TRANSFORM_UNKNOWN = 0, - SVG_TRANSFORM_MATRIX = 1, - SVG_TRANSFORM_TRANSLATE = 2, - SVG_TRANSFORM_SCALE = 3, - SVG_TRANSFORM_ROTATE = 4, - SVG_TRANSFORM_SKEWX = 5, - SVG_TRANSFORM_SKEWY = 6 - }; - - enum ConstructionMode { - ConstructIdentityTransform, - ConstructZeroTransform - }; - - SVGTransform(); - SVGTransform(SVGTransformType, ConstructionMode = ConstructIdentityTransform); - explicit SVGTransform(const AffineTransform&); - - SVGTransformType type() const { return m_type; } - - SVGMatrix& svgMatrix() { return static_cast<SVGMatrix&>(m_matrix); } - AffineTransform matrix() const { return m_matrix; } - void updateSVGMatrix(); - - float angle() const { return m_angle; } - FloatPoint rotationCenter() const { return m_center; } - - void setMatrix(const AffineTransform&); - void setTranslate(float tx, float ty); - void setScale(float sx, float sy); - void setRotate(float angle, float cx, float cy); - void setSkewX(float angle); - void setSkewY(float angle); - - // Internal use only (animation system) - FloatPoint translate() const; - FloatSize scale() const; - - bool isValid() const { return m_type != SVG_TRANSFORM_UNKNOWN; } - String valueAsString() const; - - static const String& transformTypePrefixForParsing(SVGTransformType); + static Ref<SVGTransform> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGTransformValue& value) + { + return adoptRef(*new SVGTransform(animatedProperty, role, value)); + } -private: - friend bool operator==(const SVGTransform& a, const SVGTransform& b); + static Ref<SVGTransform> create(const SVGTransformValue& initialValue = { }) + { + return adoptRef(*new SVGTransform(initialValue)); + } - SVGTransformType m_type; - float m_angle; - FloatPoint m_center; - AffineTransform m_matrix; -}; + static Ref<SVGTransform> create(const SVGTransformValue* initialValue) + { + return adoptRef(*new SVGTransform(initialValue)); + } -inline bool operator==(const SVGTransform& a, const SVGTransform& b) -{ - return a.m_type == b.m_type && a.m_angle == b.m_angle && a.m_matrix == b.m_matrix; -} + template<typename T> static ExceptionOr<Ref<SVGTransform>> create(ExceptionOr<T>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } -inline bool operator!=(const SVGTransform& a, const SVGTransform& b) -{ - return !(a == b); -} + unsigned short type() + { + return propertyReference().type(); + } -} // namespace WebCore + Ref<SVGMatrix> matrix(); + + float angle() + { + return propertyReference().angle(); + } + + ExceptionOr<void> setMatrix(SVGMatrix& matrix) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setMatrix(matrix.propertyReference()); + commitChange(); + + return { }; + } + + ExceptionOr<void> setTranslate(float tx, float ty) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setTranslate(tx, ty); + commitChange(); + + return { }; + } + + ExceptionOr<void> setScale(float sx, float sy) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setScale(sx, sy); + commitChange(); -#endif // ENABLE(SVG) -#endif + return { }; + } + + ExceptionOr<void> setRotate(float angle, float cx, float cy) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setRotate(angle, cx, cy); + commitChange(); + + return { }; + } + + ExceptionOr<void> setSkewX(float angle) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setSkewX(angle); + commitChange(); + + return { }; + } + + ExceptionOr<void> setSkewY(float angle) + { + if (isReadOnly()) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; + + propertyReference().setSkewY(angle); + commitChange(); + + return { }; + } + +private: + SVGTransform(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, SVGTransformValue& value) + : SVGPropertyTearOff<SVGTransformValue>(&animatedProperty, role, value) + { + } + + explicit SVGTransform(const SVGTransformValue& initialValue) + : SVGPropertyTearOff<SVGTransformValue>(initialValue) + { + } + + explicit SVGTransform(const SVGTransformValue* initialValue) + : SVGPropertyTearOff<SVGTransformValue>(initialValue) + { + } +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGTransform.idl b/Source/WebCore/svg/SVGTransform.idl index 525041eb8..119740593 100644 --- a/Source/WebCore/svg/SVGTransform.idl +++ b/Source/WebCore/svg/SVGTransform.idl @@ -20,7 +20,7 @@ */ [ - Conditional=SVG, + ConstantsScope=SVGTransformValue ] interface SVGTransform { // Transform Types const unsigned short SVG_TRANSFORM_UNKNOWN = 0; @@ -32,14 +32,14 @@ const unsigned short SVG_TRANSFORM_SKEWY = 6; readonly attribute unsigned short type; - [ImplementedAs=svgMatrix] readonly attribute SVGMatrix matrix; - readonly attribute float angle; + [NewObject] readonly attribute SVGMatrix matrix; + readonly attribute unrestricted float angle; - [StrictTypeChecking] void setMatrix(SVGMatrix matrix); - [StrictTypeChecking] void setTranslate(float tx, float ty); - [StrictTypeChecking] void setScale(float sx, float sy); - [StrictTypeChecking] void setRotate(float angle, float cx, float cy); - [StrictTypeChecking] void setSkewX(float angle); - [StrictTypeChecking] void setSkewY(float angle); + [MayThrowException] void setMatrix(SVGMatrix matrix); + [MayThrowException] void setTranslate(unrestricted float tx, unrestricted float ty); + [MayThrowException] void setScale(unrestricted float sx, unrestricted float sy); + [MayThrowException] void setRotate(unrestricted float angle, unrestricted float cx, unrestricted float cy); + [MayThrowException] void setSkewX(unrestricted float angle); + [MayThrowException] void setSkewY(unrestricted float angle); }; diff --git a/Source/WebCore/svg/SVGTransformDistance.cpp b/Source/WebCore/svg/SVGTransformDistance.cpp index 85b3a27a8..04f08358d 100644 --- a/Source/WebCore/svg/SVGTransformDistance.cpp +++ b/Source/WebCore/svg/SVGTransformDistance.cpp @@ -18,27 +18,26 @@ */ #include "config.h" -#if ENABLE(SVG) #include "SVGTransformDistance.h" #include "FloatConversion.h" #include "FloatPoint.h" #include "FloatSize.h" -#include "SVGTransform.h" +#include "SVGTransformValue.h" #include <math.h> namespace WebCore { SVGTransformDistance::SVGTransformDistance() - : m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN) + : m_type(SVGTransformValue::SVG_TRANSFORM_UNKNOWN) , m_angle(0) , m_cx(0) , m_cy(0) { } -SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, float angle, float cx, float cy, const AffineTransform& transform) +SVGTransformDistance::SVGTransformDistance(SVGTransformValue::SVGTransformType type, float angle, float cx, float cy, const AffineTransform& transform) : m_type(type) , m_angle(angle) , m_cx(cx) @@ -47,7 +46,7 @@ SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, { } -SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, const SVGTransform& toSVGTransform) +SVGTransformDistance::SVGTransformDistance(const SVGTransformValue& fromSVGTransform, const SVGTransformValue& toSVGTransform) : m_type(fromSVGTransform.type()) , m_angle(0) , m_cx(0) @@ -56,33 +55,33 @@ SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, ASSERT(m_type == toSVGTransform.type()); switch (m_type) { - case SVGTransform::SVG_TRANSFORM_MATRIX: + case SVGTransformValue::SVG_TRANSFORM_MATRIX: ASSERT_NOT_REACHED(); #if ASSERT_DISABLED FALLTHROUGH; #endif - case SVGTransform::SVG_TRANSFORM_UNKNOWN: + case SVGTransformValue::SVG_TRANSFORM_UNKNOWN: break; - case SVGTransform::SVG_TRANSFORM_ROTATE: { + case SVGTransformValue::SVG_TRANSFORM_ROTATE: { FloatSize centerDistance = toSVGTransform.rotationCenter() - fromSVGTransform.rotationCenter(); m_angle = toSVGTransform.angle() - fromSVGTransform.angle(); m_cx = centerDistance.width(); m_cy = centerDistance.height(); break; } - case SVGTransform::SVG_TRANSFORM_TRANSLATE: { + case SVGTransformValue::SVG_TRANSFORM_TRANSLATE: { FloatSize translationDistance = toSVGTransform.translate() - fromSVGTransform.translate(); m_transform.translate(translationDistance.width(), translationDistance.height()); break; } - case SVGTransform::SVG_TRANSFORM_SCALE: { + case SVGTransformValue::SVG_TRANSFORM_SCALE: { float scaleX = toSVGTransform.scale().width() - fromSVGTransform.scale().width(); float scaleY = toSVGTransform.scale().height() - fromSVGTransform.scale().height(); m_transform.scaleNonUniform(scaleX, scaleY); break; } - case SVGTransform::SVG_TRANSFORM_SKEWX: - case SVGTransform::SVG_TRANSFORM_SKEWY: + case SVGTransformValue::SVG_TRANSFORM_SKEWX: + case SVGTransformValue::SVG_TRANSFORM_SKEWY: m_angle = toSVGTransform.angle() - fromSVGTransform.angle(); break; } @@ -91,25 +90,25 @@ SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, SVGTransformDistance SVGTransformDistance::scaledDistance(float scaleFactor) const { switch (m_type) { - case SVGTransform::SVG_TRANSFORM_MATRIX: + case SVGTransformValue::SVG_TRANSFORM_MATRIX: ASSERT_NOT_REACHED(); #if ASSERT_DISABLED FALLTHROUGH; #endif - case SVGTransform::SVG_TRANSFORM_UNKNOWN: + case SVGTransformValue::SVG_TRANSFORM_UNKNOWN: return SVGTransformDistance(); - case SVGTransform::SVG_TRANSFORM_ROTATE: + case SVGTransformValue::SVG_TRANSFORM_ROTATE: return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform()); - case SVGTransform::SVG_TRANSFORM_SCALE: + case SVGTransformValue::SVG_TRANSFORM_SCALE: return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor)); - case SVGTransform::SVG_TRANSFORM_TRANSLATE: { + case SVGTransformValue::SVG_TRANSFORM_TRANSLATE: { AffineTransform newTransform(m_transform); newTransform.setE(m_transform.e() * scaleFactor); newTransform.setF(m_transform.f() * scaleFactor); return SVGTransformDistance(m_type, 0, 0, 0, newTransform); } - case SVGTransform::SVG_TRANSFORM_SKEWX: - case SVGTransform::SVG_TRANSFORM_SKEWY: + case SVGTransformValue::SVG_TRANSFORM_SKEWX: + case SVGTransformValue::SVG_TRANSFORM_SKEWY: return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform()); } @@ -117,89 +116,89 @@ SVGTransformDistance SVGTransformDistance::scaledDistance(float scaleFactor) con return SVGTransformDistance(); } -SVGTransform SVGTransformDistance::addSVGTransforms(const SVGTransform& first, const SVGTransform& second, unsigned repeatCount) +SVGTransformValue SVGTransformDistance::addSVGTransforms(const SVGTransformValue& first, const SVGTransformValue& second, unsigned repeatCount) { ASSERT(first.type() == second.type()); - SVGTransform transform; + SVGTransformValue transform; switch (first.type()) { - case SVGTransform::SVG_TRANSFORM_MATRIX: + case SVGTransformValue::SVG_TRANSFORM_MATRIX: ASSERT_NOT_REACHED(); #if ASSERT_DISABLED FALLTHROUGH; #endif - case SVGTransform::SVG_TRANSFORM_UNKNOWN: - return SVGTransform(); - case SVGTransform::SVG_TRANSFORM_ROTATE: { + case SVGTransformValue::SVG_TRANSFORM_UNKNOWN: + return { }; + case SVGTransformValue::SVG_TRANSFORM_ROTATE: { transform.setRotate(first.angle() + second.angle() * repeatCount, first.rotationCenter().x() + second.rotationCenter().x() * repeatCount, first.rotationCenter().y() + second.rotationCenter().y() * repeatCount); return transform; } - case SVGTransform::SVG_TRANSFORM_TRANSLATE: { + case SVGTransformValue::SVG_TRANSFORM_TRANSLATE: { float dx = first.translate().x() + second.translate().x() * repeatCount; float dy = first.translate().y() + second.translate().y() * repeatCount; transform.setTranslate(dx, dy); return transform; } - case SVGTransform::SVG_TRANSFORM_SCALE: { + case SVGTransformValue::SVG_TRANSFORM_SCALE: { FloatSize scale = second.scale(); scale.scale(repeatCount); scale += first.scale(); transform.setScale(scale.width(), scale.height()); return transform; } - case SVGTransform::SVG_TRANSFORM_SKEWX: + case SVGTransformValue::SVG_TRANSFORM_SKEWX: transform.setSkewX(first.angle() + second.angle() * repeatCount); return transform; - case SVGTransform::SVG_TRANSFORM_SKEWY: + case SVGTransformValue::SVG_TRANSFORM_SKEWY: transform.setSkewY(first.angle() + second.angle() * repeatCount); return transform; } ASSERT_NOT_REACHED(); - return SVGTransform(); + return { }; } -SVGTransform SVGTransformDistance::addToSVGTransform(const SVGTransform& transform) const +SVGTransformValue SVGTransformDistance::addToSVGTransform(const SVGTransformValue& transform) const { - ASSERT(m_type == transform.type() || transform == SVGTransform()); + ASSERT(m_type == transform.type() || transform == SVGTransformValue()); - SVGTransform newTransform(transform); + SVGTransformValue newTransform(transform); switch (m_type) { - case SVGTransform::SVG_TRANSFORM_MATRIX: + case SVGTransformValue::SVG_TRANSFORM_MATRIX: ASSERT_NOT_REACHED(); #if ASSERT_DISABLED FALLTHROUGH; #endif - case SVGTransform::SVG_TRANSFORM_UNKNOWN: - return SVGTransform(); - case SVGTransform::SVG_TRANSFORM_TRANSLATE: { + case SVGTransformValue::SVG_TRANSFORM_UNKNOWN: + return { }; + case SVGTransformValue::SVG_TRANSFORM_TRANSLATE: { FloatPoint translation = transform.translate(); translation += FloatSize::narrowPrecision(m_transform.e(), m_transform.f()); newTransform.setTranslate(translation.x(), translation.y()); return newTransform; } - case SVGTransform::SVG_TRANSFORM_SCALE: { + case SVGTransformValue::SVG_TRANSFORM_SCALE: { FloatSize scale = transform.scale(); scale += FloatSize::narrowPrecision(m_transform.a(), m_transform.d()); newTransform.setScale(scale.width(), scale.height()); return newTransform; } - case SVGTransform::SVG_TRANSFORM_ROTATE: { + case SVGTransformValue::SVG_TRANSFORM_ROTATE: { FloatPoint center = transform.rotationCenter(); newTransform.setRotate(transform.angle() + m_angle, center.x() + m_cx, center.y() + m_cy); return newTransform; } - case SVGTransform::SVG_TRANSFORM_SKEWX: + case SVGTransformValue::SVG_TRANSFORM_SKEWX: newTransform.setSkewX(transform.angle() + m_angle); return newTransform; - case SVGTransform::SVG_TRANSFORM_SKEWY: + case SVGTransformValue::SVG_TRANSFORM_SKEWY: newTransform.setSkewY(transform.angle() + m_angle); return newTransform; } ASSERT_NOT_REACHED(); - return SVGTransform(); + return { }; } bool SVGTransformDistance::isZero() const @@ -210,21 +209,21 @@ bool SVGTransformDistance::isZero() const float SVGTransformDistance::distance() const { switch (m_type) { - case SVGTransform::SVG_TRANSFORM_MATRIX: + case SVGTransformValue::SVG_TRANSFORM_MATRIX: ASSERT_NOT_REACHED(); #if ASSERT_DISABLED FALLTHROUGH; #endif - case SVGTransform::SVG_TRANSFORM_UNKNOWN: + case SVGTransformValue::SVG_TRANSFORM_UNKNOWN: return 0; - case SVGTransform::SVG_TRANSFORM_ROTATE: + case SVGTransformValue::SVG_TRANSFORM_ROTATE: return sqrtf(m_angle * m_angle + m_cx * m_cx + m_cy * m_cy); - case SVGTransform::SVG_TRANSFORM_SCALE: + case SVGTransformValue::SVG_TRANSFORM_SCALE: return static_cast<float>(sqrt(m_transform.a() * m_transform.a() + m_transform.d() * m_transform.d())); - case SVGTransform::SVG_TRANSFORM_TRANSLATE: + case SVGTransformValue::SVG_TRANSFORM_TRANSLATE: return static_cast<float>(sqrt(m_transform.e() * m_transform.e() + m_transform.f() * m_transform.f())); - case SVGTransform::SVG_TRANSFORM_SKEWX: - case SVGTransform::SVG_TRANSFORM_SKEWY: + case SVGTransformValue::SVG_TRANSFORM_SKEWX: + case SVGTransformValue::SVG_TRANSFORM_SKEWY: return m_angle; } ASSERT_NOT_REACHED(); @@ -232,5 +231,3 @@ float SVGTransformDistance::distance() const } } - -#endif diff --git a/Source/WebCore/svg/SVGTransformDistance.h b/Source/WebCore/svg/SVGTransformDistance.h index 7ab58593f..e336dd07b 100644 --- a/Source/WebCore/svg/SVGTransformDistance.h +++ b/Source/WebCore/svg/SVGTransformDistance.h @@ -17,11 +17,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTransformDistance_h -#define SVGTransformDistance_h -#if ENABLE(SVG) +#pragma once -#include "SVGTransform.h" +#include "SVGTransformValue.h" namespace WebCore { @@ -30,26 +28,24 @@ class AffineTransform; class SVGTransformDistance { public: SVGTransformDistance(); - SVGTransformDistance(const SVGTransform& fromTransform, const SVGTransform& toTransform); + SVGTransformDistance(const SVGTransformValue& fromTransform, const SVGTransformValue& toTransform); SVGTransformDistance scaledDistance(float scaleFactor) const; - SVGTransform addToSVGTransform(const SVGTransform&) const; + SVGTransformValue addToSVGTransform(const SVGTransformValue&) const; - static SVGTransform addSVGTransforms(const SVGTransform&, const SVGTransform&, unsigned repeatCount = 1); + static SVGTransformValue addSVGTransforms(const SVGTransformValue&, const SVGTransformValue&, unsigned repeatCount = 1); bool isZero() const; float distance() const; private: - SVGTransformDistance(SVGTransform::SVGTransformType, float angle, float cx, float cy, const AffineTransform&); + SVGTransformDistance(SVGTransformValue::SVGTransformType, float angle, float cx, float cy, const AffineTransform&); - SVGTransform::SVGTransformType m_type; + SVGTransformValue::SVGTransformType m_type; float m_angle; float m_cx; float m_cy; AffineTransform m_transform; // for storing scale, translation or matrix transforms }; -} -#endif // ENABLE(SVG) -#endif // SVGTransformDistance_h +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGTransformList.h b/Source/WebCore/svg/SVGTransformList.h index 14aba3bf4..d329fd38b 100644 --- a/Source/WebCore/svg/SVGTransformList.h +++ b/Source/WebCore/svg/SVGTransformList.h @@ -18,38 +18,60 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTransformList_h -#define SVGTransformList_h +#pragma once -#if ENABLE(SVG) -#include "SVGPropertyTraits.h" -#include "SVGTransform.h" -#include <wtf/Vector.h> +#include "SVGAnimatedListPropertyTearOff.h" +#include "SVGListPropertyTearOff.h" +#include "SVGTransformListValues.h" namespace WebCore { -class SVGTransformList : public Vector<SVGTransform> { +class SVGTransformList final : public SVGListPropertyTearOff<SVGTransformListValues> { public: - SVGTransformList() { } + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<SVGTransformListValues>; + using ListWrapperCache = AnimatedListPropertyTearOff::ListWrapperCache; - SVGTransform createSVGTransformFromMatrix(const SVGMatrix&) const; - SVGTransform consolidate(); + static Ref<SVGTransformList> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGTransformListValues& values, ListWrapperCache& wrappers) + { + return adoptRef(*new SVGTransformList(animatedProperty, role, values, wrappers)); + } - // Internal use only - bool concatenate(AffineTransform& result) const; - - String valueAsString() const; - void parse(const String&); -}; + ExceptionOr<Ref<SVGTransform>> createSVGTransformFromMatrix(SVGMatrix& matrix) + { + ASSERT(m_values); + return m_values->createSVGTransformFromMatrix(matrix); + } + + ExceptionOr<RefPtr<SVGTransform>> consolidate() + { + ASSERT(m_values); + ASSERT(m_wrappers); + + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); + + ASSERT(m_values->size() == m_wrappers->size()); -template<> -struct SVGPropertyTraits<SVGTransformList> { - static SVGTransformList initialValue() { return SVGTransformList(); } - static String toString(const SVGTransformList& type) { return type.valueAsString(); } - typedef SVGTransform ListItemType; + // Spec: If the list was empty, then a value of null is returned. + if (m_values->isEmpty()) + return nullptr; + + detachListWrappers(0); + + RefPtr<SVGTransform> wrapper = m_values->consolidate(); + m_wrappers->append(wrapper.get()); + + ASSERT(m_values->size() == m_wrappers->size()); + return WTFMove(wrapper); + } + +private: + SVGTransformList(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, SVGTransformListValues& values, ListWrapperCache& wrappers) + : SVGListPropertyTearOff<SVGTransformListValues>(animatedProperty, role, values, wrappers) + { + } }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGTransformList_h diff --git a/Source/WebCore/svg/SVGTransformList.idl b/Source/WebCore/svg/SVGTransformList.idl index 2d3f9041f..3e81d62a3 100644 --- a/Source/WebCore/svg/SVGTransformList.idl +++ b/Source/WebCore/svg/SVGTransformList.idl @@ -24,21 +24,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG, -] interface SVGTransformList { +interface SVGTransformList { readonly attribute unsigned long numberOfItems; - [RaisesException] void clear(); - [StrictTypeChecking, RaisesException] SVGTransform initialize(SVGTransform item); - [StrictTypeChecking, RaisesException] SVGTransform getItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGTransform insertItemBefore(SVGTransform item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGTransform replaceItem(SVGTransform item, unsigned long index); - [StrictTypeChecking, RaisesException] SVGTransform removeItem(unsigned long index); - [StrictTypeChecking, RaisesException] SVGTransform appendItem(SVGTransform item); + [MayThrowException] void clear(); + [MayThrowException] SVGTransform initialize(SVGTransform item); + [MayThrowException] SVGTransform getItem(unsigned long index); + [MayThrowException] SVGTransform insertItemBefore(SVGTransform item, unsigned long index); + [MayThrowException] SVGTransform replaceItem(SVGTransform item, unsigned long index); + [MayThrowException] SVGTransform removeItem(unsigned long index); + [MayThrowException] SVGTransform appendItem(SVGTransform item); - [StrictTypeChecking, RaisesException] SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix); - - [RaisesException] SVGTransform consolidate(); + [MayThrowException, NewObject] SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix); + [MayThrowException, NewObject] SVGTransform consolidate(); }; - diff --git a/Source/WebCore/svg/SVGTransformList.cpp b/Source/WebCore/svg/SVGTransformListValues.cpp index dfab122d4..25b3c316f 100644 --- a/Source/WebCore/svg/SVGTransformList.cpp +++ b/Source/WebCore/svg/SVGTransformListValues.cpp @@ -19,36 +19,33 @@ */ #include "config.h" - -#if ENABLE(SVG) -#include "SVGTransformList.h" +#include "SVGTransformListValues.h" #include "AffineTransform.h" #include "SVGSVGElement.h" -#include "SVGTransform.h" #include "SVGTransformable.h" #include <wtf/text/StringBuilder.h> namespace WebCore { -SVGTransform SVGTransformList::createSVGTransformFromMatrix(const SVGMatrix& matrix) const +Ref<SVGTransform> SVGTransformListValues::createSVGTransformFromMatrix(SVGMatrix& matrix) const { return SVGSVGElement::createSVGTransformFromMatrix(matrix); } -SVGTransform SVGTransformList::consolidate() +Ref<SVGTransform> SVGTransformListValues::consolidate() { AffineTransform matrix; if (!concatenate(matrix)) - return SVGTransform(); + return SVGTransform::create(); - SVGTransform transform(matrix); + SVGTransformValue transform(matrix); clear(); append(transform); - return transform; + return SVGTransform::create(transform); } -bool SVGTransformList::concatenate(AffineTransform& result) const +bool SVGTransformListValues::concatenate(AffineTransform& result) const { unsigned size = this->size(); if (!size) @@ -60,7 +57,7 @@ bool SVGTransformList::concatenate(AffineTransform& result) const return true; } -String SVGTransformList::valueAsString() const +String SVGTransformListValues::valueAsString() const { StringBuilder builder; unsigned size = this->size(); @@ -74,13 +71,12 @@ String SVGTransformList::valueAsString() const return builder.toString(); } -void SVGTransformList::parse(const String& transform) +void SVGTransformListValues::parse(const String& transform) { - const UChar* start = transform.deprecatedCharacters(); + auto upconvertedCharacters = StringView(transform).upconvertedCharacters(); + const UChar* start = upconvertedCharacters; if (!SVGTransformable::parseTransformAttribute(*this, start, start + transform.length())) clear(); } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTransformListValues.h b/Source/WebCore/svg/SVGTransformListValues.h new file mode 100644 index 000000000..29407628e --- /dev/null +++ b/Source/WebCore/svg/SVGTransformListValues.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005 Rob Buis <buis@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. + */ + +#pragma once + +#include "SVGPropertyTraits.h" +#include "SVGTransform.h" +#include <wtf/Vector.h> + +namespace WebCore { + +template<typename T> +class SVGListPropertyTearOff; + +class SVGTransformList; + +class SVGTransformListValues final : public Vector<SVGTransformValue, 1> { +public: + Ref<SVGTransform> createSVGTransformFromMatrix(SVGMatrix&) const; + Ref<SVGTransform> consolidate(); + + bool concatenate(AffineTransform& result) const; + + String valueAsString() const; + void parse(const String&); +}; + +template<> struct SVGPropertyTraits<SVGTransformListValues> { + static SVGTransformListValues initialValue() { return { }; } + static String toString(const SVGTransformListValues& list) { return list.valueAsString(); } + + using ListItemType = SVGTransformValue; + using ListItemTearOff = SVGTransform; + using ListPropertyTearOff = SVGTransformList; +}; + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGTransformValue.cpp b/Source/WebCore/svg/SVGTransformValue.cpp new file mode 100644 index 000000000..4f94fe498 --- /dev/null +++ b/Source/WebCore/svg/SVGTransformValue.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005 Rob Buis <buis@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. + */ + +#include "config.h" +#include "SVGTransformValue.h" + +#include "FloatConversion.h" +#include "FloatPoint.h" +#include "FloatSize.h" +#include <wtf/MathExtras.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +SVGTransformValue::SVGTransformValue() +{ +} + +SVGTransformValue::SVGTransformValue(SVGTransformType type, ConstructionMode mode) + : m_type(type) +{ + if (mode == ConstructZeroTransform) + m_matrix = AffineTransform(0, 0, 0, 0, 0, 0); +} + +SVGTransformValue::SVGTransformValue(const AffineTransform& matrix) + : m_type(SVG_TRANSFORM_MATRIX) + , m_matrix(matrix) +{ +} + +void SVGTransformValue::setMatrix(const AffineTransform& matrix) +{ + m_type = SVG_TRANSFORM_MATRIX; + m_angle = 0; + m_matrix = matrix; +} + +void SVGTransformValue::updateSVGMatrix() +{ + // The underlying matrix has been changed, alter the transformation type. + // Spec: In case the matrix object is changed directly (i.e., without using the methods on the SVGTransform interface itself) + // then the type of the SVGTransform changes to SVG_TRANSFORM_MATRIX. + m_type = SVG_TRANSFORM_MATRIX; + m_angle = 0; +} + +void SVGTransformValue::setTranslate(float tx, float ty) +{ + m_type = SVG_TRANSFORM_TRANSLATE; + m_angle = 0; + + m_matrix.makeIdentity(); + m_matrix.translate(tx, ty); +} + +FloatPoint SVGTransformValue::translate() const +{ + return FloatPoint::narrowPrecision(m_matrix.e(), m_matrix.f()); +} + +void SVGTransformValue::setScale(float sx, float sy) +{ + m_type = SVG_TRANSFORM_SCALE; + m_angle = 0; + m_center = FloatPoint(); + + m_matrix.makeIdentity(); + m_matrix.scaleNonUniform(sx, sy); +} + +FloatSize SVGTransformValue::scale() const +{ + return FloatSize::narrowPrecision(m_matrix.a(), m_matrix.d()); +} + +void SVGTransformValue::setRotate(float angle, float cx, float cy) +{ + m_type = SVG_TRANSFORM_ROTATE; + m_angle = angle; + m_center = FloatPoint(cx, cy); + + // TODO: toString() implementation, which can show cx, cy (need to be stored?) + m_matrix.makeIdentity(); + m_matrix.translate(cx, cy); + m_matrix.rotate(angle); + m_matrix.translate(-cx, -cy); +} + +void SVGTransformValue::setSkewX(float angle) +{ + m_type = SVG_TRANSFORM_SKEWX; + m_angle = angle; + + m_matrix.makeIdentity(); + m_matrix.skewX(angle); +} + +void SVGTransformValue::setSkewY(float angle) +{ + m_type = SVG_TRANSFORM_SKEWY; + m_angle = angle; + + m_matrix.makeIdentity(); + m_matrix.skewY(angle); +} + +const String& SVGTransformValue::transformTypePrefixForParsing(SVGTransformType type) +{ + switch (type) { + case SVG_TRANSFORM_UNKNOWN: + return emptyString(); + case SVG_TRANSFORM_MATRIX: { + static NeverDestroyed<String> matrixString(ASCIILiteral("matrix(")); + return matrixString; + } + case SVG_TRANSFORM_TRANSLATE: { + static NeverDestroyed<String> translateString(ASCIILiteral("translate(")); + return translateString; + } + case SVG_TRANSFORM_SCALE: { + static NeverDestroyed<String> scaleString(ASCIILiteral("scale(")); + return scaleString; + } + case SVG_TRANSFORM_ROTATE: { + static NeverDestroyed<String> rotateString(ASCIILiteral("rotate(")); + return rotateString; + } + case SVG_TRANSFORM_SKEWX: { + static NeverDestroyed<String> skewXString(ASCIILiteral("skewX(")); + return skewXString; + } + case SVG_TRANSFORM_SKEWY: { + static NeverDestroyed<String> skewYString(ASCIILiteral("skewY(")); + return skewYString; + } + } + + ASSERT_NOT_REACHED(); + return emptyString(); +} + +String SVGTransformValue::valueAsString() const +{ + const String& prefix = transformTypePrefixForParsing(m_type); + switch (m_type) { + case SVG_TRANSFORM_UNKNOWN: + return prefix; + case SVG_TRANSFORM_MATRIX: { + StringBuilder builder; + builder.append(prefix); + builder.appendNumber(m_matrix.a()); + builder.append(' '); + builder.appendNumber(m_matrix.b()); + builder.append(' '); + builder.appendNumber(m_matrix.c()); + builder.append(' '); + builder.appendNumber(m_matrix.d()); + builder.append(' '); + builder.appendNumber(m_matrix.e()); + builder.append(' '); + builder.appendNumber(m_matrix.f()); + builder.append(')'); + return builder.toString(); + } + case SVG_TRANSFORM_TRANSLATE: { + StringBuilder builder; + builder.append(prefix); + builder.appendNumber(m_matrix.e()); + builder.append(' '); + builder.appendNumber(m_matrix.f()); + builder.append(')'); + return builder.toString(); + } + case SVG_TRANSFORM_SCALE: { + StringBuilder builder; + builder.append(prefix); + builder.appendNumber(m_matrix.xScale()); + builder.append(' '); + builder.appendNumber(m_matrix.yScale()); + builder.append(')'); + return builder.toString(); + } + case SVG_TRANSFORM_ROTATE: { + double angleInRad = deg2rad(m_angle); + double cosAngle = std::cos(angleInRad); + double sinAngle = std::sin(angleInRad); + float cx = narrowPrecisionToFloat(cosAngle != 1 ? (m_matrix.e() * (1 - cosAngle) - m_matrix.f() * sinAngle) / (1 - cosAngle) / 2 : 0); + float cy = narrowPrecisionToFloat(cosAngle != 1 ? (m_matrix.e() * sinAngle / (1 - cosAngle) + m_matrix.f()) / 2 : 0); + StringBuilder builder; + builder.append(prefix); + builder.appendNumber(m_angle); + if (cx || cy) { + builder.append(' '); + builder.appendNumber(cx); + builder.append(' '); + builder.appendNumber(cy); + } + builder.append(')'); + return builder.toString(); + } + case SVG_TRANSFORM_SKEWX: + case SVG_TRANSFORM_SKEWY: { + StringBuilder builder; + builder.append(prefix); + builder.appendNumber(m_angle); + builder.append(')'); + return builder.toString(); + } + } + + ASSERT_NOT_REACHED(); + return emptyString(); +} + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGTransformValue.h b/Source/WebCore/svg/SVGTransformValue.h new file mode 100644 index 000000000..fadd03a23 --- /dev/null +++ b/Source/WebCore/svg/SVGTransformValue.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2004, 2005 Rob Buis <buis@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. + */ + +#pragma once + +#include "FloatPoint.h" +#include "SVGMatrixValue.h" + +namespace WebCore { + +class FloatSize; + +class SVGTransformValue { +public: + enum SVGTransformType { + SVG_TRANSFORM_UNKNOWN = 0, + SVG_TRANSFORM_MATRIX = 1, + SVG_TRANSFORM_TRANSLATE = 2, + SVG_TRANSFORM_SCALE = 3, + SVG_TRANSFORM_ROTATE = 4, + SVG_TRANSFORM_SKEWX = 5, + SVG_TRANSFORM_SKEWY = 6 + }; + + enum ConstructionMode { + ConstructIdentityTransform, + ConstructZeroTransform + }; + + SVGTransformValue(); + SVGTransformValue(SVGTransformType, ConstructionMode = ConstructIdentityTransform); + explicit SVGTransformValue(const AffineTransform&); + + SVGTransformType type() const { return m_type; } + + SVGMatrixValue& svgMatrix() { return static_cast<SVGMatrixValue&>(m_matrix); } + AffineTransform matrix() const { return m_matrix; } + void updateSVGMatrix(); + + float angle() const { return m_angle; } + FloatPoint rotationCenter() const { return m_center; } + + void setMatrix(const AffineTransform&); + void setTranslate(float tx, float ty); + void setScale(float sx, float sy); + void setRotate(float angle, float cx, float cy); + void setSkewX(float angle); + void setSkewY(float angle); + + FloatPoint translate() const; + FloatSize scale() const; + + bool isValid() const { return m_type != SVG_TRANSFORM_UNKNOWN; } + String valueAsString() const; + + static const String& transformTypePrefixForParsing(SVGTransformType); + +private: + friend bool operator==(const SVGTransformValue&, const SVGTransformValue&); + + SVGTransformType m_type { SVG_TRANSFORM_UNKNOWN }; + float m_angle { 0 }; + FloatPoint m_center; + AffineTransform m_matrix; +}; + +inline bool operator==(const SVGTransformValue& a, const SVGTransformValue& b) +{ + return a.m_type == b.m_type && a.m_angle == b.m_angle && a.m_matrix == b.m_matrix; +} + +inline bool operator!=(const SVGTransformValue& a, const SVGTransformValue& b) +{ + return !(a == b); +} + +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGTransformable.cpp b/Source/WebCore/svg/SVGTransformable.cpp index fb8ff8866..ea048528b 100644 --- a/Source/WebCore/svg/SVGTransformable.cpp +++ b/Source/WebCore/svg/SVGTransformable.cpp @@ -20,8 +20,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTransformable.h" #include "AffineTransform.h" @@ -29,7 +27,8 @@ #include "SVGElement.h" #include "SVGNames.h" #include "SVGParserUtilities.h" -#include "SVGTransformList.h" +#include "SVGTransformListValues.h" +#include <wtf/text/StringView.h> namespace WebCore { @@ -94,9 +93,9 @@ SVGTransformable::~SVGTransformable() { } -bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& transform) +bool SVGTransformable::parseTransformValue(SVGTransformValue::SVGTransformType type, const UChar*& ptr, const UChar* end, SVGTransformValue& transform) { - if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN) + if (type == SVGTransformValue::SVG_TRANSFORM_UNKNOWN) return false; int valueCount = 0; @@ -105,31 +104,34 @@ bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, con return false; switch (type) { - case SVGTransform::SVG_TRANSFORM_SKEWX: + case SVGTransformValue::SVG_TRANSFORM_UNKNOWN: + ASSERT_NOT_REACHED(); + break; + case SVGTransformValue::SVG_TRANSFORM_SKEWX: transform.setSkewX(values[0]); break; - case SVGTransform::SVG_TRANSFORM_SKEWY: + case SVGTransformValue::SVG_TRANSFORM_SKEWY: transform.setSkewY(values[0]); break; - case SVGTransform::SVG_TRANSFORM_SCALE: + case SVGTransformValue::SVG_TRANSFORM_SCALE: if (valueCount == 1) // Spec: if only one param given, assume uniform scaling transform.setScale(values[0], values[0]); else transform.setScale(values[0], values[1]); break; - case SVGTransform::SVG_TRANSFORM_TRANSLATE: + case SVGTransformValue::SVG_TRANSFORM_TRANSLATE: if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0 transform.setTranslate(values[0], 0); else transform.setTranslate(values[0], values[1]); break; - case SVGTransform::SVG_TRANSFORM_ROTATE: + case SVGTransformValue::SVG_TRANSFORM_ROTATE: if (valueCount == 1) transform.setRotate(values[0], 0, 0); else transform.setRotate(values[0], values[1], values[2]); break; - case SVGTransform::SVG_TRANSFORM_MATRIX: + case SVGTransformValue::SVG_TRANSFORM_MATRIX: transform.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5])); break; } @@ -144,41 +146,42 @@ static const UChar translateDesc[] = {'t', 'r', 'a', 'n', 's', 'l', 'a', 't', ' static const UChar rotateDesc[] = {'r', 'o', 't', 'a', 't', 'e'}; static const UChar matrixDesc[] = {'m', 'a', 't', 'r', 'i', 'x'}; -static inline bool parseAndSkipType(const UChar*& currTransform, const UChar* end, unsigned short& type) +static inline bool parseAndSkipType(const UChar*& currTransform, const UChar* end, SVGTransformValue::SVGTransformType& type) { if (currTransform >= end) return false; if (*currTransform == 's') { if (skipString(currTransform, end, skewXDesc, WTF_ARRAY_LENGTH(skewXDesc))) - type = SVGTransform::SVG_TRANSFORM_SKEWX; + type = SVGTransformValue::SVG_TRANSFORM_SKEWX; else if (skipString(currTransform, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc))) - type = SVGTransform::SVG_TRANSFORM_SKEWY; + type = SVGTransformValue::SVG_TRANSFORM_SKEWY; else if (skipString(currTransform, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc))) - type = SVGTransform::SVG_TRANSFORM_SCALE; + type = SVGTransformValue::SVG_TRANSFORM_SCALE; else return false; } else if (skipString(currTransform, end, translateDesc, WTF_ARRAY_LENGTH(translateDesc))) - type = SVGTransform::SVG_TRANSFORM_TRANSLATE; + type = SVGTransformValue::SVG_TRANSFORM_TRANSLATE; else if (skipString(currTransform, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc))) - type = SVGTransform::SVG_TRANSFORM_ROTATE; + type = SVGTransformValue::SVG_TRANSFORM_ROTATE; else if (skipString(currTransform, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc))) - type = SVGTransform::SVG_TRANSFORM_MATRIX; + type = SVGTransformValue::SVG_TRANSFORM_MATRIX; else return false; return true; } -SVGTransform::SVGTransformType SVGTransformable::parseTransformType(const String& typeString) +SVGTransformValue::SVGTransformType SVGTransformable::parseTransformType(const String& typeString) { - unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN; - const UChar* characters = typeString.deprecatedCharacters(); + SVGTransformValue::SVGTransformType type = SVGTransformValue::SVG_TRANSFORM_UNKNOWN; + auto upconvertedCharacters = StringView(typeString).upconvertedCharacters(); + const UChar* characters = upconvertedCharacters; parseAndSkipType(characters, characters + typeString.length(), type); - return static_cast<SVGTransform::SVGTransformType>(type); + return type; } -bool SVGTransformable::parseTransformAttribute(SVGTransformList& list, const UChar*& currTransform, const UChar* end, TransformParsingMode mode) +bool SVGTransformable::parseTransformAttribute(SVGTransformListValues& list, const UChar*& currTransform, const UChar* end, TransformParsingMode mode) { if (mode == ClearList) list.clear(); @@ -186,13 +189,13 @@ bool SVGTransformable::parseTransformAttribute(SVGTransformList& list, const UCh bool delimParsed = false; while (currTransform < end) { delimParsed = false; - unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN; + SVGTransformValue::SVGTransformType type = SVGTransformValue::SVG_TRANSFORM_UNKNOWN; skipOptionalSVGSpaces(currTransform, end); if (!parseAndSkipType(currTransform, end, type)) return false; - SVGTransform transform; + SVGTransformValue transform; if (!parseTransformValue(type, currTransform, end, transform)) return false; @@ -209,5 +212,3 @@ bool SVGTransformable::parseTransformAttribute(SVGTransformList& list, const UCh } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGTransformable.h b/Source/WebCore/svg/SVGTransformable.h index be79d1f99..b5e07175a 100644 --- a/Source/WebCore/svg/SVGTransformable.h +++ b/Source/WebCore/svg/SVGTransformable.h @@ -18,20 +18,18 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGTransformable_h -#define SVGTransformable_h +#pragma once -#if ENABLE(SVG) #include "SVGLocatable.h" -#include "SVGTransform.h" +#include "SVGTransformValue.h" #include <wtf/text/WTFString.h> namespace WebCore { class AffineTransform; -class SVGTransformList; +class SVGTransformListValues; -class SVGTransformable : virtual public SVGLocatable { +class SVGTransformable : public SVGLocatable { public: enum TransformParsingMode { ClearList, @@ -40,15 +38,12 @@ public: virtual ~SVGTransformable(); - 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&); - static SVGTransform::SVGTransformType parseTransformType(const String&); + static bool parseTransformAttribute(SVGTransformListValues&, const UChar*& ptr, const UChar* end, TransformParsingMode = ClearList); + static bool parseTransformValue(SVGTransformValue::SVGTransformType, const UChar*& ptr, const UChar* end, SVGTransformValue&); + static SVGTransformValue::SVGTransformType parseTransformType(const String&); - virtual AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const override { return animatedLocalTransform(); } + AffineTransform localCoordinateSpaceTransform(SVGLocatable::CTMScope) const override { return animatedLocalTransform(); } virtual AffineTransform animatedLocalTransform() const = 0; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGTransformable_h diff --git a/Source/WebCore/svg/SVGURIReference.cpp b/Source/WebCore/svg/SVGURIReference.cpp index a667e11d2..0e28196ba 100644 --- a/Source/WebCore/svg/SVGURIReference.cpp +++ b/Source/WebCore/svg/SVGURIReference.cpp @@ -19,11 +19,8 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGURIReference.h" -#include "Attribute.h" #include "Document.h" #include "Element.h" #include "URL.h" @@ -31,14 +28,10 @@ namespace WebCore { -bool SVGURIReference::parseAttribute(const QualifiedName& name, const AtomicString& value) +void SVGURIReference::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (name.matches(XLinkNames::hrefAttr)) { + if (name.matches(XLinkNames::hrefAttr)) setHrefBaseValue(value); - return true; - } - - return false; } bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName) @@ -46,13 +39,13 @@ bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName) return attrName.matches(XLinkNames::hrefAttr); } -String SVGURIReference::fragmentIdentifierFromIRIString(const String& url, Document& document) +String SVGURIReference::fragmentIdentifierFromIRIString(const String& url, const Document& document) { size_t start = url.find('#'); if (start == notFound) return emptyString(); - URL base = start ? URL(document.baseURI(), url.substring(0, start)) : document.baseURI(); + URL base = start ? URL(document.baseURL(), url.substring(0, start)) : document.baseURL(); String fragmentIdentifier = url.substring(start); URL kurl(base, fragmentIdentifier); if (equalIgnoringFragmentIdentifier(kurl, document.url())) @@ -62,7 +55,7 @@ String SVGURIReference::fragmentIdentifierFromIRIString(const String& url, Docum return emptyString(); } -static inline URL urlFromIRIStringWithFragmentIdentifier(const String& url, Document& document, String& fragmentIdentifier) +static inline URL urlFromIRIStringWithFragmentIdentifier(const String& url, const Document& document, String& fragmentIdentifier) { size_t startOfFragmentIdentifier = url.find('#'); if (startOfFragmentIdentifier == notFound) @@ -71,14 +64,14 @@ static inline URL urlFromIRIStringWithFragmentIdentifier(const String& url, Docu // Exclude the '#' character when determining the fragmentIdentifier. fragmentIdentifier = url.substring(startOfFragmentIdentifier + 1); if (startOfFragmentIdentifier) { - URL base(document.baseURI(), url.substring(0, startOfFragmentIdentifier)); + URL base(document.baseURL(), url.substring(0, startOfFragmentIdentifier)); return URL(base, url.substring(startOfFragmentIdentifier)); } - return URL(document.baseURI(), url.substring(startOfFragmentIdentifier)); + return URL(document.baseURL(), url.substring(startOfFragmentIdentifier)); } -Element* SVGURIReference::targetElementFromIRIString(const String& iri, Document& document, String* fragmentIdentifier, Document* externalDocument) +Element* SVGURIReference::targetElementFromIRIString(const String& iri, const Document& document, String* fragmentIdentifier, const Document* externalDocument) { // If there's no fragment identifier contained within the IRI string, we can't lookup an element. String id; @@ -111,5 +104,3 @@ void SVGURIReference::addSupportedAttributes(HashSet<QualifiedName>& supportedAt } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGURIReference.h b/Source/WebCore/svg/SVGURIReference.h index dd956af87..ddd66b27b 100644 --- a/Source/WebCore/svg/SVGURIReference.h +++ b/Source/WebCore/svg/SVGURIReference.h @@ -18,29 +18,25 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGURIReference_h -#define SVGURIReference_h +#pragma once -#if ENABLE(SVG) #include "Document.h" +#include "QualifiedName.h" namespace WebCore { -class Attribute; -class Element; - class SVGURIReference { public: virtual ~SVGURIReference() { } - bool parseAttribute(const QualifiedName&, const AtomicString&); - bool isKnownAttribute(const QualifiedName&); - void addSupportedAttributes(HashSet<QualifiedName>&); + void parseAttribute(const QualifiedName&, const AtomicString&); + static bool isKnownAttribute(const QualifiedName&); + static void addSupportedAttributes(HashSet<QualifiedName>&); - static String fragmentIdentifierFromIRIString(const String&, Document&); - static Element* targetElementFromIRIString(const String&, Document&, String* = 0, Document* = 0); + static String fragmentIdentifierFromIRIString(const String&, const Document&); + static Element* targetElementFromIRIString(const String&, const Document&, String* fragmentIdentifier = nullptr, const Document* externalDocument = nullptr); - static inline bool isExternalURIReference(const String& uri, Document& document) + static bool isExternalURIReference(const String& uri, const Document& document) { // Fragment-only URIs are always internal if (uri.startsWith('#')) @@ -48,14 +44,13 @@ public: // If the URI matches our documents URL, we're dealing with a local reference. URL url = document.completeURL(uri); + ASSERT(!url.protocolIsData()); return !equalIgnoringFragmentIdentifier(url, document.url()); } protected: + virtual String& hrefBaseValue() const = 0; virtual void setHrefBaseValue(const String&, const bool validValue = true) = 0; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGURIReference_h diff --git a/Source/WebCore/svg/SVGURIReference.idl b/Source/WebCore/svg/SVGURIReference.idl index f1ac3922c..0ab024d2b 100644 --- a/Source/WebCore/svg/SVGURIReference.idl +++ b/Source/WebCore/svg/SVGURIReference.idl @@ -26,10 +26,7 @@ [ NoInterfaceObject, - Conditional=SVG, - ObjCProtocol, SuppressToJSObject, ] interface SVGURIReference { readonly attribute SVGAnimatedString href; }; - diff --git a/Source/WebCore/svg/SVGUnitTypes.h b/Source/WebCore/svg/SVGUnitTypes.h index 86e06523b..b0edf7681 100644 --- a/Source/WebCore/svg/SVGUnitTypes.h +++ b/Source/WebCore/svg/SVGUnitTypes.h @@ -17,16 +17,14 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGUnitTypes_h -#define SVGUnitTypes_h +#pragma once -#if ENABLE(SVG) #include "SVGPropertyTraits.h" #include <wtf/RefCounted.h> namespace WebCore { -class SVGUnitTypes : public RefCounted<SVGUnitTypes> { +class SVGUnitTypes final : public RefCounted<SVGUnitTypes> { public: enum SVGUnitType { SVG_UNIT_TYPE_UNKNOWN = 0, @@ -48,9 +46,9 @@ struct SVGPropertyTraits<SVGUnitTypes::SVGUnitType> { case SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN: return emptyString(); case SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE: - return "userSpaceOnUse"; + return ASCIILiteral("userSpaceOnUse"); case SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX: - return "objectBoundingBox"; + return ASCIILiteral("objectBoundingBox"); } ASSERT_NOT_REACHED(); @@ -67,7 +65,4 @@ struct SVGPropertyTraits<SVGUnitTypes::SVGUnitType> { } }; -} - -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/SVGUnitTypes.idl b/Source/WebCore/svg/SVGUnitTypes.idl index c6c055178..32596478b 100644 --- a/Source/WebCore/svg/SVGUnitTypes.idl +++ b/Source/WebCore/svg/SVGUnitTypes.idl @@ -24,7 +24,6 @@ */ [ - Conditional=SVG, SuppressToJSObject, ImplementationLacksVTable ] interface SVGUnitTypes { diff --git a/Source/WebCore/svg/SVGUnknownElement.h b/Source/WebCore/svg/SVGUnknownElement.h index cb6b65a5f..713f83d59 100644 --- a/Source/WebCore/svg/SVGUnknownElement.h +++ b/Source/WebCore/svg/SVGUnknownElement.h @@ -23,10 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGUnknownElement_h -#define SVGUnknownElement_h - -#if ENABLE(SVG) +#pragma once #include "SVGElement.h" @@ -40,9 +37,9 @@ namespace WebCore { // false to make sure we don't attempt to render such elements. class SVGUnknownElement final : public SVGElement { public: - static PassRefPtr<SVGUnknownElement> create(const QualifiedName& tagName, Document& document) + static Ref<SVGUnknownElement> create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGUnknownElement(tagName, document)); + return adoptRef(*new SVGUnknownElement(tagName, document)); } private: @@ -51,11 +48,7 @@ private: { } - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; } // namespace WebCore - -#endif // ENABLE(SVG) - -#endif // SVGUnknownElement_h diff --git a/Source/WebCore/svg/SVGUseElement.cpp b/Source/WebCore/svg/SVGUseElement.cpp index a45910643..e1a8ef787 100644 --- a/Source/WebCore/svg/SVGUseElement.cpp +++ b/Source/WebCore/svg/SVGUseElement.cpp @@ -5,6 +5,7 @@ * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. * Copyright (C) 2012 University of Szeged * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> + * Copyright (C) 2015 Apple Inc. 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 @@ -23,46 +24,23 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGUseElement.h" #include "CachedResourceLoader.h" -#include "CachedResourceRequest.h" #include "CachedSVGDocument.h" -#include "Document.h" #include "ElementIterator.h" #include "Event.h" -#include "EventListener.h" -#include "HTMLNames.h" -#include "NodeRenderStyle.h" -#include "RegisteredEventListener.h" +#include "EventNames.h" #include "RenderSVGResource.h" #include "RenderSVGTransformableContainer.h" #include "ShadowRoot.h" -#include "SVGElementInstance.h" -#include "SVGElementRareData.h" -#include "SVGElementInstanceList.h" #include "SVGGElement.h" -#include "SVGLengthContext.h" -#include "SVGNames.h" -#include "SVGSMILElement.h" #include "SVGSVGElement.h" #include "SVGSymbolElement.h" -#include "StyleResolver.h" #include "XLinkNames.h" -#include "XMLDocumentParser.h" -#include "XMLSerializer.h" - -// Dump SVGElementInstance object tree - useful to debug instanceRoot problems -// #define DUMP_INSTANCE_TREE - -// Dump the deep-expanded shadow tree (where the renderers are built from) -// #define DUMP_SHADOW_TREE namespace WebCore { -// Animated property definitions DEFINE_ANIMATED_LENGTH(SVGUseElement, SVGNames::xAttr, X, x) DEFINE_ANIMATED_LENGTH(SVGUseElement, SVGNames::yAttr, Y, y) DEFINE_ANIMATED_LENGTH(SVGUseElement, SVGNames::widthAttr, Width, width) @@ -80,158 +58,106 @@ BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGUseElement) REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement) END_REGISTER_ANIMATED_PROPERTIES -inline SVGUseElement::SVGUseElement(const QualifiedName& tagName, Document& document, bool wasInsertedByParser) +inline SVGUseElement::SVGUseElement(const QualifiedName& tagName, Document& document) : SVGGraphicsElement(tagName, document) , m_x(LengthModeWidth) , m_y(LengthModeHeight) , m_width(LengthModeWidth) , m_height(LengthModeHeight) - , m_wasInsertedByParser(wasInsertedByParser) - , m_haveFiredLoadEvent(false) - , m_needsShadowTreeRecreation(false) - , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) + , m_svgLoadEventTimer(*this, &SVGElement::svgLoadEventTimerFired) { ASSERT(hasCustomStyleResolveCallbacks()); ASSERT(hasTagName(SVGNames::useTag)); registerAnimatedPropertiesForSVGUseElement(); } -PassRefPtr<SVGUseElement> SVGUseElement::create(const QualifiedName& tagName, Document& document, bool wasInsertedByParser) +Ref<SVGUseElement> SVGUseElement::create(const QualifiedName& tagName, Document& document) { - // Always build a #shadow-root for SVGUseElement. - RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(tagName, document, wasInsertedByParser)); - use->ensureUserAgentShadowRoot(); - return use.release(); + return adoptRef(*new SVGUseElement(tagName, document)); } SVGUseElement::~SVGUseElement() { - setCachedDocument(0); - - clearResourceReferences(); -} - -SVGElementInstance* SVGUseElement::instanceRoot() -{ - // 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(); -} - -SVGElementInstance* SVGUseElement::animatedInstanceRoot() const -{ - // FIXME: Implement me. - return 0; -} - -bool SVGUseElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGLangSpace::addSupportedAttributes(supportedAttributes); - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - SVGURIReference::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::xAttr); - supportedAttributes.add(SVGNames::yAttr); - supportedAttributes.add(SVGNames::widthAttr); - supportedAttributes.add(SVGNames::heightAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + if (m_externalDocument) + m_externalDocument->removeClient(*this); } void SVGUseElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { SVGParsingError parseError = NoError; - if (!isSupportedAttribute(name)) - SVGGraphicsElement::parseAttribute(name, value); - else if (name == SVGNames::xAttr) - setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); + if (name == SVGNames::xAttr) + setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); else if (name == SVGNames::yAttr) - setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); + setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); else if (name == SVGNames::widthAttr) - setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); + setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths)); else if (name == SVGNames::heightAttr) - setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); - else if (SVGLangSpace::parseAttribute(name, value) - || SVGExternalResourcesRequired::parseAttribute(name, value) - || SVGURIReference::parseAttribute(name, value)) { - } else - ASSERT_NOT_REACHED(); + setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths)); reportAttributeParsingError(parseError, name, value); -} -#if !ASSERT_DISABLED -static inline bool isWellFormedDocument(Document& document) -{ - if (document.isSVGDocument() || document.isXHTMLDocument()) - return static_cast<XMLDocumentParser*>(document.parser())->wellFormed(); - return true; + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGGraphicsElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); } -#endif Node::InsertionNotificationRequest SVGUseElement::insertedInto(ContainerNode& rootParent) { - // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied. SVGGraphicsElement::insertedInto(rootParent); - if (!rootParent.inDocument()) - return InsertionDone; - ASSERT(!m_targetElementInstance || !isWellFormedDocument(document())); - ASSERT(!hasPendingResources() || !isWellFormedDocument(document())); - if (!m_wasInsertedByParser) - buildPendingResource(); - SVGExternalResourcesRequired::insertedIntoDocument(this); + if (isConnected()) { + SVGExternalResourcesRequired::insertedIntoDocument(this); + invalidateShadowTree(); + updateExternalDocument(); + } return InsertionDone; } void SVGUseElement::removedFrom(ContainerNode& rootParent) { SVGGraphicsElement::removedFrom(rootParent); - if (rootParent.inDocument()) - clearResourceReferences(); + clearShadowTree(); + updateExternalDocument(); } -Document* SVGUseElement::referencedDocument() const +inline Document* SVGUseElement::externalDocument() const { - if (!isExternalURIReference(href(), document())) - return &document(); - return externalDocument(); + return m_externalDocument ? m_externalDocument->document() : nullptr; } -Document* SVGUseElement::externalDocument() const +void SVGUseElement::transferSizeAttributesToTargetClone(SVGElement& shadowElement) const { - if (m_cachedDocument && m_cachedDocument->isLoaded()) { - // Gracefully handle error condition. - if (m_cachedDocument->errorOccurred()) - return 0; - ASSERT(m_cachedDocument->document()); - return m_cachedDocument->document(); + // FIXME: The check for valueInSpecifiedUnits being non-zero below is a workaround for the fact + // that we currently have no good way to tell whether a particular animatable attribute is a value + // indicating it was unspecified, or specified but could not be parsed. Would be nice to fix that some day. + if (is<SVGSymbolElement>(shadowElement)) { + // 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. + shadowElement.setAttribute(SVGNames::widthAttr, (widthIsValid() && width().valueInSpecifiedUnits()) ? AtomicString(width().valueAsString()) : "100%"); + shadowElement.setAttribute(SVGNames::heightAttr, (heightIsValid() && height().valueInSpecifiedUnits()) ? AtomicString(height().valueAsString()) : "100%"); + } else if (is<SVGSVGElement>(shadowElement)) { + // 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. + SVGElement* correspondingElement = shadowElement.correspondingElement(); + shadowElement.setAttribute(SVGNames::widthAttr, (widthIsValid() && width().valueInSpecifiedUnits()) ? AtomicString(width().valueAsString()) : (correspondingElement ? correspondingElement->getAttribute(SVGNames::widthAttr) : nullAtom)); + shadowElement.setAttribute(SVGNames::heightAttr, (heightIsValid() && height().valueInSpecifiedUnits()) ? AtomicString(height().valueAsString()) : (correspondingElement ? correspondingElement->getAttribute(SVGNames::heightAttr) : nullAtom)); } - return 0; } void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGGraphicsElement::svgAttributeChanged(attrName); - return; - } + InstanceInvalidationGuard guard(*this); - SVGElementInstance::InvalidationGuard invalidationGuard(this); - - auto renderer = this->renderer(); - if (attrName == SVGNames::xAttr - || attrName == SVGNames::yAttr - || attrName == SVGNames::widthAttr - || attrName == SVGNames::heightAttr) { + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { updateRelativeLengthsInformation(); - if (renderer) + if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { + // FIXME: It's unnecessarily inefficient to update both width and height each time either is changed. + if (auto* targetClone = this->targetClone()) + transferSizeAttributesToTargetClone(*targetClone); + } + if (auto* renderer = this->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } @@ -240,758 +166,444 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) return; if (SVGURIReference::isKnownAttribute(attrName)) { - bool isExternalReference = isExternalURIReference(href(), document()); - if (isExternalReference) { - URL url = document().completeURL(href()); - if (url.hasFragmentIdentifier()) { - CachedResourceRequest request(ResourceRequest(url.string())); - request.setInitiator(this); - setCachedDocument(document().cachedResourceLoader()->requestSVGDocument(request)); - } - } else - setCachedDocument(0); - - if (!m_wasInsertedByParser) - buildPendingResource(); - + updateExternalDocument(); + invalidateShadowTree(); return; } - if (SVGLangSpace::isKnownAttribute(attrName) - || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { + if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { invalidateShadowTree(); return; } - ASSERT_NOT_REACHED(); + SVGGraphicsElement::svgAttributeChanged(attrName); } -void SVGUseElement::willAttachRenderers() +void SVGUseElement::willRecalcStyle(Style::Change change) { - if (m_needsShadowTreeRecreation) - buildPendingResource(); + // FIXME: Shadow tree should be updated before style recalc. + if (m_shadowTreeNeedsUpdate) + updateShadowTree(); + SVGGraphicsElement::willRecalcStyle(change); } -#ifdef DUMP_INSTANCE_TREE -static void dumpInstanceTree(unsigned int& depth, String& text, SVGElementInstance* targetInstance) -{ - SVGElement* element = targetInstance->correspondingElement(); - ASSERT(element); - - if (element->hasTagName(SVGNames::useTag)) { - if (toSVGUseElement(element)->cachedDocumentIsStillLoading()) - return; - } - - SVGElement* shadowTreeElement = targetInstance->shadowTreeElement(); - ASSERT(shadowTreeElement); - - SVGUseElement* directUseElement = targetInstance->directUseElement(); - String directUseElementName = directUseElement ? directUseElement->nodeName() : "null"; - - 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 (%p), firstChild=%s (%p), correspondingElement=%s (%p), directUseElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n", - targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(), - elementNodeName.latin1().data(), element, directUseElementName.latin1().data(), directUseElement, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data()); - - for (unsigned int i = 0; i < depth; ++i) - text += " "; - - const HashSet<SVGElementInstance*>& elementInstances = element->instancesForElement(); - text += "Corresponding element is associated with " + String::number(elementInstances.size()) + " instance(s):\n"; - - 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 += " "; - - text += String::format(" -> SVGElementInstance this=%p, (refCount: %i, shadowTreeElement in document? %i)\n", - *it, (*it)->refCount(), (*it)->shadowTreeElement()->inDocument()); - } - - ++depth; - - for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) - dumpInstanceTree(depth, text, instance); - - --depth; -} -#endif - -static bool isDisallowedElement(const Element& element) +static HashSet<AtomicString> createAllowedElementSet() { // Spec: "Any 'svg', 'symbol', 'g', graphics element or other 'use' is potentially a template object that can be re-used // (i.e., "instanced") in the SVG document via a 'use' element." // "Graphics Element" is defined as 'circle', 'ellipse', 'image', 'line', 'path', 'polygon', 'polyline', 'rect', 'text' // Excluded are anything that is used by reference or that only make sense to appear once in a document. - - if (!element.isSVGElement()) - return true; - - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, allowedElementTags, ()); - if (allowedElementTags.isEmpty()) { - allowedElementTags.add(SVGNames::aTag); - allowedElementTags.add(SVGNames::circleTag); - allowedElementTags.add(SVGNames::descTag); - allowedElementTags.add(SVGNames::ellipseTag); - allowedElementTags.add(SVGNames::gTag); - allowedElementTags.add(SVGNames::imageTag); - allowedElementTags.add(SVGNames::lineTag); - allowedElementTags.add(SVGNames::metadataTag); - allowedElementTags.add(SVGNames::pathTag); - allowedElementTags.add(SVGNames::polygonTag); - allowedElementTags.add(SVGNames::polylineTag); - allowedElementTags.add(SVGNames::rectTag); - allowedElementTags.add(SVGNames::svgTag); - allowedElementTags.add(SVGNames::switchTag); - allowedElementTags.add(SVGNames::symbolTag); - allowedElementTags.add(SVGNames::textTag); - allowedElementTags.add(SVGNames::textPathTag); - allowedElementTags.add(SVGNames::titleTag); - allowedElementTags.add(SVGNames::trefTag); - allowedElementTags.add(SVGNames::tspanTag); - allowedElementTags.add(SVGNames::useTag); - } - return !allowedElementTags.contains<SVGAttributeHashTranslator>(element.tagQName()); + using namespace SVGNames; + HashSet<AtomicString> set; + for (auto& tag : { aTag, circleTag, descTag, ellipseTag, gTag, imageTag, lineTag, metadataTag, pathTag, polygonTag, polylineTag, rectTag, svgTag, switchTag, symbolTag, textTag, textPathTag, titleTag, trefTag, tspanTag, useTag }) + set.add(tag.localName()); + return set; } -static bool subtreeContainsDisallowedElement(SVGElement& start) +static inline bool isDisallowedElement(const SVGElement& element) { - for (auto& element : descendantsOfType<Element>(start)) { - if (isDisallowedElement(element)) - return true; - } - - return false; + static NeverDestroyed<HashSet<AtomicString>> set = createAllowedElementSet(); + return !set.get().contains(element.localName()); } -void SVGUseElement::clearResourceReferences() +static inline bool isDisallowedElement(const Element& element) { - // FIXME: We should try to optimize this, to at least allow partial reclones. - if (ShadowRoot* shadowTreeRootElement = shadowRoot()) - shadowTreeRootElement->removeChildren(); - - if (m_targetElementInstance) { - m_targetElementInstance->detach(); - m_targetElementInstance = 0; - } - - m_needsShadowTreeRecreation = false; + return !element.isSVGElement() || isDisallowedElement(downcast<SVGElement>(element)); +} - document().accessSVGExtensions()->removeAllTargetReferencesForElement(this); +void SVGUseElement::clearShadowTree() +{ + if (auto* root = userAgentShadowRoot()) + root->removeChildren(); } void SVGUseElement::buildPendingResource() { - if (!referencedDocument() || isInShadowTree()) - return; - clearResourceReferences(); - if (!inDocument()) - return; - - String id; - Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id, externalDocument()); - if (!target || !target->inDocument()) { - // If we can't find the target of an external element, just give up. - // We can't observe if the target somewhen enters the external document, nor should we do it. - if (externalDocument()) - return; - if (id.isEmpty()) - return; - - referencedDocument()->accessSVGExtensions()->addPendingResource(id, this); - ASSERT(hasPendingResources()); - return; - } - - if (target->isSVGElement()) { - buildShadowAndInstanceTree(toSVGElement(target)); - invalidateDependentShadowTrees(); - } - - ASSERT(!m_needsShadowTreeRecreation); + invalidateShadowTree(); } -void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target) +void SVGUseElement::updateShadowTree() { - ASSERT(!m_targetElementInstance); - - // Do not build the shadow/instance tree for <use> elements living in a shadow tree. - // The will be expanded soon anyway - see expandUseElementsInShadowTree(). - if (isInShadowTree()) - return; - - // Do not allow self-referencing. - // 'target' may be null, if it's a non SVG namespaced element. - if (!target || target == this) - return; - - // Why a seperated instance/shadow tree? SVG demands it: - // The instance tree is accesable from JavaScript, and has to - // expose a 1:1 copy of the referenced tree, whereas internally we need - // to alter the tree for correct "use-on-symbol", "use-on-svg" support. - - // Build instance tree. Create root SVGElementInstance object for the first sub-tree node. - // - // Spec: If the 'use' element references a simple graphics element such as a 'rect', then there is only a - // single SVGElementInstance object, and the correspondingElement attribute on this SVGElementInstance object - // is the SVGRectElement that corresponds to the referenced 'rect' element. - m_targetElementInstance = SVGElementInstance::create(this, this, target); + m_shadowTreeNeedsUpdate = false; - // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children - bool foundProblem = false; - buildInstanceTree(target, m_targetElementInstance.get(), foundProblem, false); + // FIXME: It's expensive to re-clone the entire tree every time. We should find a more efficient way to handle this. + clearShadowTree(); - if (instanceTreeIsLoading(m_targetElementInstance.get())) + if (isInShadowTree() || !isConnected()) return; - // SVG specification does not say a word about <use> & cycles. My view on this is: just ignore it! - // Non-appearing <use> content is easier to debug, then half-appearing content. - if (foundProblem) { - clearResourceReferences(); + String targetID; + auto* target = findTarget(&targetID); + if (!target) { + document().accessSVGExtensions().addPendingResource(targetID, this); return; } - // Assure instance tree building was successfull - ASSERT(m_targetElementInstance); - ASSERT(!m_targetElementInstance->shadowTreeElement()); - ASSERT(m_targetElementInstance->correspondingUseElement() == this); - ASSERT(m_targetElementInstance->directUseElement() == this); - ASSERT(m_targetElementInstance->correspondingElement() == target); - - ShadowRoot* shadowTreeRootElement = shadowRoot(); - ASSERT(shadowTreeRootElement); - - // Build shadow tree from instance tree - // This also handles the special cases: <use> on <symbol>, <use> on <svg>. - buildShadowTree(target, m_targetElementInstance.get()); - - // Expand all <use> elements in the shadow tree. - // Expand means: replace the actual <use> element by what it references. - expandUseElementsInShadowTree(shadowTreeRootElement); - - // Expand all <symbol> elements in the shadow tree. - // Expand means: replace the actual <symbol> element by the <svg> element. - expandSymbolElementsInShadowTree(shadowTreeRootElement); - - // Now that the shadow tree is completly expanded, we can associate - // shadow tree elements <-> instances in the instance tree. - associateInstancesWithShadowTreeElements(shadowTreeRootElement->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()) { - clearResourceReferences(); - return; - } - - ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowTreeRootElement); + cloneTarget(ensureUserAgentShadowRoot(), *target); + expandUseElementsInShadowTree(); + expandSymbolElementsInShadowTree(); + transferEventListenersToShadowTree(); - // Transfer event listeners assigned to the referenced element to our shadow tree elements. - transferEventListenersToShadowTree(m_targetElementInstance.get()); - - // Update relative length information. updateRelativeLengthsInformation(); - // Eventually dump instance tree -#ifdef DUMP_INSTANCE_TREE - String text; - unsigned int depth = 0; - - dumpInstanceTree(depth, text, m_targetElementInstance.get()); - fprintf(stderr, "\nDumping <use> instance tree:\n%s\n", text.latin1().data()); -#endif + // When we invalidate the other shadow trees, it's important that we don't + // follow any cycles and invalidate ourselves. To avoid that, we temporarily + // set m_shadowTreeNeedsUpdate to true so invalidateShadowTree will + // quickly return and do nothing. + ASSERT(!m_shadowTreeNeedsUpdate); + m_shadowTreeNeedsUpdate = true; + invalidateDependentShadowTrees(); + m_shadowTreeNeedsUpdate = false; +} - // Eventually dump shadow tree -#ifdef DUMP_SHADOW_TREE - RefPtr<XMLSerializer> serializer = XMLSerializer::create(); - String markup = serializer->serializeToString(shadowTreeRootElement, ASSERT_NO_EXCEPTION); - fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data()); -#endif +SVGElement* SVGUseElement::targetClone() const +{ + auto* root = userAgentShadowRoot(); + if (!root) + return nullptr; + return childrenOfType<SVGElement>(*root).first(); } -RenderPtr<RenderElement> SVGUseElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGUseElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGTransformableContainer>(*this, std::move(style)); + return createRenderer<RenderSVGTransformableContainer>(*this, WTFMove(style)); } -static bool isDirectReference(const Node* node) +static bool isDirectReference(const SVGElement& element) { - return node->hasTagName(SVGNames::pathTag) - || node->hasTagName(SVGNames::rectTag) - || node->hasTagName(SVGNames::circleTag) - || node->hasTagName(SVGNames::ellipseTag) - || node->hasTagName(SVGNames::polygonTag) - || node->hasTagName(SVGNames::polylineTag) - || node->hasTagName(SVGNames::textTag); + using namespace SVGNames; + return element.hasTagName(circleTag) + || element.hasTagName(ellipseTag) + || element.hasTagName(pathTag) + || element.hasTagName(polygonTag) + || element.hasTagName(polylineTag) + || element.hasTagName(rectTag) + || element.hasTagName(textTag); } void SVGUseElement::toClipPath(Path& path) { ASSERT(path.isEmpty()); - Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0; - if (!n) + auto* targetClone = this->targetClone(); + if (!is<SVGGraphicsElement>(targetClone)) return; - if (n->isSVGElement() && toSVGElement(n)->isSVGGraphicsElement()) { - if (!isDirectReference(n)) - // Spec: Indirect references are an error (14.3.5) - document().accessSVGExtensions()->reportError("Not allowed to use indirect reference in <clip-path>"); - else { - toSVGGraphicsElement(n)->toClipPath(path); - // FIXME: Avoid manual resolution of x/y here. Its potentially harmful. - SVGLengthContext lengthContext(this); - path.translate(FloatSize(x().value(lengthContext), y().value(lengthContext))); - path.transform(animatedLocalTransform()); - } + if (!isDirectReference(*targetClone)) { + // Spec: Indirect references are an error (14.3.5) + document().accessSVGExtensions().reportError(ASCIILiteral("Not allowed to use indirect reference in <clip-path>")); + return; } + + downcast<SVGGraphicsElement>(*targetClone).toClipPath(path); + SVGLengthContext lengthContext(this); + // FIXME: Find a way to do this without manual resolution of x/y here. It's potentially incorrect. + path.translate(FloatSize(x().value(lengthContext), y().value(lengthContext))); + path.transform(animatedLocalTransform()); } RenderElement* SVGUseElement::rendererClipChild() const { - Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0; - if (!n) - return 0; - - if (n->isSVGElement() && isDirectReference(n)) - return toSVGElement(n)->renderer(); - - return 0; + auto* targetClone = this->targetClone(); + if (!targetClone) + return nullptr; + if (!isDirectReference(*targetClone)) + return nullptr; + return targetClone->renderer(); } -void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundProblem, bool foundUse) +static inline void disassociateAndRemoveClones(const Vector<Element*>& clones) { - ASSERT(target); - ASSERT(targetInstance); - - // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced - // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree. - bool targetHasUseTag = target->hasTagName(SVGNames::useTag); - SVGElement* newTarget = 0; - if (targetHasUseTag) { - foundProblem = hasCycleUseReferencing(toSVGUseElement(target), targetInstance, newTarget); - if (foundProblem) - return; - - // We only need to track first degree <use> dependencies. Indirect references are handled - // as the invalidation bubbles up the dependency chain. - if (!foundUse) { - document().accessSVGExtensions()->addElementReferencingTarget(this, target); - foundUse = true; - } - } else if (isDisallowedElement(*target)) { - foundProblem = true; - return; - } - - // A general description from the SVG spec, describing what buildInstanceTree() actually does. - // - // Spec: If the 'use' element references a 'g' which contains two 'rect' elements, then the instance tree - // contains three SVGElementInstance objects, a root SVGElementInstance object whose correspondingElement - // is the SVGGElement object for the 'g', and then two child SVGElementInstance objects, each of which has - // its correspondingElement that is an SVGRectElement object. - - for (auto& element : childrenOfType<SVGElement>(*target)) { - // Skip any non-svg nodes or any disallowed element. - if (isDisallowedElement(element)) - continue; - - // Create SVGElementInstance object, for both container/non-container nodes. - RefPtr<SVGElementInstance> instance = SVGElementInstance::create(this, 0, &element); - SVGElementInstance* instancePtr = instance.get(); - targetInstance->appendChild(instance.release()); - - // Enter recursion, appending new instance tree nodes to the "instance" object. - buildInstanceTree(&element, instancePtr, foundProblem, foundUse); - if (foundProblem) - return; + for (auto& clone : clones) { + for (auto& descendant : descendantsOfType<SVGElement>(*clone)) + descendant.setCorrespondingElement(nullptr); + clone->parentNode()->removeChild(*clone); } - - if (!targetHasUseTag || !newTarget) - return; - - RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, toSVGUseElement(target), newTarget); - SVGElementInstance* newInstancePtr = newInstance.get(); - targetInstance->appendChild(newInstance.release()); - buildInstanceTree(newTarget, newInstancePtr, foundProblem, foundUse); } -bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, SVGElement*& newTarget) +static void removeDisallowedElementsFromSubtree(SVGElement& subtree) { - ASSERT(referencedDocument()); - Element* targetElement = SVGURIReference::targetElementFromIRIString(use->href(), *referencedDocument()); - newTarget = 0; - if (targetElement && targetElement->isSVGElement()) - newTarget = toSVGElement(targetElement); - - if (!newTarget) - return false; - - // Shortcut for self-references - if (newTarget == this) - return true; + // Remove disallowed elements after the fact rather than not cloning them in the first place. + // This optimizes for the normal case where none of those elements are present. - AtomicString targetId = newTarget->getIdAttribute(); - SVGElementInstance* instance = targetInstance->parentNode(); - while (instance) { - SVGElement* element = instance->correspondingElement(); + // This function is used only on elements in subtrees that are not yet in documents, so + // mutation events are not a factor; there are no event listeners to handle those events. + // Assert that it's not in a document to make sure callers are still using it this way. + ASSERT(!subtree.isConnected()); - if (element->hasID() && element->getIdAttribute() == targetId && &element->document() == &newTarget->document()) - return true; - - instance = instance->parentNode(); - } - return false; -} - -static inline void removeDisallowedElementsFromSubtree(SVGElement& subtree) -{ - ASSERT(!subtree.inDocument()); - Vector<Element*> toRemove; - auto it = descendantsOfType<Element>(subtree).begin(); - auto end = descendantsOfType<Element>(subtree).end(); - while (it != end) { + Vector<Element*> disallowedElements; + auto descendants = descendantsOfType<Element>(subtree); + for (auto it = descendants.begin(), end = descendants.end(); it != end; ) { if (isDisallowedElement(*it)) { - toRemove.append(&*it); + disallowedElements.append(&*it); it.traverseNextSkippingChildren(); continue; } ++it; } - // The subtree is not in document so this won't generate events that could mutate the tree. - for (unsigned i = 0; i < toRemove.size(); ++i) - toRemove[i]->parentNode()->removeChild(toRemove[i]); + + disassociateAndRemoveClones(disallowedElements); } -void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance) +static void removeSymbolElementsFromSubtree(SVGElement& subtree) { - ASSERT(target); // FIXME: Don't be a pointer! - - // For instance <use> on <foreignObject> (direct case). - if (isDisallowedElement(*target)) - return; - - RefPtr<SVGElement> newChild = static_pointer_cast<SVGElement>(targetInstance->correspondingElement()->cloneElementWithChildren()); - - // We don't walk the target tree element-by-element, and clone each element, - // but instead use cloneElementWithChildren(). This is an optimization for the common - // case where <use> doesn't contain disallowed elements (ie. <foreignObject>). - // Though if there are disallowed elements in the subtree, we have to remove them. - // For instance: <use> on <g> containing <foreignObject> (indirect case). - if (subtreeContainsDisallowedElement(*newChild)) - removeDisallowedElementsFromSubtree(*newChild); - - shadowRoot()->appendChild(newChild.release()); + // Symbol elements inside the subtree should not be cloned for two reasons: 1) They are invisible and + // don't need to be cloned to get correct rendering. 2) expandSymbolElementsInShadowTree will turn them + // into <svg> elements, which is correct for symbol elements directly referenced by use elements, + // but incorrect for ones that just happen to be in a subtree. + Vector<Element*> symbolElements; + for (auto& descendant : descendantsOfType<SVGSymbolElement>(subtree)) + symbolElements.append(&descendant); + disassociateAndRemoveClones(symbolElements); } -void SVGUseElement::expandUseElementsInShadowTree(Node* element) +static void associateClonesWithOriginals(SVGElement& clone, SVGElement& original) { - // Why expand the <use> elements in the shadow tree here, and not just - // do this directly in buildShadowTree, if we encounter a <use> element? - // - // Short answer: Because we may miss to expand some elements. Ie. if a <symbol> - // contains <use> tags, we'd miss them. So once we're done with settin' up the - // actual shadow tree (after the special case modification for svg/symbol) we have - // to walk it completely and expand all <use> elements. - if (element->hasTagName(SVGNames::useTag)) { - SVGUseElement* use = toSVGUseElement(element); - ASSERT(!use->cachedDocumentIsStillLoading()); - - ASSERT(referencedDocument()); - Element* targetElement = SVGURIReference::targetElementFromIRIString(use->href(), *referencedDocument()); - SVGElement* target = 0; - if (targetElement && targetElement->isSVGElement()) - target = toSVGElement(targetElement); + // This assertion checks that we don't call this with the arguments backwards. + // The clone is new and so it's not installed in a parent yet. + ASSERT(!clone.parentNode()); - // Don't ASSERT(target) here, it may be "pending", too. - // Setup sub-shadow tree root node - RefPtr<SVGGElement> cloneParent = SVGGElement::create(SVGNames::gTag, *referencedDocument()); - use->cloneChildNodes(cloneParent.get()); - - // 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()); + // The loop below works because we are associating these clones immediately, before + // doing transformations like removing disallowed elements or expanding elements. + clone.setCorrespondingElement(&original); + for (auto pair : descendantsOfType<SVGElement>(clone, original)) + pair.first.setCorrespondingElement(&pair.second); +} - if (target && !isDisallowedElement(*target)) { - RefPtr<Element> newChild = target->cloneElementWithChildren(); - ASSERT(newChild->isSVGElement()); - cloneParent->appendChild(newChild.release()); - } +static void associateReplacementCloneWithOriginal(SVGElement& replacementClone, SVGElement& originalClone) +{ + auto* correspondingElement = originalClone.correspondingElement(); + ASSERT(correspondingElement); + originalClone.setCorrespondingElement(nullptr); + replacementClone.setCorrespondingElement(correspondingElement); +} - // We don't walk the target tree element-by-element, and clone each element, - // but instead use cloneElementWithChildren(). This is an optimization for the common - // case where <use> doesn't contain disallowed elements (ie. <foreignObject>). - // Though if there are disallowed elements in the subtree, we have to remove them. - // For instance: <use> on <g> containing <foreignObject> (indirect case). - if (subtreeContainsDisallowedElement(*cloneParent)) - removeDisallowedElementsFromSubtree(*cloneParent); - - RefPtr<Node> replacingElement(cloneParent.get()); - - // Replace <use> with referenced content. - ASSERT(use->parentNode()); - use->parentNode()->replaceChild(cloneParent.release(), use); - - // Expand the siblings because the *element* is replaced and we will - // lose the sibling chain when we are back from recursion. - element = replacingElement.get(); - for (RefPtr<Node> sibling = element->nextSibling(); sibling; sibling = sibling->nextSibling()) - expandUseElementsInShadowTree(sibling.get()); - } +static void associateReplacementClonesWithOriginals(SVGElement& replacementClone, SVGElement& originalClone) +{ + // This assertion checks that we don't call this with the arguments backwards. + // The replacement clone is new and so it's not installed in a parent yet. + ASSERT(!replacementClone.parentNode()); - for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling()) - expandUseElementsInShadowTree(child.get()); + // The loop below works because we are associating these clones immediately, before + // doing transformations like removing disallowed elements or expanding elements. + associateReplacementCloneWithOriginal(replacementClone, originalClone); + for (auto pair : descendantsOfType<SVGElement>(replacementClone, originalClone)) + associateReplacementCloneWithOriginal(pair.first, pair.second); } -void SVGUseElement::expandSymbolElementsInShadowTree(Node* element) +SVGElement* SVGUseElement::findTarget(String* targetID) const { - if (element->hasTagName(SVGNames::symbolTag)) { - // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree, - // with the exception that the 'symbol' is replaced by an 'svg'. 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. - RefPtr<SVGSVGElement> svgElement = SVGSVGElement::create(SVGNames::svgTag, *referencedDocument()); - - // Transfer all data (attributes, etc.) from <symbol> to the new <svg> element. - svgElement->cloneDataFromElement(*toElement(element)); + auto* correspondingElement = this->correspondingElement(); + auto& original = correspondingElement ? downcast<SVGUseElement>(*correspondingElement) : *this; - // Only clone symbol children, and add them to the new <svg> element - for (Node* child = element->firstChild(); child; child = child->nextSibling()) { - RefPtr<Node> newChild = child->cloneNode(true); - svgElement->appendChild(newChild.release()); + auto* targetCandidate = targetElementFromIRIString(original.href(), original.document(), targetID, original.externalDocument()); + if (targetID && !targetID->isNull()) { + // If the reference is external, don't return the target ID to the caller. + // The caller would use the target ID to wait for a pending resource on the wrong document. + // If we ever want the change that and let the caller to wait on the external document, + // we should change this function so it returns the appropriate document to go with the ID. + if (isExternalURIReference(original.href(), original.document())) + *targetID = String(); + } + if (!is<SVGElement>(targetCandidate)) + return nullptr; + auto& target = downcast<SVGElement>(*targetCandidate); + + if (!target.isConnected() || isDisallowedElement(target)) + return nullptr; + + // Reject any target that has already been cloned to create one of the ancestors of this element, + // already in the shadow tree. This is sufficient to prevent cycles. + if (correspondingElement) { + for (auto& ancestor : lineageOfType<SVGElement>(*this)) { + if (ancestor.correspondingElement() == &target) + return nullptr; } - - // We don't walk the target tree element-by-element, and clone each element, - // but instead use cloneNode(deep=true). This is an optimization for the common - // case where <use> doesn't contain disallowed elements (ie. <foreignObject>). - // Though if there are disallowed elements in the subtree, we have to remove them. - // For instance: <use> on <g> containing <foreignObject> (indirect case). - if (subtreeContainsDisallowedElement(*svgElement)) - removeDisallowedElementsFromSubtree(*svgElement); - - RefPtr<Node> replacingElement(svgElement.get()); - - // Replace <symbol> with <svg>. - element->parentNode()->replaceChild(svgElement.release(), element); - - // Expand the siblings because the *element* is replaced and we will - // lose the sibling chain when we are back from recursion. - element = replacingElement.get(); - for (RefPtr<Node> sibling = element->nextSibling(); sibling; sibling = sibling->nextSibling()) - expandSymbolElementsInShadowTree(sibling.get()); } - for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling()) - expandSymbolElementsInShadowTree(child.get()); + return ⌖ } -void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target) +void SVGUseElement::cloneTarget(ContainerNode& container, SVGElement& target) const { - if (!target) - return; - - SVGElement* originalElement = target->correspondingElement(); - ASSERT(originalElement); + Ref<SVGElement> targetClone = static_cast<SVGElement&>(target.cloneElementWithChildren(document()).get()); + associateClonesWithOriginals(targetClone.get(), target); + removeDisallowedElementsFromSubtree(targetClone.get()); + removeSymbolElementsFromSubtree(targetClone.get()); + transferSizeAttributesToTargetClone(targetClone.get()); + container.appendChild(targetClone); +} - if (SVGElement* shadowTreeElement = target->shadowTreeElement()) { - if (EventTargetData* data = originalElement->eventTargetData()) - data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(shadowTreeElement); - } +static void cloneDataAndChildren(SVGElement& replacementClone, SVGElement& originalClone) +{ + // This assertion checks that we don't call this with the arguments backwards. + // The replacement clone is new and so it's not installed in a parent yet. + ASSERT(!replacementClone.parentNode()); - for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling()) - transferEventListenersToShadowTree(instance); + replacementClone.cloneDataFromElement(originalClone); + originalClone.cloneChildNodes(replacementClone); + associateReplacementClonesWithOriginals(replacementClone, originalClone); + removeDisallowedElementsFromSubtree(replacementClone); } -void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance) +void SVGUseElement::expandUseElementsInShadowTree() const { - if (!target || !targetInstance) - return; + auto descendants = descendantsOfType<SVGUseElement>(*userAgentShadowRoot()); + for (auto it = descendants.begin(), end = descendants.end(); it != end; ) { + SVGUseElement& originalClone = *it; + it = end; // Efficiently quiets assertions due to the outstanding iterator. - SVGElement* originalElement = targetInstance->correspondingElement(); + auto* target = originalClone.findTarget(); - if (originalElement->hasTagName(SVGNames::useTag)) { - // <use> gets replaced by <g> - ASSERT(target->nodeName() == SVGNames::gTag); - } else if (originalElement->hasTagName(SVGNames::symbolTag)) { - // <symbol> gets replaced by <svg> - ASSERT(target->nodeName() == SVGNames::svgTag); - } else - ASSERT(target->nodeName() == originalElement->nodeName()); + // 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. - SVGElement* element = 0; - if (target->isSVGElement()) - element = toSVGElement(target); + auto replacementClone = SVGGElement::create(document()); + cloneDataAndChildren(replacementClone.get(), originalClone); - ASSERT(!targetInstance->shadowTreeElement()); - targetInstance->setShadowTreeElement(element); - element->setCorrespondingElement(originalElement); + replacementClone->removeAttribute(SVGNames::xAttr); + replacementClone->removeAttribute(SVGNames::yAttr); + replacementClone->removeAttribute(SVGNames::widthAttr); + replacementClone->removeAttribute(SVGNames::heightAttr); + replacementClone->removeAttribute(XLinkNames::hrefAttr); - Node* node = target->firstChild(); - for (SVGElementInstance* instance = targetInstance->firstChild(); node && instance; instance = instance->nextSibling()) { - // Skip any non-svg elements in shadow tree - while (node && !node->isSVGElement()) - node = node->nextSibling(); + if (target) + originalClone.cloneTarget(replacementClone.get(), *target); - if (!node) - break; + originalClone.parentNode()->replaceChild(replacementClone, originalClone); - associateInstancesWithShadowTreeElements(node, instance); - node = node->nextSibling(); + // Resume iterating, starting just inside the replacement clone. + it = descendants.from(replacementClone.get()); } } -SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element) const +void SVGUseElement::expandSymbolElementsInShadowTree() const { - if (!m_targetElementInstance) { - ASSERT(!inDocument()); - return 0; - } - - return instanceForShadowTreeElement(element, m_targetElementInstance.get()); -} + auto descendants = descendantsOfType<SVGSymbolElement>(*userAgentShadowRoot()); + for (auto it = descendants.begin(), end = descendants.end(); it != end; ) { + SVGSymbolElement& originalClone = *it; + it = end; // Efficiently quiets assertions due to the outstanding iterator. -SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const -{ - ASSERT(element); - ASSERT(instance); + // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree, + // with the exception that the 'symbol' is replaced by an 'svg'. 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. - // We're dispatching a mutation event during shadow tree construction - // this instance hasn't yet been associated to a shadowTree element. - if (!instance->shadowTreeElement()) - return 0; + auto replacementClone = SVGSVGElement::create(document()); + cloneDataAndChildren(replacementClone.get(), originalClone); - if (element == instance->shadowTreeElement()) - return instance; + originalClone.parentNode()->replaceChild(replacementClone, originalClone); - for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) { - if (SVGElementInstance* search = instanceForShadowTreeElement(element, current)) - return search; + // Resume iterating, starting just inside the replacement clone. + it = descendants.from(replacementClone.get()); } +} - return 0; +void SVGUseElement::transferEventListenersToShadowTree() const +{ + for (auto& descendant : descendantsOfType<SVGElement>(*userAgentShadowRoot())) { + if (EventTargetData* data = descendant.correspondingElement()->eventTargetData()) + data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(&descendant); + } } void SVGUseElement::invalidateShadowTree() { - if (m_needsShadowTreeRecreation) + if (m_shadowTreeNeedsUpdate) return; - m_needsShadowTreeRecreation = true; - setNeedsStyleRecalc(ReconstructRenderTree); + m_shadowTreeNeedsUpdate = true; + invalidateStyleAndRenderersForSubtree(); invalidateDependentShadowTrees(); } void SVGUseElement::invalidateDependentShadowTrees() { - // Recursively invalidate dependent <use> shadow trees - const HashSet<SVGElementInstance*>& instances = instancesForElement(); - const HashSet<SVGElementInstance*>::const_iterator end = instances.end(); - for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) { - if (SVGUseElement* element = (*it)->correspondingUseElement()) { - ASSERT(element->inDocument()); + for (auto* instance : instances()) { + if (auto* element = instance->correspondingUseElement()) element->invalidateShadowTree(); - } } } -void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const -{ - ASSERT(from); - ASSERT(to); - - to->cloneDataFromElement(*from); - - to->removeAttribute(SVGNames::xAttr); - to->removeAttribute(SVGNames::yAttr); - to->removeAttribute(SVGNames::widthAttr); - to->removeAttribute(SVGNames::heightAttr); - to->removeAttribute(XLinkNames::hrefAttr); -} - bool SVGUseElement::selfHasRelativeLengths() const { - if (x().isRelative() - || y().isRelative() - || width().isRelative() - || height().isRelative()) + if (x().isRelative() || y().isRelative() || width().isRelative() || height().isRelative()) return true; - if (!m_targetElementInstance) - return false; - - SVGElement* element = m_targetElementInstance->correspondingElement(); - if (!element) - return false; - - return element->hasRelativeLengths(); + auto* targetClone = this->targetClone(); + return targetClone && targetClone->hasRelativeLengths(); } -void SVGUseElement::notifyFinished(CachedResource* resource) +void SVGUseElement::notifyFinished(CachedResource& resource) { - if (!inDocument()) - return; - invalidateShadowTree(); - if (resource->errorOccurred()) + if (resource.errorOccurred()) dispatchEvent(Event::create(eventNames().errorEvent, false, false)); - else if (!resource->wasCanceled()) + else if (!resource.wasCanceled()) SVGExternalResourcesRequired::dispatchLoadEvent(this); } -bool SVGUseElement::cachedDocumentIsStillLoading() +void SVGUseElement::finishParsingChildren() { - if (m_cachedDocument && m_cachedDocument->isLoading()) - return true; - return false; + SVGGraphicsElement::finishParsingChildren(); + SVGExternalResourcesRequired::finishParsingChildren(); } -bool SVGUseElement::instanceTreeIsLoading(SVGElementInstance* targetElementInstance) +void SVGUseElement::updateExternalDocument() { - for (SVGElementInstance* instance = targetElementInstance->firstChild(); instance; instance = instance->nextSibling()) { - if (SVGUseElement* use = instance->correspondingUseElement()) { - if (use->cachedDocumentIsStillLoading()) - return true; - } - if (instance->hasChildNodes()) - instanceTreeIsLoading(instance); + URL externalDocumentURL; + if (isConnected() && isExternalURIReference(href(), document())) { + externalDocumentURL = document().completeURL(href()); + if (!externalDocumentURL.hasFragmentIdentifier()) + externalDocumentURL = URL(); } - return false; + + if (externalDocumentURL == (m_externalDocument ? m_externalDocument->url() : URL())) + return; + + if (m_externalDocument) + m_externalDocument->removeClient(*this); + + if (externalDocumentURL.isNull()) + m_externalDocument = nullptr; + else { + ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions(); + options.contentSecurityPolicyImposition = isInUserAgentShadowTree() ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck; + options.mode = FetchOptions::Mode::SameOrigin; + CachedResourceRequest request { ResourceRequest { externalDocumentURL }, options }; + request.setInitiator(*this); + m_externalDocument = document().cachedResourceLoader().requestSVGDocument(WTFMove(request)); + if (m_externalDocument) + m_externalDocument->addClient(*this); + } + + invalidateShadowTree(); } -void SVGUseElement::finishParsingChildren() +bool SVGUseElement::isValid() const { - SVGGraphicsElement::finishParsingChildren(); - SVGExternalResourcesRequired::finishParsingChildren(); - if (m_wasInsertedByParser) { - buildPendingResource(); - m_wasInsertedByParser = false; - } + return SVGTests::isValid(); } -void SVGUseElement::setCachedDocument(CachedResourceHandle<CachedSVGDocument> cachedDocument) +bool SVGUseElement::haveLoadedRequiredResources() { - if (m_cachedDocument == cachedDocument) - return; + return SVGExternalResourcesRequired::haveLoadedRequiredResources(); +} - if (m_cachedDocument) - m_cachedDocument->removeClient(this); +void SVGUseElement::setHaveFiredLoadEvent(bool haveFiredLoadEvent) +{ + m_haveFiredLoadEvent = haveFiredLoadEvent; +} - m_cachedDocument = cachedDocument; - if (m_cachedDocument) - m_cachedDocument->addClient(this); +bool SVGUseElement::haveFiredLoadEvent() const +{ + return m_haveFiredLoadEvent; } +Timer* SVGUseElement::svgLoadEventTimer() +{ + return &m_svgLoadEventTimer; } -#endif // ENABLE(SVG) +} diff --git a/Source/WebCore/svg/SVGUseElement.h b/Source/WebCore/svg/SVGUseElement.h index 86123fc21..070fdfd32 100644 --- a/Source/WebCore/svg/SVGUseElement.h +++ b/Source/WebCore/svg/SVGUseElement.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2015 Apple Inc. 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 @@ -18,118 +19,81 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGUseElement_h -#define SVGUseElement_h +#pragma once -#if ENABLE(SVG) #include "CachedResourceHandle.h" #include "CachedSVGDocumentClient.h" #include "SVGAnimatedBoolean.h" #include "SVGAnimatedLength.h" #include "SVGExternalResourcesRequired.h" #include "SVGGraphicsElement.h" -#include "SVGNames.h" #include "SVGURIReference.h" namespace WebCore { class CachedSVGDocument; -class SVGElementInstance; +class SVGGElement; + +class SVGUseElement final : public SVGGraphicsElement, public SVGExternalResourcesRequired, public SVGURIReference, private CachedSVGDocumentClient { + + BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGUseElement) + DECLARE_ANIMATED_LENGTH(X, x) + DECLARE_ANIMATED_LENGTH(Y, y) + DECLARE_ANIMATED_LENGTH(Width, width) + DECLARE_ANIMATED_LENGTH(Height, height) + DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) + END_DECLARE_ANIMATED_PROPERTIES -class SVGUseElement final : public SVGGraphicsElement, - public SVGExternalResourcesRequired, - public SVGURIReference, - public CachedSVGDocumentClient { public: - static PassRefPtr<SVGUseElement> create(const QualifiedName&, Document&, bool wasInsertedByParser); + static Ref<SVGUseElement> create(const QualifiedName&, Document&); virtual ~SVGUseElement(); - SVGElementInstance* instanceRoot(); - SVGElementInstance* animatedInstanceRoot() const; - SVGElementInstance* instanceForShadowTreeElement(Node*) const; void invalidateShadowTree(); - void invalidateDependentShadowTrees(); RenderElement* rendererClipChild() const; private: - SVGUseElement(const QualifiedName&, Document&, bool wasInsertedByParser); - - virtual bool isValid() const override { return SVGTests::isValid(); } - virtual bool supportsFocus() const override { return true; } - - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - virtual void buildPendingResource() override; - - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - - virtual void willAttachRenderers() override; - - virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override; - virtual void toClipPath(Path&) override; - - void clearResourceReferences(); - void buildShadowAndInstanceTree(SVGElement* target); - void detachInstance(); + SVGUseElement(const QualifiedName&, Document&); + + bool isValid() const override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; + void buildPendingResource() override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + void willRecalcStyle(Style::Change) override; + RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + void toClipPath(Path&) override; + bool haveLoadedRequiredResources() override; + void finishParsingChildren() override; + bool selfHasRelativeLengths() const override; + void setHaveFiredLoadEvent(bool) override; + bool haveFiredLoadEvent() const override; + Timer* svgLoadEventTimer() override; + void notifyFinished(CachedResource&) final; - virtual bool haveLoadedRequiredResources() override { return SVGExternalResourcesRequired::haveLoadedRequiredResources(); } - - virtual void finishParsingChildren() override; - virtual bool selfHasRelativeLengths() const override; - - // Instance tree handling - void buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundCycle, bool foundUse); - bool hasCycleUseReferencing(SVGUseElement*, SVGElementInstance* targetInstance, SVGElement*& newTarget); - - // Shadow tree handling - void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance); + Document* externalDocument() const; + void updateExternalDocument(); - void expandUseElementsInShadowTree(Node* element); - void expandSymbolElementsInShadowTree(Node* element); + SVGElement* findTarget(String* targetID = nullptr) const; - // "Tree connector" - void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance); - SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const; + void cloneTarget(ContainerNode&, SVGElement& target) const; + SVGElement* targetClone() const; - void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const; - void transferEventListenersToShadowTree(SVGElementInstance* target); + void updateShadowTree(); + void expandUseElementsInShadowTree() const; + void expandSymbolElementsInShadowTree() const; + void transferEventListenersToShadowTree() const; + void transferSizeAttributesToTargetClone(SVGElement&) const; - BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGUseElement) - DECLARE_ANIMATED_LENGTH(X, x) - DECLARE_ANIMATED_LENGTH(Y, y) - DECLARE_ANIMATED_LENGTH(Width, width) - DECLARE_ANIMATED_LENGTH(Height, height) - DECLARE_ANIMATED_STRING(Href, href) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) - END_DECLARE_ANIMATED_PROPERTIES + void clearShadowTree(); + void invalidateDependentShadowTrees(); - bool cachedDocumentIsStillLoading(); - Document* externalDocument() const; - bool instanceTreeIsLoading(SVGElementInstance*); - virtual void notifyFinished(CachedResource*) override; - Document* referencedDocument() const; - void setCachedDocument(CachedResourceHandle<CachedSVGDocument>); - - // SVGExternalResourcesRequired - virtual void setHaveFiredLoadEvent(bool haveFiredLoadEvent) override { m_haveFiredLoadEvent = haveFiredLoadEvent; } - virtual bool isParserInserted() const override { return m_wasInsertedByParser; } - virtual bool haveFiredLoadEvent() const override { return m_haveFiredLoadEvent; } - virtual Timer<SVGElement>* svgLoadEventTimer() override { return &m_svgLoadEventTimer; } - - bool m_wasInsertedByParser; - bool m_haveFiredLoadEvent; - bool m_needsShadowTreeRecreation; - RefPtr<SVGElementInstance> m_targetElementInstance; - CachedResourceHandle<CachedSVGDocument> m_cachedDocument; - Timer<SVGElement> m_svgLoadEventTimer; + bool m_haveFiredLoadEvent { false }; + bool m_shadowTreeNeedsUpdate { true }; + CachedResourceHandle<CachedSVGDocument> m_externalDocument; + Timer m_svgLoadEventTimer; }; -NODE_TYPE_CASTS(SVGUseElement) - } - -#endif -#endif diff --git a/Source/WebCore/svg/SVGUseElement.idl b/Source/WebCore/svg/SVGUseElement.idl index c4cdf1317..b8e9eaf30 100644 --- a/Source/WebCore/svg/SVGUseElement.idl +++ b/Source/WebCore/svg/SVGUseElement.idl @@ -23,16 +23,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGUseElement : SVGGraphicsElement { - readonly attribute SVGAnimatedLength x; - readonly attribute SVGAnimatedLength y; - readonly attribute SVGAnimatedLength width; - readonly attribute SVGAnimatedLength height; - - readonly attribute SVGElementInstance instanceRoot; - readonly attribute SVGElementInstance animatedInstanceRoot; +interface SVGUseElement : SVGGraphicsElement { + readonly attribute SVGAnimatedLength x; + readonly attribute SVGAnimatedLength y; + readonly attribute SVGAnimatedLength width; + readonly attribute SVGAnimatedLength height; }; SVGUseElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGVKernElement.cpp b/Source/WebCore/svg/SVGVKernElement.cpp index 44e09fd79..51fad8a8f 100644 --- a/Source/WebCore/svg/SVGVKernElement.cpp +++ b/Source/WebCore/svg/SVGVKernElement.cpp @@ -35,48 +35,29 @@ inline SVGVKernElement::SVGVKernElement(const QualifiedName& tagName, Document& ASSERT(hasTagName(SVGNames::vkernTag)); } -PassRefPtr<SVGVKernElement> SVGVKernElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGVKernElement> SVGVKernElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGVKernElement(tagName, document)); + return adoptRef(*new SVGVKernElement(tagName, document)); } -Node::InsertionNotificationRequest SVGVKernElement::insertedInto(ContainerNode& rootParent) +bool SVGVKernElement::buildVerticalKerningPair(SVGKerningPair& kerningPair) const { - if (rootParent.inDocument()) { - ContainerNode* fontNode = parentNode(); - if (fontNode && isSVGFontElement(fontNode)) - toSVGFontElement(fontNode)->invalidateGlyphCache(); - } - - return SVGElement::insertedInto(rootParent); -} - -void SVGVKernElement::removedFrom(ContainerNode& rootParent) -{ - ContainerNode* fontNode = parentNode(); - if (fontNode && isSVGFontElement(fontNode)) - toSVGFontElement(fontNode)->invalidateGlyphCache(); - - SVGElement::removedFrom(rootParent); -} - -void SVGVKernElement::buildVerticalKerningPair(SVGKerningMap& kerningMap) -{ - String u1 = fastGetAttribute(SVGNames::u1Attr); - String g1 = fastGetAttribute(SVGNames::g1Attr); - String u2 = fastGetAttribute(SVGNames::u2Attr); - String g2 = fastGetAttribute(SVGNames::g2Attr); + String u1 = attributeWithoutSynchronization(SVGNames::u1Attr); + String g1 = attributeWithoutSynchronization(SVGNames::g1Attr); + String u2 = attributeWithoutSynchronization(SVGNames::u2Attr); + String g2 = attributeWithoutSynchronization(SVGNames::g2Attr); if ((u1.isEmpty() && g1.isEmpty()) || (u2.isEmpty() && g2.isEmpty())) - return; + return false; - SVGKerningPair kerningPair; if (parseGlyphName(g1, kerningPair.glyphName1) && parseGlyphName(g2, kerningPair.glyphName2) && parseKerningUnicodeString(u1, kerningPair.unicodeRange1, kerningPair.unicodeName1) && parseKerningUnicodeString(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)) { - kerningPair.kerning = fastGetAttribute(SVGNames::kAttr).string().toFloat(); - kerningMap.insert(kerningPair); + bool ok = false; + kerningPair.kerning = attributeWithoutSynchronization(SVGNames::kAttr).string().toFloat(&ok); + return ok; } + return false; } } diff --git a/Source/WebCore/svg/SVGVKernElement.h b/Source/WebCore/svg/SVGVKernElement.h index ce88de5b4..37f7f46e1 100644 --- a/Source/WebCore/svg/SVGVKernElement.h +++ b/Source/WebCore/svg/SVGVKernElement.h @@ -17,10 +17,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGVKernElement_h -#define SVGVKernElement_h +#pragma once #if ENABLE(SVG_FONTS) + #include "SVGElement.h" #include "SVGFontElement.h" @@ -28,22 +28,16 @@ namespace WebCore { class SVGVKernElement final : public SVGElement { public: - static PassRefPtr<SVGVKernElement> create(const QualifiedName&, Document&); + static Ref<SVGVKernElement> create(const QualifiedName&, Document&); - void buildVerticalKerningPair(SVGKerningMap&); + bool buildVerticalKerningPair(SVGKerningPair& kerningPair) const; private: SVGVKernElement(const QualifiedName&, Document&); - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } }; -NODE_TYPE_CASTS(SVGVKernElement) - } // namespace WebCore #endif // ENABLE(SVG_FONTS) -#endif diff --git a/Source/WebCore/svg/SVGVKernElement.idl b/Source/WebCore/svg/SVGVKernElement.idl index 55a1648fa..7b3bd392a 100644 --- a/Source/WebCore/svg/SVGVKernElement.idl +++ b/Source/WebCore/svg/SVGVKernElement.idl @@ -18,7 +18,7 @@ */ [ - Conditional=SVG&SVG_FONTS + Conditional=SVG_FONTS ] interface SVGVKernElement : SVGElement { }; diff --git a/Source/WebCore/svg/SVGViewElement.cpp b/Source/WebCore/svg/SVGViewElement.cpp index fe038d987..04b7e8239 100644 --- a/Source/WebCore/svg/SVGViewElement.cpp +++ b/Source/WebCore/svg/SVGViewElement.cpp @@ -19,15 +19,10 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGViewElement.h" -#include "Attribute.h" -#include "SVGFitToViewBox.h" #include "SVGNames.h" #include "SVGStringList.h" -#include "SVGZoomAndPan.h" namespace WebCore { @@ -52,45 +47,25 @@ inline SVGViewElement::SVGViewElement(const QualifiedName& tagName, Document& do registerAnimatedPropertiesForSVGViewElement(); } -PassRefPtr<SVGViewElement> SVGViewElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGViewElement> SVGViewElement::create(const QualifiedName& tagName, Document& document) { - return adoptRef(new SVGViewElement(tagName, document)); + return adoptRef(*new SVGViewElement(tagName, document)); } -bool SVGViewElement::isSupportedAttribute(const QualifiedName& attrName) +Ref<SVGStringList> SVGViewElement::viewTarget() { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); - SVGFitToViewBox::addSupportedAttributes(supportedAttributes); - SVGZoomAndPan::addSupportedAttributes(supportedAttributes); - supportedAttributes.add(SVGNames::viewTargetAttr); - } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return SVGStringList::create(*this, m_viewTarget); } void SVGViewElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGElement::parseAttribute(name, value); - return; - } - - if (name == SVGNames::viewTargetAttr) { - viewTarget().reset(value); - return; - } + if (name == SVGNames::viewTargetAttr) + m_viewTarget.reset(value); - if (SVGExternalResourcesRequired::parseAttribute(name, value)) - return; - if (SVGFitToViewBox::parseAttribute(this, name, value)) - return; - if (SVGZoomAndPan::parseAttribute(this, name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGExternalResourcesRequired::parseAttribute(name, value); + SVGFitToViewBox::parseAttribute(this, name, value); + SVGZoomAndPan::parseAttribute(*this, name, value); + SVGElement::parseAttribute(name, value); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGViewElement.h b/Source/WebCore/svg/SVGViewElement.h index 35b954a8a..081cd1d49 100644 --- a/Source/WebCore/svg/SVGViewElement.h +++ b/Source/WebCore/svg/SVGViewElement.h @@ -18,32 +18,29 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGViewElement_h -#define SVGViewElement_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedBoolean.h" #include "SVGAnimatedPreserveAspectRatio.h" #include "SVGAnimatedRect.h" #include "SVGElement.h" #include "SVGExternalResourcesRequired.h" #include "SVGFitToViewBox.h" -#include "SVGStringList.h" +#include "SVGStringListValues.h" #include "SVGZoomAndPan.h" namespace WebCore { -class SVGViewElement final : public SVGElement, - public SVGExternalResourcesRequired, - public SVGFitToViewBox, - public SVGZoomAndPan { +class SVGStringList; + +class SVGViewElement final : public SVGElement, public SVGExternalResourcesRequired, public SVGFitToViewBox, public SVGZoomAndPan { public: - static PassRefPtr<SVGViewElement> create(const QualifiedName&, Document&); + static Ref<SVGViewElement> create(const QualifiedName&, Document&); using SVGElement::ref; using SVGElement::deref; - SVGStringList& viewTarget() { return m_viewTarget; } + Ref<SVGStringList> viewTarget(); SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; } void setZoomAndPan(unsigned short zoomAndPan) { m_zoomAndPan = SVGZoomAndPan::parseFromNumber(zoomAndPan); } @@ -51,24 +48,18 @@ private: SVGViewElement(const QualifiedName&, Document&); // FIXME: svgAttributeChanged missing. - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) final; - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) final { return false; } BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGViewElement) - DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) + DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) DECLARE_ANIMATED_RECT(ViewBox, viewBox) DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio) END_DECLARE_ANIMATED_PROPERTIES SVGZoomAndPanType m_zoomAndPan; - SVGStringList m_viewTarget; + SVGStringListValues m_viewTarget; }; -NODE_TYPE_CASTS(SVGViewElement) - } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGViewElement.idl b/Source/WebCore/svg/SVGViewElement.idl index 3b459e352..d71764789 100644 --- a/Source/WebCore/svg/SVGViewElement.idl +++ b/Source/WebCore/svg/SVGViewElement.idl @@ -23,10 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGViewElement : SVGElement { - readonly attribute SVGStringList viewTarget; +interface SVGViewElement : SVGElement { + [NewObject] readonly attribute SVGStringList viewTarget; }; SVGViewElement implements SVGExternalResourcesRequired; diff --git a/Source/WebCore/svg/SVGViewSpec.cpp b/Source/WebCore/svg/SVGViewSpec.cpp index ee2510c10..2b467db22 100644 --- a/Source/WebCore/svg/SVGViewSpec.cpp +++ b/Source/WebCore/svg/SVGViewSpec.cpp @@ -18,16 +18,15 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGViewSpec.h" #include "Document.h" #include "SVGAnimatedTransformList.h" +#include "SVGElement.h" #include "SVGFitToViewBox.h" #include "SVGNames.h" #include "SVGParserUtilities.h" -#include "SVGSVGElement.h" +#include "SVGTransformList.h" #include "SVGTransformable.h" namespace WebCore { @@ -35,7 +34,7 @@ namespace WebCore { // Define custom animated property 'viewBox'. const SVGPropertyInfo* SVGViewSpec::viewBoxPropertyInfo() { - static const SVGPropertyInfo* s_propertyInfo = 0; + static const SVGPropertyInfo* s_propertyInfo = nullptr; if (!s_propertyInfo) { s_propertyInfo = new SVGPropertyInfo(AnimatedRect, PropertyIsReadOnly, @@ -50,7 +49,7 @@ const SVGPropertyInfo* SVGViewSpec::viewBoxPropertyInfo() // Define custom animated property 'preserveAspectRatio'. const SVGPropertyInfo* SVGViewSpec::preserveAspectRatioPropertyInfo() { - static const SVGPropertyInfo* s_propertyInfo = 0; + static const SVGPropertyInfo* s_propertyInfo = nullptr; if (!s_propertyInfo) { s_propertyInfo = new SVGPropertyInfo(AnimatedPreserveAspectRatio, PropertyIsReadOnly, @@ -66,7 +65,7 @@ const SVGPropertyInfo* SVGViewSpec::preserveAspectRatioPropertyInfo() // Define custom non-animated property 'transform'. const SVGPropertyInfo* SVGViewSpec::transformPropertyInfo() { - static const SVGPropertyInfo* s_propertyInfo = 0; + static const SVGPropertyInfo* s_propertyInfo = nullptr; if (!s_propertyInfo) { s_propertyInfo = new SVGPropertyInfo(AnimatedTransformList, PropertyIsReadOnly, @@ -78,125 +77,109 @@ const SVGPropertyInfo* SVGViewSpec::transformPropertyInfo() return s_propertyInfo; } -SVGViewSpec::SVGViewSpec(SVGElement* contextElement) - : m_contextElement(contextElement) - , m_zoomAndPan(SVGZoomAndPanMagnify) +SVGViewSpec::SVGViewSpec(SVGElement& contextElement) + : m_contextElement(&contextElement) { - ASSERT(m_contextElement); } const AtomicString& SVGViewSpec::viewBoxIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGViewSpecViewBoxAttribute", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGViewSpecViewBoxAttribute", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGViewSpec::preserveAspectRatioIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGViewSpecPreserveAspectRatioAttribute", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGViewSpecPreserveAspectRatioAttribute", AtomicString::ConstructFromLiteral); return s_identifier; } const AtomicString& SVGViewSpec::transformIdentifier() { - DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGViewSpecTransformAttribute", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> s_identifier("SVGViewSpecTransformAttribute", AtomicString::ConstructFromLiteral); return s_identifier; } -void SVGViewSpec::setZoomAndPan(unsigned short, ExceptionCode& ec) +ExceptionOr<void> SVGViewSpec::setZoomAndPan(unsigned short) { // SVGViewSpec and all of its content is read-only. - ec = NO_MODIFICATION_ALLOWED_ERR; -} - -void SVGViewSpec::setTransformString(const String& transform) -{ - if (!m_contextElement) - return; - - SVGTransformList newList; - newList.parse(transform); - - if (SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGElement, SVGAnimatedTransformList>(m_contextElement, transformPropertyInfo())) - static_cast<SVGAnimatedTransformList*>(wrapper)->detachListWrappers(newList.size()); - - m_transform = newList; + return Exception { NO_MODIFICATION_ALLOWED_ERR }; } String SVGViewSpec::transformString() const { - return SVGPropertyTraits<SVGTransformList>::toString(m_transform); + return SVGPropertyTraits<SVGTransformListValues>::toString(m_transform); } String SVGViewSpec::viewBoxString() const { - return SVGPropertyTraits<FloatRect>::toString(viewBoxBaseValue()); + return SVGPropertyTraits<FloatRect>::toString(m_viewBox); } String SVGViewSpec::preserveAspectRatioString() const { - return SVGPropertyTraits<SVGPreserveAspectRatio>::toString(preserveAspectRatioBaseValue()); + return SVGPropertyTraits<SVGPreserveAspectRatioValue>::toString(m_preserveAspectRatio); } SVGElement* SVGViewSpec::viewTarget() const { if (!m_contextElement) - return 0; - Element* element = m_contextElement->treeScope().getElementById(m_viewTargetString); - if (!element || !element->isSVGElement()) - return 0; - return toSVGElement(element); + return nullptr; + auto* element = m_contextElement->treeScope().getElementById(m_viewTargetString); + if (!is<SVGElement>(element)) + return nullptr; + return downcast<SVGElement>(element); } -SVGTransformListPropertyTearOff* SVGViewSpec::transform() +RefPtr<SVGTransformList> SVGViewSpec::transform() { if (!m_contextElement) - return 0; + return nullptr; // Return the animVal here, as its readonly by default - which is exactly what we want here. - return static_cast<SVGTransformListPropertyTearOff*>(static_pointer_cast<SVGAnimatedTransformList>(lookupOrCreateTransformWrapper(this))->animVal()); + return static_reference_cast<SVGAnimatedTransformList>(lookupOrCreateTransformWrapper(this))->animVal(); } -PassRefPtr<SVGAnimatedRect> SVGViewSpec::viewBoxAnimated() +RefPtr<SVGAnimatedRect> SVGViewSpec::viewBoxAnimated() { if (!m_contextElement) - return 0; - return static_pointer_cast<SVGAnimatedRect>(lookupOrCreateViewBoxWrapper(this)); + return nullptr; + return static_reference_cast<SVGAnimatedRect>(lookupOrCreateViewBoxWrapper(this)); } -PassRefPtr<SVGAnimatedPreserveAspectRatio> SVGViewSpec::preserveAspectRatioAnimated() +RefPtr<SVGAnimatedPreserveAspectRatio> SVGViewSpec::preserveAspectRatioAnimated() { if (!m_contextElement) - return 0; - return static_pointer_cast<SVGAnimatedPreserveAspectRatio>(lookupOrCreatePreserveAspectRatioWrapper(this)); + return nullptr; + return static_reference_cast<SVGAnimatedPreserveAspectRatio>(lookupOrCreatePreserveAspectRatioWrapper(this)); } -PassRefPtr<SVGAnimatedProperty> SVGViewSpec::lookupOrCreateViewBoxWrapper(SVGViewSpec* ownerType) +Ref<SVGAnimatedProperty> SVGViewSpec::lookupOrCreateViewBoxWrapper(SVGViewSpec* ownerType) { ASSERT(ownerType); - ASSERT(ownerType->contextElement()); - return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedRect, FloatRect>(ownerType->contextElement(), viewBoxPropertyInfo(), ownerType->m_viewBox); + ASSERT(ownerType->m_contextElement); + return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedRect, FloatRect>(ownerType->m_contextElement, viewBoxPropertyInfo(), ownerType->m_viewBox); } -PassRefPtr<SVGAnimatedProperty> SVGViewSpec::lookupOrCreatePreserveAspectRatioWrapper(SVGViewSpec* ownerType) +Ref<SVGAnimatedProperty> SVGViewSpec::lookupOrCreatePreserveAspectRatioWrapper(SVGViewSpec* ownerType) { ASSERT(ownerType); - ASSERT(ownerType->contextElement()); - return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedPreserveAspectRatio, SVGPreserveAspectRatio>(ownerType->contextElement(), preserveAspectRatioPropertyInfo(), ownerType->m_preserveAspectRatio); + ASSERT(ownerType->m_contextElement); + return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedPreserveAspectRatio, SVGPreserveAspectRatioValue>(ownerType->m_contextElement, preserveAspectRatioPropertyInfo(), ownerType->m_preserveAspectRatio); } -PassRefPtr<SVGAnimatedProperty> SVGViewSpec::lookupOrCreateTransformWrapper(SVGViewSpec* ownerType) +Ref<SVGAnimatedProperty> SVGViewSpec::lookupOrCreateTransformWrapper(SVGViewSpec* ownerType) { ASSERT(ownerType); - ASSERT(ownerType->contextElement()); - return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedTransformList, SVGTransformList>(ownerType->contextElement(), transformPropertyInfo(), ownerType->m_transform); + ASSERT(ownerType->m_contextElement); + return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedTransformList, SVGTransformListValues>(ownerType->m_contextElement, transformPropertyInfo(), ownerType->m_transform); } void SVGViewSpec::reset() { m_zoomAndPan = SVGZoomAndPanMagnify; m_transform.clear(); - m_viewBox = FloatRect(); - m_preserveAspectRatio = SVGPreserveAspectRatio(); + m_viewBox = { }; + m_preserveAspectRatio = { }; m_viewTargetString = emptyString(); } @@ -209,7 +192,8 @@ static const UChar viewTargetSpec[] = {'v', 'i', 'e', 'w', 'T', 'a', 'r', 'g', bool SVGViewSpec::parseViewSpec(const String& viewSpec) { - const UChar* currViewSpec = viewSpec.deprecatedCharacters(); + auto upconvertedCharacters = StringView(viewSpec).upconvertedCharacters(); + const UChar* currViewSpec = upconvertedCharacters; const UChar* end = currViewSpec + viewSpec.length(); if (currViewSpec >= end || !m_contextElement) @@ -243,7 +227,7 @@ bool SVGViewSpec::parseViewSpec(const String& viewSpec) currViewSpec++; if (currViewSpec >= end) return false; - setViewTargetString(String(viewTargetStart, currViewSpec - viewTargetStart)); + m_viewTargetString = String(viewTargetStart, currViewSpec - viewTargetStart); currViewSpec++; } else return false; @@ -253,7 +237,7 @@ bool SVGViewSpec::parseViewSpec(const String& viewSpec) if (currViewSpec >= end || *currViewSpec != '(') return false; currViewSpec++; - if (!parseZoomAndPan(currViewSpec, end, m_zoomAndPan)) + if (!parse(currViewSpec, end, m_zoomAndPan)) return false; if (currViewSpec >= end || *currViewSpec != ')') return false; @@ -264,7 +248,7 @@ bool SVGViewSpec::parseViewSpec(const String& viewSpec) if (currViewSpec >= end || *currViewSpec != '(') return false; currViewSpec++; - SVGPreserveAspectRatio preserveAspectRatio; + SVGPreserveAspectRatioValue preserveAspectRatio; if (!preserveAspectRatio.parse(currViewSpec, end, false)) return false; setPreserveAspectRatioBaseValue(preserveAspectRatio); @@ -295,5 +279,3 @@ bool SVGViewSpec::parseViewSpec(const String& viewSpec) } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGViewSpec.h b/Source/WebCore/svg/SVGViewSpec.h index f8634afd6..9fb5d42be 100644 --- a/Source/WebCore/svg/SVGViewSpec.h +++ b/Source/WebCore/svg/SVGViewSpec.h @@ -17,75 +17,58 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGViewSpec_h -#define SVGViewSpec_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPreserveAspectRatio.h" #include "SVGAnimatedRect.h" #include "SVGFitToViewBox.h" -#include "SVGTransformList.h" +#include "SVGTransformListValues.h" #include "SVGZoomAndPan.h" namespace WebCore { class SVGElement; -class SVGTransformListPropertyTearOff; +class SVGTransformList; -class SVGViewSpec : public RefCounted<SVGViewSpec> - , public SVGZoomAndPan - , public SVGFitToViewBox { +class SVGViewSpec final : public RefCounted<SVGViewSpec>, public SVGZoomAndPan, public SVGFitToViewBox { public: - virtual ~SVGViewSpec() { } - - using RefCounted<SVGViewSpec>::ref; - using RefCounted<SVGViewSpec>::deref; - - static PassRefPtr<SVGViewSpec> create(SVGElement* contextElement) + static Ref<SVGViewSpec> create(SVGElement& contextElement) { - return adoptRef(new SVGViewSpec(contextElement)); + return adoptRef(*new SVGViewSpec(contextElement)); } bool parseViewSpec(const String&); void reset(); SVGElement* viewTarget() const; - String viewBoxString() const; - - String preserveAspectRatioString() const; - void setTransformString(const String&); String transformString() const; - - void setViewTargetString(const String& string) { m_viewTargetString = string; } - String viewTargetString() const { return m_viewTargetString; } + String viewBoxString() const; + String preserveAspectRatioString() const; + const String& viewTargetString() const { return m_viewTargetString; } SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; } - void setZoomAndPan(unsigned short zoomAndPan) { setZoomAndPanBaseValue(zoomAndPan); } - void setZoomAndPan(unsigned short, ExceptionCode&); + ExceptionOr<void> setZoomAndPan(unsigned short); void setZoomAndPanBaseValue(unsigned short zoomAndPan) { m_zoomAndPan = SVGZoomAndPan::parseFromNumber(zoomAndPan); } - SVGElement* contextElement() const { return m_contextElement; } - void resetContextElement() { m_contextElement = 0; } + void resetContextElement() { m_contextElement = nullptr; } // Custom non-animated 'transform' property. - SVGTransformListPropertyTearOff* transform(); - SVGTransformList transformBaseValue() const { return m_transform; } + RefPtr<SVGTransformList> transform(); + SVGTransformListValues transformBaseValue() const { return m_transform; } // Custom animated 'viewBox' property. - PassRefPtr<SVGAnimatedRect> viewBoxAnimated(); + RefPtr<SVGAnimatedRect> viewBoxAnimated(); FloatRect& viewBox() { return m_viewBox; } - FloatRect viewBoxBaseValue() const { return m_viewBox; } void setViewBoxBaseValue(const FloatRect& viewBox) { m_viewBox = viewBox; } // Custom animated 'preserveAspectRatio' property. - PassRefPtr<SVGAnimatedPreserveAspectRatio> preserveAspectRatioAnimated(); - SVGPreserveAspectRatio& preserveAspectRatio() { return m_preserveAspectRatio; } - SVGPreserveAspectRatio preserveAspectRatioBaseValue() const { return m_preserveAspectRatio; } - void setPreserveAspectRatioBaseValue(const SVGPreserveAspectRatio& preserveAspectRatio) { m_preserveAspectRatio = preserveAspectRatio; } + RefPtr<SVGAnimatedPreserveAspectRatio> preserveAspectRatioAnimated(); + SVGPreserveAspectRatioValue& preserveAspectRatio() { return m_preserveAspectRatio; } + void setPreserveAspectRatioBaseValue(const SVGPreserveAspectRatioValue& preserveAspectRatio) { m_preserveAspectRatio = preserveAspectRatio; } private: - SVGViewSpec(SVGElement*); + explicit SVGViewSpec(SVGElement&); static const SVGPropertyInfo* transformPropertyInfo(); static const SVGPropertyInfo* viewBoxPropertyInfo(); @@ -95,20 +78,16 @@ private: static const AtomicString& viewBoxIdentifier(); static const AtomicString& preserveAspectRatioIdentifier(); - static PassRefPtr<SVGAnimatedProperty> lookupOrCreateTransformWrapper(SVGViewSpec* contextElement); - static PassRefPtr<SVGAnimatedProperty> lookupOrCreateViewBoxWrapper(SVGViewSpec* contextElement); - static PassRefPtr<SVGAnimatedProperty> lookupOrCreatePreserveAspectRatioWrapper(SVGViewSpec* contextElement); + static Ref<SVGAnimatedProperty> lookupOrCreateTransformWrapper(SVGViewSpec* contextElement); + static Ref<SVGAnimatedProperty> lookupOrCreateViewBoxWrapper(SVGViewSpec* contextElement); + static Ref<SVGAnimatedProperty> lookupOrCreatePreserveAspectRatioWrapper(SVGViewSpec* contextElement); SVGElement* m_contextElement; - SVGZoomAndPanType m_zoomAndPan; - - SVGTransformList m_transform; + SVGZoomAndPanType m_zoomAndPan { SVGZoomAndPanMagnify }; + SVGTransformListValues m_transform; FloatRect m_viewBox; - SVGPreserveAspectRatio m_preserveAspectRatio; + SVGPreserveAspectRatioValue m_preserveAspectRatio; String m_viewTargetString; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif diff --git a/Source/WebCore/svg/SVGViewSpec.idl b/Source/WebCore/svg/SVGViewSpec.idl index 88558fde8..4441329ce 100644 --- a/Source/WebCore/svg/SVGViewSpec.idl +++ b/Source/WebCore/svg/SVGViewSpec.idl @@ -26,18 +26,18 @@ // SVGViewSpec intentionally doesn't inherit from SVGZoomAndPan & SVGFitToViewBox on the IDLs. // It would require that any of those classes would be RefCounted, and we want to avoid that. [ - Conditional=SVG, - JSGenerateToJSObject + ImplementationLacksVTable, + JSGenerateToJSObject, ] interface SVGViewSpec { - readonly attribute SVGTransformList transform; - readonly attribute SVGElement viewTarget; - readonly attribute DOMString viewBoxString; - readonly attribute DOMString preserveAspectRatioString; - readonly attribute DOMString transformString; - readonly attribute DOMString viewTargetString; + readonly attribute SVGTransformList transform; + readonly attribute SVGElement viewTarget; + readonly attribute DOMString viewBoxString; + readonly attribute DOMString preserveAspectRatioString; + readonly attribute DOMString transformString; + readonly attribute DOMString viewTargetString; - // SVGZoomAndPan - [SetterRaisesException] attribute unsigned short zoomAndPan; + // SVGZoomAndPan + [SetterMayThrowException] attribute unsigned short zoomAndPan; }; SVGViewSpec implements SVGFitToViewBox; diff --git a/Source/WebCore/svg/SVGZoomAndPan.cpp b/Source/WebCore/svg/SVGZoomAndPan.cpp index 813ebe76a..f15c8370b 100644 --- a/Source/WebCore/svg/SVGZoomAndPan.cpp +++ b/Source/WebCore/svg/SVGZoomAndPan.cpp @@ -19,33 +19,20 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGZoomAndPan.h" #include "SVGParserUtilities.h" namespace WebCore { -bool SVGZoomAndPan::isKnownAttribute(const QualifiedName& attrName) -{ - return attrName == SVGNames::zoomAndPanAttr; -} - -void SVGZoomAndPan::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) -{ - supportedAttributes.add(SVGNames::zoomAndPanAttr); -} - -static const UChar disable[] = {'d', 'i', 's', 'a', 'b', 'l', 'e'}; -static const UChar magnify[] = {'m', 'a', 'g', 'n', 'i', 'f', 'y'}; - -bool SVGZoomAndPan::parseZoomAndPan(const UChar*& start, const UChar* end, SVGZoomAndPanType& zoomAndPan) +bool SVGZoomAndPan::parse(const UChar*& start, const UChar* end, SVGZoomAndPanType& zoomAndPan) { + static const UChar disable[] = { 'd', 'i', 's', 'a', 'b', 'l', 'e' }; if (skipString(start, end, disable, WTF_ARRAY_LENGTH(disable))) { zoomAndPan = SVGZoomAndPanDisable; return true; } + static const UChar magnify[] = { 'm', 'a', 'g', 'n', 'i', 'f', 'y' }; if (skipString(start, end, magnify, WTF_ARRAY_LENGTH(magnify))) { zoomAndPan = SVGZoomAndPanMagnify; return true; @@ -53,21 +40,13 @@ bool SVGZoomAndPan::parseZoomAndPan(const UChar*& start, const UChar* end, SVGZo return false; } -NO_RETURN_DUE_TO_ASSERT void SVGZoomAndPan::ref() +SVGZoomAndPanType SVGZoomAndPan::parseAttributeValue(const AtomicString& value) { - ASSERT_NOT_REACHED(); + if (value == "disable") + return SVGZoomAndPanDisable; + if (value == "magnify") + return SVGZoomAndPanMagnify; + return SVGZoomAndPanUnknown; } -NO_RETURN_DUE_TO_ASSERT void SVGZoomAndPan::deref() -{ - ASSERT_NOT_REACHED(); -} - -NO_RETURN_DUE_TO_ASSERT void SVGZoomAndPan::setZoomAndPan(unsigned short) -{ - ASSERT_NOT_REACHED(); } - -} - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGZoomAndPan.h b/Source/WebCore/svg/SVGZoomAndPan.h index a29353c2e..2a3702b92 100644 --- a/Source/WebCore/svg/SVGZoomAndPan.h +++ b/Source/WebCore/svg/SVGZoomAndPan.h @@ -18,21 +18,14 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGZoomAndPan_h -#define SVGZoomAndPan_h +#pragma once -#if ENABLE(SVG) #include "QualifiedName.h" #include "SVGNames.h" -#include <wtf/HashSet.h> namespace WebCore { -enum SVGZoomAndPanType { - SVGZoomAndPanUnknown = 0, - SVGZoomAndPanDisable, - SVGZoomAndPanMagnify -}; +enum SVGZoomAndPanType { SVGZoomAndPanUnknown, SVGZoomAndPanDisable, SVGZoomAndPanMagnify }; class SVGZoomAndPan { public: @@ -44,43 +37,32 @@ public: }; static bool isKnownAttribute(const QualifiedName&); - static void addSupportedAttributes(HashSet<QualifiedName>&); - static SVGZoomAndPanType parseFromNumber(unsigned short number) - { - if (!number || number > SVGZoomAndPanMagnify) - return SVGZoomAndPanUnknown; - return static_cast<SVGZoomAndPanType>(number); - } + static SVGZoomAndPanType parseFromNumber(unsigned short); - static bool parseZoomAndPan(const UChar*& start, const UChar* end, SVGZoomAndPanType&); + static bool parse(const UChar*& start, const UChar* end, SVGZoomAndPanType&); + template<class DerivedClass> static void parseAttribute(DerivedClass&, const QualifiedName&, const AtomicString& value); - template<class SVGElementTarget> - static bool parseAttribute(SVGElementTarget* target, const QualifiedName& name, const AtomicString& value) - { - ASSERT(target); - if (name == SVGNames::zoomAndPanAttr) { - const UChar* start = value.string().deprecatedCharacters(); - const UChar* end = start + value.length(); - SVGZoomAndPanType zoomAndPan = SVGZoomAndPanUnknown; - parseZoomAndPan(start, end, zoomAndPan); - target->setZoomAndPan(zoomAndPan); - return true; - } +private: + static SVGZoomAndPanType parseAttributeValue(const AtomicString&); +}; - return false; - } +inline bool SVGZoomAndPan::isKnownAttribute(const QualifiedName& name) +{ + return name == SVGNames::zoomAndPanAttr; +} - SVGZoomAndPanType zoomAndPan() const { return SVGZoomAndPanUnknown; } +inline SVGZoomAndPanType SVGZoomAndPan::parseFromNumber(unsigned short number) +{ + if (number > SVGZoomAndPanMagnify) + return SVGZoomAndPanUnknown; + return static_cast<SVGZoomAndPanType>(number); +} - // These methods only exist to allow us to compile JSSVGZoomAndPan.*. - // These are never called, and thus ASSERT_NOT_REACHED. - void ref(); - void deref(); - void setZoomAndPan(unsigned short); -}; +template<class DerivedClass> void SVGZoomAndPan::parseAttribute(DerivedClass& element, const QualifiedName& name, const AtomicString& value) +{ + if (name == SVGNames::zoomAndPanAttr) + element.setZoomAndPan(parseAttributeValue(value)); +} } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGZoomAndPan_h diff --git a/Source/WebCore/svg/SVGZoomAndPan.idl b/Source/WebCore/svg/SVGZoomAndPan.idl index 5b1c9b090..63c0834d9 100644 --- a/Source/WebCore/svg/SVGZoomAndPan.idl +++ b/Source/WebCore/svg/SVGZoomAndPan.idl @@ -26,8 +26,6 @@ [ NoInterfaceObject, - Conditional=SVG, - ObjCProtocol ] interface SVGZoomAndPan { const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0; const unsigned short SVG_ZOOMANDPAN_DISABLE = 1; @@ -35,4 +33,3 @@ attribute unsigned short zoomAndPan; }; - diff --git a/Source/WebCore/svg/SVGZoomEvent.cpp b/Source/WebCore/svg/SVGZoomEvent.cpp index 4ffde5f59..87ca4cebb 100644 --- a/Source/WebCore/svg/SVGZoomEvent.cpp +++ b/Source/WebCore/svg/SVGZoomEvent.cpp @@ -20,11 +20,10 @@ */ #include "config.h" - -#if ENABLE(SVG) - #include "SVGZoomEvent.h" -#include "EventNames.h" + +#include "SVGPoint.h" +#include "SVGRect.h" namespace WebCore { @@ -34,9 +33,9 @@ SVGZoomEvent::SVGZoomEvent() { } -FloatRect SVGZoomEvent::zoomRectScreen() const +Ref<SVGRect> SVGZoomEvent::zoomRectScreen() const { - return m_zoomRectScreen; + return SVGRect::create(m_zoomRectScreen); } float SVGZoomEvent::previousScale() const @@ -49,9 +48,9 @@ void SVGZoomEvent::setPreviousScale(float scale) m_previousScale = scale; } -SVGPoint SVGZoomEvent::previousTranslate() const +Ref<SVGPoint> SVGZoomEvent::previousTranslate() const { - return m_previousTranslate; + return SVGPoint::create(m_previousTranslate); } float SVGZoomEvent::newScale() const @@ -64,9 +63,9 @@ void SVGZoomEvent::setNewScale(float scale) m_newScale = scale; } -SVGPoint SVGZoomEvent::newTranslate() const +Ref<SVGPoint> SVGZoomEvent::newTranslate() const { - return m_newTranslate; + return SVGPoint::create(m_newTranslate); } EventInterface SVGZoomEvent::eventInterface() const @@ -75,5 +74,3 @@ EventInterface SVGZoomEvent::eventInterface() const } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/SVGZoomEvent.h b/Source/WebCore/svg/SVGZoomEvent.h index 6e29dfd52..d7e3fd1ed 100644 --- a/Source/WebCore/svg/SVGZoomEvent.h +++ b/Source/WebCore/svg/SVGZoomEvent.h @@ -19,34 +19,34 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGZoomEvent_h -#define SVGZoomEvent_h -#if ENABLE(SVG) +#pragma once #include "FloatRect.h" -#include "SVGPoint.h" #include "UIEvent.h" namespace WebCore { -class SVGZoomEvent : public UIEvent { +class SVGPoint; +class SVGRect; + +class SVGZoomEvent final : public UIEvent { public: - static PassRefPtr<SVGZoomEvent> create() { return adoptRef(new SVGZoomEvent); } + static Ref<SVGZoomEvent> createForBindings() { return adoptRef(*new SVGZoomEvent); } // 'SVGZoomEvent' functions - FloatRect zoomRectScreen() const; + Ref<SVGRect> zoomRectScreen() const; float previousScale() const; void setPreviousScale(float); - SVGPoint previousTranslate() const; + Ref<SVGPoint> previousTranslate() const; float newScale() const; void setNewScale(float); - SVGPoint newTranslate() const; + Ref<SVGPoint> newTranslate() const; - virtual EventInterface eventInterface() const override; + EventInterface eventInterface() const final; private: SVGZoomEvent(); @@ -56,13 +56,8 @@ private: FloatRect m_zoomRectScreen; - SVGPoint m_newTranslate; - SVGPoint m_previousTranslate; + FloatPoint m_newTranslate; + FloatPoint m_previousTranslate; }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGZoomEvent_h - -// vim:ts=4:noet diff --git a/Source/WebCore/svg/SVGZoomEvent.idl b/Source/WebCore/svg/SVGZoomEvent.idl index 320e55250..2d8f8d0cd 100644 --- a/Source/WebCore/svg/SVGZoomEvent.idl +++ b/Source/WebCore/svg/SVGZoomEvent.idl @@ -23,13 +23,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -[ - Conditional=SVG -] interface SVGZoomEvent : UIEvent { - readonly attribute SVGRect zoomRectScreen; - readonly attribute float previousScale; +interface SVGZoomEvent : UIEvent { + [NewObject] readonly attribute SVGRect zoomRectScreen; + readonly attribute unrestricted float previousScale; [Immutable] readonly attribute SVGPoint previousTranslate; - readonly attribute float newScale; + readonly attribute unrestricted float newScale; [Immutable] readonly attribute SVGPoint newTranslate; }; diff --git a/Source/WebCore/svg/animation/SMILTime.cpp b/Source/WebCore/svg/animation/SMILTime.cpp index 2b1f19e5d..3e3d70771 100644 --- a/Source/WebCore/svg/animation/SMILTime.cpp +++ b/Source/WebCore/svg/animation/SMILTime.cpp @@ -24,7 +24,6 @@ */ #include "config.h" -#if ENABLE(SVG) #include "SMILTime.h" #include <float.h> @@ -63,5 +62,3 @@ SMILTime WebCore::operator*(const SMILTime& a, const SMILTime& b) return SMILTime::indefinite(); return a.value() * b.value(); } -#endif - diff --git a/Source/WebCore/svg/animation/SMILTime.h b/Source/WebCore/svg/animation/SMILTime.h index 4e7f5e263..e79b5b34f 100644 --- a/Source/WebCore/svg/animation/SMILTime.h +++ b/Source/WebCore/svg/animation/SMILTime.h @@ -23,16 +23,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SMILTime_h -#define SMILTime_h - -#if ENABLE(SVG) +#pragma once #include <algorithm> -#include <wtf/MathExtras.h> +#include <cmath> namespace WebCore { +const double SMILAnimationFrameDelay = 1.0 / 60; + class SMILTime { public: SMILTime() : m_time(0) { } @@ -96,7 +95,4 @@ SMILTime operator-(const SMILTime&, const SMILTime&); // So multiplying times does not make too much sense but SMIL defines it for duration * repeatCount SMILTime operator*(const SMILTime&, const SMILTime&); -} - -#endif // ENABLE(SVG) -#endif // SMILTime_h +} // namespace WebCore diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.cpp b/Source/WebCore/svg/animation/SMILTimeContainer.cpp index 25529d692..333f7a17d 100644 --- a/Source/WebCore/svg/animation/SMILTimeContainer.cpp +++ b/Source/WebCore/svg/animation/SMILTimeContainer.cpp @@ -26,18 +26,14 @@ #include "config.h" #include "SMILTimeContainer.h" -#if ENABLE(SVG) #include "Document.h" #include "ElementIterator.h" -#include "SVGNames.h" #include "SVGSMILElement.h" #include "SVGSVGElement.h" #include <wtf/CurrentTime.h> namespace WebCore { -static const double animationFrameDelay = 0.025; - SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner) : m_beginTime(0) , m_pauseTime(0) @@ -45,7 +41,7 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner) , m_resumeTime(0) , m_presetStartTime(0) , m_documentOrderIndexesDirty(false) - , m_timer(this, &SMILTimeContainer::timerFired) + , m_timer(*this, &SMILTimeContainer::timerFired) , m_ownerSVGElement(owner) #ifndef NDEBUG , m_preventScheduledAnimationsChanges(false) @@ -93,16 +89,15 @@ void SMILTimeContainer::unschedule(SVGSMILElement* animation, SVGElement* target ElementAttributePair key(target, attributeName); AnimationsVector* scheduled = m_scheduledAnimations.get(key); ASSERT(scheduled); - size_t idx = scheduled->find(animation); - ASSERT(idx != notFound); - scheduled->remove(idx); + bool removed = scheduled->removeFirst(animation); + ASSERT_UNUSED(removed, removed); } void SMILTimeContainer::notifyIntervalsChanged() { // Schedule updateAnimations() to be called asynchronously so multiple intervals // can change with updateAnimations() only called once at the end. - startTimer(0); + startTimer(elapsed(), 0); } SMILTime SMILTimeContainer::elapsed() const @@ -163,7 +158,7 @@ void SMILTimeContainer::resume() m_resumeTime = monotonicallyIncreasingTime(); m_pauseTime = 0; - startTimer(0); + startTimer(elapsed(), 0); } void SMILTimeContainer::setElapsed(SMILTime time) @@ -189,12 +184,9 @@ void SMILTimeContainer::setElapsed(SMILTime time) #ifndef NDEBUG m_preventScheduledAnimationsChanges = true; #endif - GroupedAnimationsMap::iterator end = m_scheduledAnimations.end(); - for (GroupedAnimationsMap::iterator it = m_scheduledAnimations.begin(); it != end; ++it) { - AnimationsVector* scheduled = it->value.get(); - unsigned size = scheduled->size(); - for (unsigned n = 0; n < size; n++) - scheduled->at(n)->reset(); + for (auto& animation : m_scheduledAnimations.values()) { + for (auto& element : *animation) + element->reset(); } #ifndef NDEBUG m_preventScheduledAnimationsChanges = false; @@ -203,7 +195,7 @@ void SMILTimeContainer::setElapsed(SMILTime time) updateAnimations(time, true); } -void SMILTimeContainer::startTimer(SMILTime fireTime, SMILTime minimumDelay) +void SMILTimeContainer::startTimer(SMILTime elapsed, SMILTime fireTime, SMILTime minimumDelay) { if (!m_beginTime || isPaused()) return; @@ -211,11 +203,11 @@ void SMILTimeContainer::startTimer(SMILTime fireTime, SMILTime minimumDelay) if (!fireTime.isFinite()) return; - SMILTime delay = std::max(fireTime - elapsed(), minimumDelay); + SMILTime delay = std::max(fireTime - elapsed, minimumDelay); m_timer.startOneShot(delay.value()); } -void SMILTimeContainer::timerFired(Timer<SMILTimeContainer>*) +void SMILTimeContainer::timerFired() { ASSERT(m_beginTime); ASSERT(!m_pauseTime); @@ -267,9 +259,16 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime) #endif AnimationsVector animationsToApply; - GroupedAnimationsMap::iterator end = m_scheduledAnimations.end(); - for (GroupedAnimationsMap::iterator it = m_scheduledAnimations.begin(); it != end; ++it) { - AnimationsVector* scheduled = it->value.get(); + for (auto& it : m_scheduledAnimations) { + AnimationsVector* scheduled = it.value.get(); + for (auto* animation : *scheduled) { + if (!animation->hasConditionsConnected()) + animation->connectConditions(); + } + } + + for (auto& it : m_scheduledAnimations) { + AnimationsVector* scheduled = it.value.get(); // Sort according to priority. Elements with later begin time have higher priority. // In case of a tie, document order decides. @@ -277,10 +276,8 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime) // have higher priority. sortByPriority(*scheduled, elapsed); - SVGSMILElement* resultElement = 0; - unsigned size = scheduled->size(); - for (unsigned n = 0; n < size; n++) { - SVGSMILElement* animation = scheduled->at(n); + SVGSMILElement* resultElement = nullptr; + for (auto& animation : *scheduled) { ASSERT(animation->timeContainer() == this); ASSERT(animation->targetElement()); ASSERT(animation->hasValidAttributeName()); @@ -294,7 +291,7 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime) // This will calculate the contribution from the animation and add it to the resultsElement. if (!animation->progress(elapsed, resultElement, seekToTime) && resultElement == animation) - resultElement = 0; + resultElement = nullptr; SMILTime nextFireTime = animation->nextProgressTime(); if (nextFireTime.isFinite()) @@ -305,26 +302,23 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime) animationsToApply.append(resultElement); } - unsigned animationsToApplySize = animationsToApply.size(); - if (!animationsToApplySize) { + if (animationsToApply.isEmpty()) { #ifndef NDEBUG m_preventScheduledAnimationsChanges = false; #endif - startTimer(earliestFireTime, animationFrameDelay); + startTimer(elapsed, earliestFireTime, SMILAnimationFrameDelay); return; } // Apply results to target elements. - for (unsigned i = 0; i < animationsToApplySize; ++i) - animationsToApply[i]->applyResultsToTarget(); + for (auto& animation : animationsToApply) + animation->applyResultsToTarget(); #ifndef NDEBUG m_preventScheduledAnimationsChanges = false; #endif - startTimer(earliestFireTime, animationFrameDelay); + startTimer(elapsed, earliestFireTime, SMILAnimationFrameDelay); } } - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/animation/SMILTimeContainer.h b/Source/WebCore/svg/animation/SMILTimeContainer.h index 4a3efa096..861665efa 100644 --- a/Source/WebCore/svg/animation/SMILTimeContainer.h +++ b/Source/WebCore/svg/animation/SMILTimeContainer.h @@ -23,17 +23,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SMILTimeContainer_h -#define SMILTimeContainer_h - -#if ENABLE(SVG) +#pragma once #include "QualifiedName.h" #include "SMILTime.h" #include "Timer.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> @@ -44,9 +40,9 @@ class SVGElement; class SVGSMILElement; class SVGSVGElement; -class SMILTimeContainer : public RefCounted<SMILTimeContainer> { +class SMILTimeContainer final : public RefCounted<SMILTimeContainer> { public: - static PassRefPtr<SMILTimeContainer> create(SVGSVGElement* owner) { return adoptRef(new SMILTimeContainer(owner)); } + static Ref<SMILTimeContainer> create(SVGSVGElement* owner) { return adoptRef(*new SMILTimeContainer(owner)); } ~SMILTimeContainer(); void schedule(SVGSMILElement*, SVGElement*, const QualifiedName&); @@ -69,8 +65,8 @@ public: private: SMILTimeContainer(SVGSVGElement* owner); - void timerFired(Timer<SMILTimeContainer>*); - void startTimer(SMILTime fireTime, SMILTime minimumDelay = 0); + void timerFired(); + void startTimer(SMILTime elapsed, SMILTime fireTime, SMILTime minimumDelay = 0); void updateAnimations(SMILTime elapsed, bool seekToTime = false); void updateDocumentOrderIndexes(); @@ -84,7 +80,7 @@ private: bool m_documentOrderIndexesDirty; - Timer<SMILTimeContainer> m_timer; + Timer m_timer; typedef std::pair<SVGElement*, QualifiedName> ElementAttributePair; typedef Vector<SVGSMILElement*> AnimationsVector; @@ -97,7 +93,5 @@ private: bool m_preventScheduledAnimationsChanges; #endif }; -} -#endif // ENABLE(SVG) -#endif // SMILTimeContainer_h +} // namespace WebCore diff --git a/Source/WebCore/svg/animation/SVGSMILElement.cpp b/Source/WebCore/svg/animation/SVGSMILElement.cpp index a1df1f81e..2551af600 100644 --- a/Source/WebCore/svg/animation/SVGSMILElement.cpp +++ b/Source/WebCore/svg/animation/SVGSMILElement.cpp @@ -24,18 +24,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGSMILElement.h" -#include "Attribute.h" #include "CSSPropertyNames.h" #include "Document.h" #include "Event.h" #include "EventListener.h" +#include "EventNames.h" +#include "EventSender.h" #include "FloatConversion.h" #include "FrameView.h" -#include "HTMLNames.h" #include "SMILTimeContainer.h" #include "SVGDocumentExtensions.h" #include "SVGNames.h" @@ -48,29 +46,41 @@ #include <wtf/Vector.h> namespace WebCore { - + +static SMILEventSender& smilBeginEventSender() +{ + static NeverDestroyed<SMILEventSender> sender(eventNames().beginEventEvent); + return sender; +} + +static SMILEventSender& smilEndEventSender() +{ + static NeverDestroyed<SMILEventSender> sender(eventNames().endEventEvent); + return sender; +} + // This is used for duration type time values that can't be negative. static const double invalidCachedTime = -1.; -class ConditionEventListener : public EventListener { +class ConditionEventListener final : public EventListener { public: - static PassRefPtr<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition) + static Ref<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition) { - return adoptRef(new ConditionEventListener(animation, condition)); + return adoptRef(*new ConditionEventListener(animation, condition)); } static const ConditionEventListener* cast(const EventListener* listener) { return listener->type() == ConditionEventListenerType ? static_cast<const ConditionEventListener*>(listener) - : 0; + : nullptr; } - virtual bool operator==(const EventListener& other) override; + bool operator==(const EventListener& other) const final; void disconnectAnimation() { - m_animation = 0; + m_animation = nullptr; } private: @@ -81,13 +91,13 @@ private: { } - virtual void handleEvent(ScriptExecutionContext*, Event*) override; + void handleEvent(ScriptExecutionContext*, Event*) final; SVGSMILElement* m_animation; SVGSMILElement::Condition* m_condition; }; -bool ConditionEventListener::operator==(const EventListener& listener) +bool ConditionEventListener::operator==(const EventListener& listener) const { if (const ConditionEventListener* conditionEventListener = ConditionEventListener::cast(&listener)) return m_animation == conditionEventListener->m_animation && m_condition == conditionEventListener->m_condition; @@ -114,7 +124,7 @@ SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) : SVGElement(tagName, doc) , m_attributeName(anyQName()) - , m_targetElement(0) + , m_targetElement(nullptr) , m_conditionsConnected(false) , m_hasEndEventConditions(false) , m_isWaitingForFirstInterval(true) @@ -138,6 +148,8 @@ SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) SVGSMILElement::~SVGSMILElement() { clearResourceReferences(); + smilBeginEventSender().cancelEvent(*this); + smilEndEventSender().cancelEvent(*this); disconnectConditions(); if (m_timeContainer && m_targetElement && hasValidAttributeName()) m_timeContainer->unschedule(this, m_targetElement, m_attributeName); @@ -145,16 +157,21 @@ SVGSMILElement::~SVGSMILElement() void SVGSMILElement::clearResourceReferences() { - document().accessSVGExtensions()->removeAllTargetReferencesForElement(this); + document().accessSVGExtensions().removeAllTargetReferencesForElement(this); +} + +void SVGSMILElement::clearTarget() +{ + setTargetElement(nullptr); } void SVGSMILElement::buildPendingResource() { clearResourceReferences(); - if (!inDocument()) { + if (!isConnected()) { // Reset the target element if we are no longer in the document. - setTargetElement(0); + setTargetElement(nullptr); return; } @@ -162,59 +179,62 @@ void SVGSMILElement::buildPendingResource() String href = getAttribute(XLinkNames::hrefAttr); Element* target; if (href.isEmpty()) - target = parentNode() && parentNode()->isElementNode() ? toElement(parentNode()) : 0; + target = is<Element>(parentNode()) ? downcast<Element>(parentNode()) : nullptr; else target = SVGURIReference::targetElementFromIRIString(href, document(), &id); - SVGElement* svgTarget = target && target->isSVGElement() ? toSVGElement(target) : 0; + SVGElement* svgTarget = is<SVGElement>(target) ? downcast<SVGElement>(target) : nullptr; - if (svgTarget && !svgTarget->inDocument()) - svgTarget = 0; + if (svgTarget && !svgTarget->isConnected()) + svgTarget = nullptr; if (svgTarget != targetElement()) setTargetElement(svgTarget); if (!svgTarget) { // Do not register as pending if we are already pending this resource. - if (document().accessSVGExtensions()->isPendingResource(this, id)) + if (document().accessSVGExtensions().isPendingResource(this, id)) return; if (!id.isEmpty()) { - document().accessSVGExtensions()->addPendingResource(id, this); + document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); } } else { // Register us with the target in the dependencies map. Any change of hrefElement // that leads to relayout/repainting now informs us, so we can react to it. - document().accessSVGExtensions()->addElementReferencingTarget(this, svgTarget); + document().accessSVGExtensions().addElementReferencingTarget(this, svgTarget); } } -static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const String& attributeName) +inline QualifiedName SVGSMILElement::constructAttributeName() const { - ASSERT(svgElement); - if (attributeName.isEmpty()) + auto parseResult = Document::parseQualifiedName(attributeWithoutSynchronization(SVGNames::attributeNameAttr)); + if (parseResult.hasException()) return anyQName(); - if (!attributeName.contains(':')) - return QualifiedName(nullAtom, attributeName, nullAtom); - - String prefix; - String localName; - if (!Document::parseQualifiedName(attributeName, prefix, localName, ASSERT_NO_EXCEPTION)) - return anyQName(); - - String namespaceURI = svgElement->lookupNamespaceURI(prefix); + + AtomicString prefix, localName; + std::tie(prefix, localName) = parseResult.releaseReturnValue(); + + if (prefix.isNull()) + return { nullAtom, localName, nullAtom }; + + auto namespaceURI = lookupNamespaceURI(prefix); if (namespaceURI.isEmpty()) return anyQName(); - - return QualifiedName(nullAtom, localName, namespaceURI); + + return { nullAtom, localName, namespaceURI }; +} + +inline void SVGSMILElement::updateAttributeName() +{ + setAttributeName(constructAttributeName()); } static inline void clearTimesWithDynamicOrigins(Vector<SMILTimeWithOrigin>& timeList) { - for (int i = timeList.size() - 1; i >= 0; --i) { - if (timeList[i].originIsScript()) - timeList.remove(i); - } + timeList.removeAllMatching([] (const SMILTimeWithOrigin& time) { + return time.originIsScript(); + }); } void SVGSMILElement::reset() @@ -235,23 +255,23 @@ void SVGSMILElement::reset() Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode& rootParent) { SVGElement::insertedInto(rootParent); - if (!rootParent.inDocument()) + if (!rootParent.isConnected()) return InsertionDone; // Verify we are not in <use> instance tree. ASSERT(!isInShadowTree()); - setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr))); + updateAttributeName(); + SVGSVGElement* owner = ownerSVGElement(); if (!owner) return InsertionDone; - m_timeContainer = owner->timeContainer(); - ASSERT(m_timeContainer); + m_timeContainer = &owner->timeContainer(); m_timeContainer->setDocumentOrderIndexesDirty(); // "If no attribute is present, the default begin value (an offset-value of 0) must be evaluated." - if (!fastHasAttribute(SVGNames::beginAttr)) + if (!hasAttributeWithoutSynchronization(SVGNames::beginAttr)) m_beginTimes.append(SMILTimeWithOrigin()); if (m_isWaitingForFirstInterval) @@ -260,20 +280,23 @@ Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode& r if (m_timeContainer) m_timeContainer->notifyIntervalsChanged(); - buildPendingResource(); + return InsertionShouldCallFinishedInsertingSubtree; +} - return InsertionDone; +void SVGSMILElement::finishedInsertingSubtree() +{ + buildPendingResource(); } void SVGSMILElement::removedFrom(ContainerNode& rootParent) { - if (rootParent.inDocument()) { + if (rootParent.isConnected()) { clearResourceReferences(); disconnectConditions(); - setTargetElement(0); + setTargetElement(nullptr); setAttributeName(anyQName()); animationAttributeChanged(); - m_timeContainer = 0; + m_timeContainer = nullptr; } SVGElement::removedFrom(rootParent); @@ -299,7 +322,7 @@ SMILTime SVGSMILElement::parseOffsetValue(const String& data) result = parse.left(parse.length() - 1).toDouble(&ok); else result = parse.toDouble(&ok); - if (!ok) + if (!ok || !SMILTime(result).isFinite()) return SMILTime::unresolved(); return result; } @@ -311,7 +334,7 @@ SMILTime SVGSMILElement::parseClockValue(const String& data) String parse = data.stripWhiteSpace(); - DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> indefiniteValue("indefinite", AtomicString::ConstructFromLiteral); if (parse == indefiniteValue) return SMILTime::indefinite(); @@ -335,7 +358,7 @@ SMILTime SVGSMILElement::parseClockValue(const String& data) } else return parseOffsetValue(parse); - if (!ok) + if (!ok || !SMILTime(result).isFinite()) return SMILTime::unresolved(); return result; } @@ -418,14 +441,14 @@ void SVGSMILElement::parseBeginOrEnd(const String& parseString, BeginOrEnd begin if (beginOrEnd == End) m_hasEndEventConditions = false; HashSet<double> existing; - for (unsigned n = 0; n < timeList.size(); ++n) - existing.add(timeList[n].time().value()); + for (auto& time : timeList) + existing.add(time.time().value()); Vector<String> splitString; parseString.split(';', splitString); - for (unsigned n = 0; n < splitString.size(); ++n) { - SMILTime value = parseClockValue(splitString[n]); + for (auto& string : splitString) { + SMILTime value = parseClockValue(string); if (value.isUnresolved()) - parseCondition(splitString[n], beginOrEnd); + parseCondition(string, beginOrEnd); else if (!existing.contains(value.value())) timeList.append(SMILTimeWithOrigin(value, SMILTimeWithOrigin::ParserOrigin)); } @@ -434,19 +457,19 @@ void SVGSMILElement::parseBeginOrEnd(const String& parseString, BeginOrEnd begin bool SVGSMILElement::isSupportedAttribute(const QualifiedName& attrName) { - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) { - supportedAttributes.add(SVGNames::beginAttr); - supportedAttributes.add(SVGNames::endAttr); - supportedAttributes.add(SVGNames::durAttr); - supportedAttributes.add(SVGNames::repeatDurAttr); - supportedAttributes.add(SVGNames::repeatCountAttr); - supportedAttributes.add(SVGNames::minAttr); - supportedAttributes.add(SVGNames::maxAttr); - supportedAttributes.add(SVGNames::attributeNameAttr); - supportedAttributes.add(XLinkNames::hrefAttr); + static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; + if (supportedAttributes.get().isEmpty()) { + supportedAttributes.get().add(SVGNames::beginAttr); + supportedAttributes.get().add(SVGNames::endAttr); + supportedAttributes.get().add(SVGNames::durAttr); + supportedAttributes.get().add(SVGNames::repeatDurAttr); + supportedAttributes.get().add(SVGNames::repeatCountAttr); + supportedAttributes.get().add(SVGNames::minAttr); + supportedAttributes.get().add(SVGNames::maxAttr); + supportedAttributes.get().add(SVGNames::attributeNameAttr); + supportedAttributes.get().add(XLinkNames::hrefAttr); } - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); } void SVGSMILElement::parseAttribute(const QualifiedName& name, const AtomicString& value) @@ -455,21 +478,25 @@ void SVGSMILElement::parseAttribute(const QualifiedName& name, const AtomicStrin if (!m_conditions.isEmpty()) { disconnectConditions(); m_conditions.clear(); - parseBeginOrEnd(fastGetAttribute(SVGNames::endAttr), End); + parseBeginOrEnd(attributeWithoutSynchronization(SVGNames::endAttr), End); } parseBeginOrEnd(value.string(), Begin); - if (inDocument()) + if (isConnected()) connectConditions(); } else if (name == SVGNames::endAttr) { if (!m_conditions.isEmpty()) { disconnectConditions(); m_conditions.clear(); - parseBeginOrEnd(fastGetAttribute(SVGNames::beginAttr), Begin); + parseBeginOrEnd(attributeWithoutSynchronization(SVGNames::beginAttr), Begin); } parseBeginOrEnd(value.string(), End); - if (inDocument()) + if (isConnected()) connectConditions(); - } else + } else if (name == SVGNames::onendAttr) + setAttributeEventListener(eventNames().endEventEvent, name, value); + else if (name == SVGNames::onbeginAttr) + setAttributeEventListener(eventNames().beginEventEvent, name, value); + else SVGElement::parseAttribute(name, value); } @@ -491,11 +518,11 @@ void SVGSMILElement::svgAttributeChanged(const QualifiedName& attrName) else if (attrName == SVGNames::maxAttr) m_cachedMax = invalidCachedTime; else if (attrName == SVGNames::attributeNameAttr) - setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr))); + updateAttributeName(); else if (attrName.matches(XLinkNames::hrefAttr)) { - SVGElementInstance::InvalidationGuard invalidationGuard(this); + InstanceInvalidationGuard guard(*this); buildPendingResource(); - } else if (inDocument()) { + } else if (isConnected()) { if (attrName == SVGNames::beginAttr) beginListChanged(elapsed()); else if (attrName == SVGNames::endAttr) @@ -515,8 +542,7 @@ void SVGSMILElement::connectConditions() if (m_conditionsConnected) disconnectConditions(); m_conditionsConnected = true; - for (unsigned n = 0; n < m_conditions.size(); ++n) { - Condition& condition = m_conditions[n]; + for (auto& condition : m_conditions) { if (condition.m_type == Condition::EventBase) { ASSERT(!condition.m_syncbase); Element* eventBase = eventBaseFor(condition); @@ -524,17 +550,17 @@ void SVGSMILElement::connectConditions() continue; ASSERT(!condition.m_eventListener); condition.m_eventListener = ConditionEventListener::create(this, &condition); - eventBase->addEventListener(condition.m_name, condition.m_eventListener, false); + eventBase->addEventListener(condition.m_name, *condition.m_eventListener, false); } else if (condition.m_type == Condition::Syncbase) { ASSERT(!condition.m_baseID.isEmpty()); condition.m_syncbase = treeScope().getElementById(condition.m_baseID); if (!condition.m_syncbase) continue; - if (!isSVGSMILElement(*condition.m_syncbase)) { + if (!is<SVGSMILElement>(*condition.m_syncbase)) { condition.m_syncbase = nullptr; continue; } - toSVGSMILElement(*condition.m_syncbase).addTimeDependent(this); + downcast<SVGSMILElement>(*condition.m_syncbase).addTimeDependent(this); } } } @@ -544,8 +570,7 @@ void SVGSMILElement::disconnectConditions() if (!m_conditionsConnected) return; m_conditionsConnected = false; - for (unsigned n = 0; n < m_conditions.size(); ++n) { - Condition& condition = m_conditions[n]; + for (auto& condition : m_conditions) { if (condition.m_type == Condition::EventBase) { ASSERT(!condition.m_syncbase); if (!condition.m_eventListener) @@ -557,14 +582,14 @@ void SVGSMILElement::disconnectConditions() // our condition event listener, in case it later fires. Element* eventBase = eventBaseFor(condition); if (eventBase) - eventBase->removeEventListener(condition.m_name, condition.m_eventListener.get(), false); + eventBase->removeEventListener(condition.m_name, *condition.m_eventListener, false); condition.m_eventListener->disconnectAnimation(); - condition.m_eventListener = 0; + condition.m_eventListener = nullptr; } else if (condition.m_type == Condition::Syncbase) { if (condition.m_syncbase) - toSVGSMILElement(condition.m_syncbase.get())->removeTimeDependent(this); + downcast<SVGSMILElement>(condition.m_syncbase.get())->removeTimeDependent(this); } - condition.m_syncbase = 0; + condition.m_syncbase = nullptr; } } @@ -623,9 +648,9 @@ bool SVGSMILElement::isFrozen() const SVGSMILElement::Restart SVGSMILElement::restart() const { - DEFINE_STATIC_LOCAL(const AtomicString, never, ("never", AtomicString::ConstructFromLiteral)); - DEFINE_STATIC_LOCAL(const AtomicString, whenNotActive, ("whenNotActive", AtomicString::ConstructFromLiteral)); - const AtomicString& value = fastGetAttribute(SVGNames::restartAttr); + static NeverDestroyed<const AtomicString> never("never", AtomicString::ConstructFromLiteral); + static NeverDestroyed<const AtomicString> whenNotActive("whenNotActive", AtomicString::ConstructFromLiteral); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::restartAttr); if (value == never) return RestartNever; if (value == whenNotActive) @@ -635,8 +660,8 @@ SVGSMILElement::Restart SVGSMILElement::restart() const SVGSMILElement::FillMode SVGSMILElement::fill() const { - DEFINE_STATIC_LOCAL(const AtomicString, freeze, ("freeze", AtomicString::ConstructFromLiteral)); - const AtomicString& value = fastGetAttribute(SVGNames::fillAttr); + static NeverDestroyed<const AtomicString> freeze("freeze", AtomicString::ConstructFromLiteral); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::fillAttr); return value == freeze ? FillFreeze : FillRemove; } @@ -644,7 +669,7 @@ SMILTime SVGSMILElement::dur() const { if (m_cachedDur != invalidCachedTime) return m_cachedDur; - const AtomicString& value = fastGetAttribute(SVGNames::durAttr); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::durAttr); SMILTime clockValue = parseClockValue(value); return m_cachedDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue; } @@ -653,7 +678,7 @@ SMILTime SVGSMILElement::repeatDur() const { if (m_cachedRepeatDur != invalidCachedTime) return m_cachedRepeatDur; - const AtomicString& value = fastGetAttribute(SVGNames::repeatDurAttr); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::repeatDurAttr); SMILTime clockValue = parseClockValue(value); m_cachedRepeatDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue; return m_cachedRepeatDur; @@ -664,11 +689,11 @@ SMILTime SVGSMILElement::repeatCount() const { if (m_cachedRepeatCount != invalidCachedTime) return m_cachedRepeatCount; - const AtomicString& value = fastGetAttribute(SVGNames::repeatCountAttr); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::repeatCountAttr); if (value.isNull()) return SMILTime::unresolved(); - DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<const AtomicString> indefiniteValue("indefinite", AtomicString::ConstructFromLiteral); if (value == indefiniteValue) return SMILTime::indefinite(); bool ok; @@ -680,16 +705,16 @@ SMILTime SVGSMILElement::maxValue() const { if (m_cachedMax != invalidCachedTime) return m_cachedMax; - const AtomicString& value = fastGetAttribute(SVGNames::maxAttr); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::maxAttr); SMILTime result = parseClockValue(value); - return m_cachedMax = (result.isUnresolved() || result < 0) ? SMILTime::indefinite() : result; + return m_cachedMax = (result.isUnresolved() || result <= 0) ? SMILTime::indefinite() : result; } SMILTime SVGSMILElement::minValue() const { if (m_cachedMin != invalidCachedTime) return m_cachedMin; - const AtomicString& value = fastGetAttribute(SVGNames::minAttr); + const AtomicString& value = attributeWithoutSynchronization(SVGNames::minAttr); SMILTime result = parseClockValue(value); return m_cachedMin = (result.isUnresolved() || result < 0) ? 0 : result; } @@ -1022,7 +1047,7 @@ SMILTime SVGSMILElement::calculateNextProgressTime(SMILTime elapsed) const return repeatingDurationEnd; return m_intervalEnd; } - return elapsed + 0.025; + return elapsed + SMILAnimationFrameDelay; } return m_intervalBegin >= elapsed ? m_intervalBegin : SMILTime::unresolved(); } @@ -1047,9 +1072,6 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b ASSERT(m_timeContainer); ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite()); - if (!m_conditionsConnected) - connectConditions(); - if (!m_intervalBegin.isFinite()) { ASSERT(m_activeState == Inactive); m_nextProgressTime = SMILTime::unresolved(); @@ -1106,9 +1128,17 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b } if (oldActiveState == Active && m_activeState != Active) { + smilEndEventSender().dispatchEventSoon(*this); endedActiveInterval(); if (m_activeState != Frozen) clearAnimatedType(m_targetElement); + } else if (oldActiveState != Active && m_activeState == Active) + smilBeginEventSender().dispatchEventSoon(*this); + + // Triggering all the pending events if the animation timeline is changed. + if (seekToTime) { + if (m_activeState == Inactive || m_activeState == Frozen) + smilEndEventSender().dispatchEventSoon(*this); } m_nextProgressTime = calculateNextProgressTime(elapsed); @@ -1118,26 +1148,23 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b void SVGSMILElement::notifyDependentsIntervalChanged(NewOrExistingInterval newOrExisting) { ASSERT(m_intervalBegin.isFinite()); - DEFINE_STATIC_LOCAL(HashSet<SVGSMILElement*>, loopBreaker, ()); - if (loopBreaker.contains(this)) + static NeverDestroyed<HashSet<SVGSMILElement*>> loopBreaker; + if (loopBreaker.get().contains(this)) return; - loopBreaker.add(this); + loopBreaker.get().add(this); - TimeDependentSet::iterator end = m_timeDependents.end(); - for (TimeDependentSet::iterator it = m_timeDependents.begin(); it != end; ++it) { - SVGSMILElement* dependent = *it; + for (auto& dependent : m_timeDependents) { dependent->createInstanceTimesFromSyncbase(this, newOrExisting); } - loopBreaker.remove(this); + loopBreaker.get().remove(this); } void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval) { // FIXME: To be really correct, this should handle updating exising interval by changing // the associated times instead of creating new ones. - for (unsigned n = 0; n < m_conditions.size(); ++n) { - Condition& condition = m_conditions[n]; + for (auto& condition : m_conditions) { if (condition.m_type == Condition::Syncbase && condition.m_syncbase == syncbase) { ASSERT(condition.m_name == "begin" || condition.m_name == "end"); // No nested time containers in SVG, no need for crazy time space conversions. Phew! @@ -1189,6 +1216,11 @@ void SVGSMILElement::endedActiveInterval() clearTimesWithDynamicOrigins(m_endTimes); } +void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender) +{ + ASSERT(eventSender == &smilBeginEventSender() || eventSender == &smilEndEventSender()); + const AtomicString& eventType = eventSender->eventType(); + dispatchEvent(Event::create(eventType, false, false)); } -#endif +} diff --git a/Source/WebCore/svg/animation/SVGSMILElement.h b/Source/WebCore/svg/animation/SVGSMILElement.h index b8d38236b..cb7bd159e 100644 --- a/Source/WebCore/svg/animation/SVGSMILElement.h +++ b/Source/WebCore/svg/animation/SVGSMILElement.h @@ -23,18 +23,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGSMILElement_h -#define SVGSMILElement_h -#if ENABLE(SVG) +#pragma once + #include "SMILTime.h" #include "SVGElement.h" - -#include <wtf/HashMap.h> +#include <wtf/HashSet.h> namespace WebCore { class ConditionEventListener; class SMILTimeContainer; +class SVGSMILElement; + +template<typename T> class EventSender; + +using SMILEventSender = EventSender<SVGSMILElement>; // This class implements SMIL interval timing model as needed for SVG animation. class SVGSMILElement : public SVGElement { @@ -42,36 +45,26 @@ public: SVGSMILElement(const QualifiedName&, Document&); virtual ~SVGSMILElement(); - bool isSupportedAttribute(const QualifiedName&); - virtual void parseAttribute(const QualifiedName&, const AtomicString&) override; - virtual void svgAttributeChanged(const QualifiedName&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; + void parseAttribute(const QualifiedName&, const AtomicString&) override; + void svgAttributeChanged(const QualifiedName&) override; + InsertionNotificationRequest insertedInto(ContainerNode&) override; + void removedFrom(ContainerNode&) override; virtual bool hasValidAttributeType() = 0; virtual bool hasValidAttributeName(); virtual void animationAttributeChanged() = 0; - SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } + SMILTimeContainer* timeContainer() { return m_timeContainer.get(); } SVGElement* targetElement() const { return m_targetElement; } const QualifiedName& attributeName() const { return m_attributeName; } void beginByLinkActivation(); - enum Restart { - RestartAlways, - RestartWhenNotActive, - RestartNever - }; - + enum Restart { RestartAlways, RestartWhenNotActive, RestartNever }; Restart restart() const; - enum FillMode { - FillRemove, - FillFreeze - }; - + enum FillMode { FillRemove, FillFreeze }; FillMode fill() const; SMILTime dur() const; @@ -108,28 +101,40 @@ public: virtual void clearAnimatedType(SVGElement* targetElement) = 0; virtual void applyResultsToTarget() = 0; + void connectConditions(); + bool hasConditionsConnected() const { return m_conditionsConnected; } + + void dispatchPendingEvent(SMILEventSender*); + protected: void addBeginTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin); void addEndTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin); void setInactive() { m_activeState = Inactive; } - virtual bool rendererIsNeeded(const RenderStyle&) override { return false; } + bool rendererIsNeeded(const RenderStyle&) override { return false; } // Sub-classes may need to take action when the target is changed. virtual void setTargetElement(SVGElement*); virtual void setAttributeName(const QualifiedName&); + void finishedInsertingSubtree() override; + private: void buildPendingResource() override; void clearResourceReferences(); + void clearTarget() override; + virtual void startedActiveInterval() = 0; void endedActiveInterval(); virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0; + static bool isSupportedAttribute(const QualifiedName&); + QualifiedName constructAttributeName() const; + void updateAttributeName(); + enum BeginOrEnd { Begin, End }; - SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const; void resolveFirstInterval(); void resolveNextInterval(bool notifyDependents); @@ -143,19 +148,14 @@ private: // This represents conditions on elements begin or end list that need to be resolved on runtime // for example <animate begin="otherElement.begin + 8s; button.click" ... /> struct Condition { - enum Type { - EventBase, - Syncbase, - AccessKey - }; - + enum Type { EventBase, Syncbase, AccessKey }; Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1); Type m_type; BeginOrEnd m_beginOrEnd; String m_baseID; String m_name; SMILTime m_offset; - int m_repeats; + int m_repeats { -1 }; RefPtr<Element> m_syncbase; RefPtr<ConditionEventListener> m_eventListener; }; @@ -163,38 +163,28 @@ private: void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd); Element* eventBaseFor(const Condition&); - void connectConditions(); void disconnectConditions(); // Event base timing void handleConditionEvent(Event*, Condition*); // Syncbase timing - enum NewOrExistingInterval { - NewInterval, - ExistingInterval - }; - + enum NewOrExistingInterval { NewInterval, ExistingInterval }; void notifyDependentsIntervalChanged(NewOrExistingInterval); void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval); void addTimeDependent(SVGSMILElement*); void removeTimeDependent(SVGSMILElement*); - enum ActiveState { - Inactive, - Active, - Frozen - }; - - QualifiedName m_attributeName; - + enum ActiveState { Inactive, Active, Frozen }; ActiveState determineActiveState(SMILTime elapsed) const; float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const; SMILTime calculateNextProgressTime(SMILTime elapsed) const; - virtual bool isSMILElement() const override final { return true; } + bool isSMILElement() const final { return true; } + + QualifiedName m_attributeName; - mutable SVGElement* m_targetElement; + SVGElement* m_targetElement; Vector<Condition> m_conditions; bool m_conditionsConnected; @@ -202,8 +192,7 @@ private: bool m_isWaitingForFirstInterval; - typedef HashSet<SVGSMILElement*> TimeDependentSet; - TimeDependentSet m_timeDependents; + HashSet<SVGSMILElement*> m_timeDependents; // Instance time lists Vector<SMILTimeWithOrigin> m_beginTimes; @@ -233,14 +222,9 @@ private: friend class ConditionEventListener; }; -void isSVGSMILElement(const SVGSMILElement&); // Catch unnecessary runtime check of type known at compile time. -inline bool isSVGSMILElement(const SVGElement& element) { return element.isSMILElement(); } -inline bool isSVGSMILElement(const Node& node) { return node.isSVGElement() && toSVGElement(node).isSMILElement(); } -template <> inline bool isElementOfType<const SVGSMILElement>(const Element& element) { return isSVGSMILElement(element); } - -NODE_TYPE_CASTS(SVGSMILElement) - -} +} // namespace WebCore -#endif // ENABLE(SVG) -#endif // SVGSMILElement_h +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGSMILElement) + static bool isType(const WebCore::SVGElement& element) { return element.isSMILElement(); } + static bool isType(const WebCore::Node& node) { return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/graphics/SVGImage.cpp b/Source/WebCore/svg/graphics/SVGImage.cpp index 8ebf0444e..27cec3db7 100644 --- a/Source/WebCore/svg/graphics/SVGImage.cpp +++ b/Source/WebCore/svg/graphics/SVGImage.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Eric Seidel <eric@webkit.org> - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008-2009, 2015-2016 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2011. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,30 +26,48 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGImage.h" #include "Chrome.h" +#include "CommonVM.h" +#include "DOMWindow.h" #include "DocumentLoader.h" +#include "EditorClient.h" #include "ElementIterator.h" +#include "FrameLoader.h" #include "FrameView.h" #include "ImageBuffer.h" #include "ImageObserver.h" #include "IntRect.h" +#include "JSDOMWindowBase.h" +#include "LibWebRTCProvider.h" #include "MainFrame.h" +#include "Page.h" +#include "PageConfiguration.h" #include "RenderSVGRoot.h" #include "RenderStyle.h" #include "SVGDocument.h" +#include "SVGFEImageElement.h" #include "SVGForeignObjectElement.h" -#include "SVGImageChromeClient.h" +#include "SVGImageClients.h" +#include "SVGImageElement.h" #include "SVGSVGElement.h" #include "Settings.h" +#include "SocketProvider.h" +#include "TextStream.h" +#include <runtime/JSCInlines.h> +#include <runtime/JSLock.h> + +#if USE(DIRECT2D) +#include "COMPtr.h" +#include <d2d1.h> +#endif namespace WebCore { -SVGImage::SVGImage(ImageObserver* observer) - : Image(observer) +SVGImage::SVGImage(ImageObserver& observer, const URL& url) + : Image(&observer) + , m_url(url) { } @@ -57,7 +75,7 @@ SVGImage::~SVGImage() { if (m_page) { // Store m_page in a local variable, clearing m_page, so that SVGImageChromeClient knows we're destructed. - std::unique_ptr<Page> currentPage = std::move(m_page); + std::unique_ptr<Page> currentPage = WTFMove(m_page); currentPage->mainFrame().loader().frameDetached(); // Break both the loader and view references to the frame } @@ -65,51 +83,64 @@ SVGImage::~SVGImage() ASSERT(!m_chromeClient || !m_chromeClient->image()); } -bool SVGImage::hasSingleSecurityOrigin() const +inline SVGSVGElement* SVGImage::rootElement() const { if (!m_page) - return true; + return nullptr; + return SVGDocument::rootElement(*m_page->mainFrame().document()); +} - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); +bool SVGImage::hasSingleSecurityOrigin() const +{ + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return true; - // Don't allow foreignObject elements since they can leak information with arbitrary HTML (like spellcheck or control theme). - if (descendantsOfType<SVGForeignObjectElement>(*rootElement).first()) - return false; + // FIXME: Once foreignObject elements within SVG images are updated to not leak cross-origin data + // (e.g., visited links, spellcheck) we can remove the SVGForeignObjectElement check here and + // research if we can remove the Image::hasSingleSecurityOrigin mechanism entirely. + for (auto& element : descendantsOfType<SVGElement>(*rootElement)) { + if (is<SVGForeignObjectElement>(element)) + return false; + if (is<SVGImageElement>(element)) { + if (!downcast<SVGImageElement>(element).hasSingleSecurityOrigin()) + return false; + } else if (is<SVGFEImageElement>(element)) { + if (!downcast<SVGFEImageElement>(element).hasSingleSecurityOrigin()) + return false; + } + } // Because SVG image rendering disallows external resources and links, // these images effectively are restricted to a single security origin. return true; } -void SVGImage::setContainerSize(const IntSize& size) +void SVGImage::setContainerSize(const FloatSize& size) { - if (!m_page || !usesContainerSize()) + if (!usesContainerSize()) return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; - RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); + auto* renderer = downcast<RenderSVGRoot>(rootElement->renderer()); if (!renderer) return; FrameView* view = frameView(); view->resize(this->containerSize()); - renderer->setContainerSize(size); + renderer->setContainerSize(IntSize(size)); } IntSize SVGImage::containerSize() const { - if (!m_page) - return IntSize(); - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return IntSize(); - RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); + auto* renderer = downcast<RenderSVGRoot>(rootElement->renderer()); if (!renderer) return IntSize(); @@ -122,7 +153,7 @@ IntSize SVGImage::containerSize() const ASSERT(renderer->style().effectiveZoom() == 1); FloatSize currentSize; - if (rootElement->intrinsicWidth().isFixed() && rootElement->intrinsicHeight().isFixed()) + if (rootElement->hasIntrinsicWidth() && rootElement->hasIntrinsicHeight()) currentSize = rootElement->currentViewportSize(); else currentSize = rootElement->currentViewBoxRect().size(); @@ -134,8 +165,8 @@ IntSize SVGImage::containerSize() const return IntSize(300, 150); } -void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& dstRect, - const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp, BlendMode blendMode) +void SVGImage::drawForContainer(GraphicsContext& context, const FloatSize containerSize, float zoom, const FloatRect& dstRect, + const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode) { if (!m_page) return; @@ -144,7 +175,7 @@ void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize contai ASSERT(observer); // Temporarily reset image observer, we don't want to receive any changeInRect() calls due to this relayout. - setImageObserver(0); + setImageObserver(nullptr); IntSize roundedContainerSize = roundedIntSize(containerSize); setContainerSize(roundedContainerSize); @@ -157,38 +188,66 @@ void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize contai adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(), roundedContainerSize.height() / containerSize.height()); scaledSrc.setSize(adjustedSrcSize); - draw(context, dstRect, scaledSrc, colorSpace, compositeOp, blendMode, ImageOrientationDescription()); + draw(context, dstRect, scaledSrc, compositeOp, blendMode, ImageOrientationDescription()); setImageObserver(observer); } #if USE(CAIRO) -// Passes ownership of the native image to the caller so PassNativeImagePtr needs +// Passes ownership of the native image to the caller so NativeImagePtr needs // to be a smart pointer type. -PassNativeImagePtr SVGImage::nativeImageForCurrentFrame() +NativeImagePtr SVGImage::nativeImageForCurrentFrame(const GraphicsContext*) { if (!m_page) - return 0; + return nullptr; - std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(size(), 1); + // Cairo does not use the accelerated drawing flag, so it's OK to make an unconditionally unaccelerated buffer. + std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(size(), Unaccelerated); if (!buffer) // failed to allocate image - return 0; + return nullptr; - draw(buffer->context(), rect(), rect(), ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal, ImageOrientationDescription()); + draw(buffer->context(), rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription()); // FIXME: WK(Bug 113657): We should use DontCopyBackingStore here. return buffer->copyImage(CopyBackingStore)->nativeImageForCurrentFrame(); } #endif -void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& srcRect, - const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode) +#if USE(DIRECT2D) +NativeImagePtr SVGImage::nativeImage(const GraphicsContext* targetContext) +{ + ASSERT(targetContext); + if (!m_page || !targetContext) + return nullptr; + + auto platformContext = targetContext->platformContext(); + ASSERT(platformContext); + + // Draw the SVG into a bitmap. + COMPtr<ID2D1BitmapRenderTarget> nativeImageTarget; + HRESULT hr = platformContext->CreateCompatibleRenderTarget(IntSize(rect().size()), &nativeImageTarget); + ASSERT(SUCCEEDED(hr)); + + GraphicsContext localContext(nativeImageTarget.get()); + + draw(localContext, rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription()); + + COMPtr<ID2D1Bitmap> nativeImage; + hr = nativeImageTarget->GetBitmap(&nativeImage); + ASSERT(SUCCEEDED(hr)); + + return nativeImage; +} +#endif + +void SVGImage::drawPatternForContainer(GraphicsContext& context, const FloatSize& containerSize, float zoom, const FloatRect& srcRect, + const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode) { FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize); zoomedContainerRect.scale(zoom); // The ImageBuffer size needs to be scaled to match the final resolution. - AffineTransform transform = context->getCTM(); + AffineTransform transform = context.getCTM(); FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale()); ASSERT(imageBufferScale.width()); ASSERT(imageBufferScale.height()); @@ -196,15 +255,16 @@ void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize FloatRect imageBufferSize = zoomedContainerRect; imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height()); - std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(imageBufferSize.size()), 1); + std::unique_ptr<ImageBuffer> buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(imageBufferSize.size()), 1, ColorSpaceSRGB, context); if (!buffer) // Failed to allocate buffer. return; - drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal); - if (context->drawLuminanceMask()) + drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, CompositeSourceOver, BlendModeNormal); + if (context.drawLuminanceMask()) buffer->convertToLuminanceMask(); - RefPtr<Image> image = buffer->copyImage(DontCopyBackingStore, Unscaled); - image->setSpaceSize(spaceSize()); + RefPtr<Image> image = ImageBuffer::sinkIntoImage(WTFMove(buffer), Unscaled); + if (!image) + return; // Adjust the source rect and transform due to the image buffer's scaling. FloatRect scaledSrcRect = srcRect; @@ -212,24 +272,27 @@ void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize AffineTransform unscaledPatternTransform(patternTransform); unscaledPatternTransform.scale(1 / imageBufferScale.width(), 1 / imageBufferScale.height()); - context->setDrawLuminanceMask(false); - image->drawPattern(context, scaledSrcRect, unscaledPatternTransform, phase, colorSpace, compositeOp, dstRect, blendMode); + context.setDrawLuminanceMask(false); + image->drawPattern(context, dstRect, scaledSrcRect, unscaledPatternTransform, phase, spacing, compositeOp, blendMode); } -void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) +void SVGImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) { if (!m_page) return; FrameView* view = frameView(); + ASSERT(view); - GraphicsContextStateSaver stateSaver(*context); - context->setCompositeOperation(compositeOp, blendMode); - context->clip(enclosingIntRect(dstRect)); - bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != BlendModeNormal; + GraphicsContextStateSaver stateSaver(context); + context.setCompositeOperation(compositeOp, blendMode); + context.clip(enclosingIntRect(dstRect)); + + float alpha = context.alpha(); + bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != BlendModeNormal || alpha < 1; if (compositingRequiresTransparencyLayer) { - context->beginTransparencyLayer(1); - context->setCompositeOperation(CompositeSourceOver, BlendModeNormal); + context.beginTransparencyLayer(alpha); + context.setCompositeOperation(CompositeSourceOver, BlendModeNormal); } FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()); @@ -239,18 +302,21 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl FloatSize topLeftOffset(srcRect.location().x() * scale.width(), srcRect.location().y() * scale.height()); FloatPoint destOffset = dstRect.location() - topLeftOffset; - context->translate(destOffset.x(), destOffset.y()); - context->scale(scale); + context.translate(destOffset.x(), destOffset.y()); + context.scale(scale); view->resize(containerSize()); + if (!m_url.isEmpty()) + view->scrollToFragment(m_url); + if (view->needsLayout()) view->layout(); - view->paint(context, enclosingIntRect(srcRect)); + view->paint(context, intersection(context.clipBounds(), enclosingIntRect(srcRect))); if (compositingRequiresTransparencyLayer) - context->endTransparencyLayer(); + context.endTransparencyLayer(); stateSaver.restore(); @@ -260,52 +326,44 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl RenderBox* SVGImage::embeddedContentBox() const { - if (!m_page) - return 0; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) - return 0; - return toRenderBox(rootElement->renderer()); + return nullptr; + return downcast<RenderBox>(rootElement->renderer()); } FrameView* SVGImage::frameView() const { if (!m_page) - return 0; + return nullptr; return m_page->mainFrame().view(); } bool SVGImage::hasRelativeWidth() const { - if (!m_page) - return false; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return false; - return rootElement->intrinsicWidth().isPercent(); + return rootElement->intrinsicWidth().isPercentOrCalculated(); } bool SVGImage::hasRelativeHeight() const { - if (!m_page) - return false; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return false; - return rootElement->intrinsicHeight().isPercent(); + return rootElement->intrinsicHeight().isPercentOrCalculated(); } void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { - if (!m_page) - return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; intrinsicWidth = rootElement->intrinsicWidth(); intrinsicHeight = rootElement->intrinsicHeight(); - if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) + if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_NONE) return; intrinsicRatio = rootElement->viewBox().size(); @@ -313,12 +371,9 @@ void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrin intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)); } -// FIXME: support catchUpIfNecessary. -void SVGImage::startAnimation(bool /* catchUpIfNecessary */) +void SVGImage::startAnimation() { - if (!m_page) - return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; rootElement->unpauseAnimations(); @@ -327,9 +382,7 @@ void SVGImage::startAnimation(bool /* catchUpIfNecessary */) void SVGImage::stopAnimation() { - if (!m_page) - return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; rootElement->pauseAnimations(); @@ -340,6 +393,21 @@ void SVGImage::resetAnimation() stopAnimation(); } +void SVGImage::reportApproximateMemoryCost() const +{ + Document* document = m_page->mainFrame().document(); + size_t decodedImageMemoryCost = 0; + + for (Node* node = document; node; node = NodeTraversal::next(*node)) + decodedImageMemoryCost += node->approximateMemoryCost(); + + JSC::VM& vm = commonVM(); + JSC::JSLockHolder lock(vm); + // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated. + // https://bugs.webkit.org/show_bug.cgi?id=142595 + vm.heap.deprecatedReportExtraMemory(decodedImageMemoryCost + data()->size()); +} + bool SVGImage::dataChanged(bool allDataReceived) { // Don't do anything if is an empty image. @@ -347,10 +415,14 @@ bool SVGImage::dataChanged(bool allDataReceived) return true; if (allDataReceived) { - Page::PageClients pageClients; - fillWithEmptyClients(pageClients); + PageConfiguration pageConfiguration( + createEmptyEditorClient(), + SocketProvider::create(), + makeUniqueRef<LibWebRTCProvider>() + ); + fillWithEmptyClients(pageConfiguration); m_chromeClient = std::make_unique<SVGImageChromeClient>(this); - pageClients.chromeClient = m_chromeClient.get(); + pageConfiguration.chromeClient = m_chromeClient.get(); // FIXME: If this SVG ends up loading itself, we might leak the world. // The Cache code does not know about CachedImages holding Frames and @@ -358,10 +430,11 @@ bool SVGImage::dataChanged(bool allDataReceived) // This will become an issue when SVGImage will be able to load other // SVGImage objects, but we're safe now, because SVGImage can only be // loaded by a top-level document. - m_page = std::make_unique<Page>(pageClients); + m_page = std::make_unique<Page>(WTFMove(pageConfiguration)); m_page->settings().setMediaEnabled(false); m_page->settings().setScriptEnabled(false); m_page->settings().setPluginsEnabled(false); + m_page->settings().setAcceleratedCompositingEnabled(false); Frame& frame = m_page->mainFrame(); frame.setView(FrameView::create(frame)); @@ -380,6 +453,7 @@ bool SVGImage::dataChanged(bool allDataReceived) // Set the intrinsic size before a container size is available. m_intrinsicSize = containerSize(); + reportApproximateMemoryCost(); } return m_page != nullptr; @@ -387,7 +461,7 @@ bool SVGImage::dataChanged(bool allDataReceived) String SVGImage::filenameExtension() const { - return "svg"; + return ASCIILiteral("svg"); } bool isInSVGImage(const Element* element) @@ -401,6 +475,11 @@ bool isInSVGImage(const Element* element) return page->chrome().client().isSVGImageChromeClient(); } +void SVGImage::dump(TextStream& ts) const +{ + Image::dump(ts); + ts.dumpProperty("url", m_url.string()); } -#endif // ENABLE(SVG) + +} diff --git a/Source/WebCore/svg/graphics/SVGImage.h b/Source/WebCore/svg/graphics/SVGImage.h index 62f9f1d6a..13f9ed87e 100644 --- a/Source/WebCore/svg/graphics/SVGImage.h +++ b/Source/WebCore/svg/graphics/SVGImage.h @@ -24,12 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGImage_h -#define SVGImage_h - -#if ENABLE(SVG) +#pragma once #include "Image.h" +#include "URL.h" namespace WebCore { @@ -38,33 +36,39 @@ class FrameView; class ImageBuffer; class Page; class RenderBox; +class SVGSVGElement; class SVGImageChromeClient; class SVGImageForContainer; class SVGImage final : public Image { public: - static PassRefPtr<SVGImage> create(ImageObserver* observer) + static Ref<SVGImage> create(ImageObserver& observer, const URL& url) { - return adoptRef(new SVGImage(observer)); + return adoptRef(*new SVGImage(observer, url)); } RenderBox* embeddedContentBox() const; FrameView* frameView() const; - virtual bool isSVGImage() const override { return true; } - virtual IntSize size() const override { return m_intrinsicSize; } + bool isSVGImage() const final { return true; } + FloatSize size() const final { return m_intrinsicSize; } + + void setURL(const URL& url) { m_url = url; } - virtual bool hasSingleSecurityOrigin() const override; + bool hasSingleSecurityOrigin() const final; - virtual bool hasRelativeWidth() const override; - virtual bool hasRelativeHeight() const override; + bool hasRelativeWidth() const final; + bool hasRelativeHeight() const final; - virtual void startAnimation(bool /*catchUpIfNecessary*/ = true) override; - virtual void stopAnimation() override; - virtual void resetAnimation() override; + void startAnimation() final; + void stopAnimation() final; + void resetAnimation() final; #if USE(CAIRO) - virtual PassNativeImagePtr nativeImageForCurrentFrame() override; + NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) final; +#endif +#if USE(DIRECT2D) + NativeImagePtr nativeImage(const GraphicsContext* = nullptr) final; #endif private: @@ -73,38 +77,40 @@ private: virtual ~SVGImage(); - virtual String filenameExtension() const override; + String filenameExtension() const final; - virtual void setContainerSize(const IntSize&) override; + void setContainerSize(const FloatSize&) final; IntSize containerSize() const; - virtual bool usesContainerSize() const override { return true; } - virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override; + bool usesContainerSize() const final { return true; } + void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) final; - virtual bool dataChanged(bool allDataReceived) override; + void reportApproximateMemoryCost() const; + bool dataChanged(bool allDataReceived) final; // FIXME: SVGImages will be unable to prune because this function is not implemented yet. - virtual void destroyDecodedData(bool) override { } + void destroyDecodedData(bool) final { } // FIXME: Implement this to be less conservative. - virtual bool currentFrameKnownToBeOpaque() override { return false; } + bool currentFrameKnownToBeOpaque() const final { return false; } + + void dump(TextStream&) const final; - SVGImage(ImageObserver*); - virtual void draw(GraphicsContext*, const FloatRect& fromRect, const FloatRect& toRect, ColorSpace styleColorSpace, CompositeOperator, BlendMode, ImageOrientationDescription) override; - void drawForContainer(GraphicsContext*, const FloatSize, float, const FloatRect&, const FloatRect&, ColorSpace, CompositeOperator, BlendMode); - void drawPatternForContainer(GraphicsContext*, const FloatSize, float, const FloatRect&, const AffineTransform&, const FloatPoint&, ColorSpace, + SVGImage(ImageObserver&, const URL&); + void draw(GraphicsContext&, const FloatRect& fromRect, const FloatRect& toRect, CompositeOperator, BlendMode, ImageOrientationDescription) final; + void drawForContainer(GraphicsContext&, const FloatSize, float, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode); + void drawPatternForContainer(GraphicsContext&, const FloatSize& containerSize, float zoom, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect&, BlendMode); + SVGSVGElement* rootElement() const; + std::unique_ptr<SVGImageChromeClient> m_chromeClient; std::unique_ptr<Page> m_page; - IntSize m_intrinsicSize; + FloatSize m_intrinsicSize; + URL m_url; }; bool isInSVGImage(const Element*); -IMAGE_TYPE_CASTS(SVGImage) - -} - +} // namespace WebCore -#endif // ENABLE(SVG) -#endif // SVGImage_h +SPECIALIZE_TYPE_TRAITS_IMAGE(SVGImage) diff --git a/Source/WebCore/svg/graphics/SVGImageCache.cpp b/Source/WebCore/svg/graphics/SVGImageCache.cpp index e3a89fd3b..399d6bae5 100644 --- a/Source/WebCore/svg/graphics/SVGImageCache.cpp +++ b/Source/WebCore/svg/graphics/SVGImageCache.cpp @@ -21,11 +21,10 @@ #include "config.h" #include "SVGImageCache.h" -#if ENABLE(SVG) #include "FrameView.h" #include "GraphicsContext.h" #include "ImageBuffer.h" -#include "Page.h" +#include "LayoutSize.h" #include "RenderSVGRoot.h" #include "SVGImage.h" #include "SVGImageForContainer.h" @@ -50,7 +49,7 @@ void SVGImageCache::removeClientFromCache(const CachedImageClient* client) m_imageForContainerMap.remove(client); } -void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, const IntSize& containerSize, float containerZoom) +void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, const LayoutSize& containerSize, float containerZoom) { ASSERT(client); ASSERT(!containerSize.isEmpty()); @@ -62,37 +61,26 @@ void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, m_imageForContainerMap.set(client, SVGImageForContainer::create(m_svgImage, containerSizeWithoutZoom, containerZoom)); } -IntSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const +Image* SVGImageCache::findImageForRenderer(const RenderObject* renderer) const { - IntSize imageSize = m_svgImage->size(); - if (!renderer) - return imageSize; - - ImageForContainerMap::const_iterator it = m_imageForContainerMap.find(renderer); - if (it == m_imageForContainerMap.end()) - return imageSize; + return renderer ? m_imageForContainerMap.get(renderer) : nullptr; +} - RefPtr<SVGImageForContainer> imageForContainer = it->value; - ASSERT(!imageForContainer->size().isEmpty()); - return imageForContainer->size(); +FloatSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const +{ + auto* image = findImageForRenderer(renderer); + return image ? image->size() : m_svgImage->size(); } // FIXME: This doesn't take into account the animation timeline so animations will not // restart on page load, nor will two animations in different pages have different timelines. -Image* SVGImageCache::imageForRenderer(const RenderObject* renderer) +Image* SVGImageCache::imageForRenderer(const RenderObject* renderer) const { - if (!renderer) + auto* image = findImageForRenderer(renderer); + if (!image) return Image::nullImage(); - - ImageForContainerMap::iterator it = m_imageForContainerMap.find(renderer); - if (it == m_imageForContainerMap.end()) - return Image::nullImage(); - - RefPtr<SVGImageForContainer> imageForContainer = it->value; - ASSERT(!imageForContainer->size().isEmpty()); - return imageForContainer.get(); + ASSERT(!image->size().isEmpty()); + return image; } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/graphics/SVGImageCache.h b/Source/WebCore/svg/graphics/SVGImageCache.h index 3e000d3ac..bd8ce4f55 100644 --- a/Source/WebCore/svg/graphics/SVGImageCache.h +++ b/Source/WebCore/svg/graphics/SVGImageCache.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGImageCache_h -#define SVGImageCache_h +#pragma once -#if ENABLE(SVG) #include "FloatSize.h" #include "Image.h" #include "IntSize.h" @@ -32,6 +30,7 @@ namespace WebCore { class CachedImage; class CachedImageClient; class ImageBuffer; +class LayoutSize; class SVGImage; class SVGImageForContainer; class RenderObject; @@ -44,12 +43,14 @@ public: void removeClientFromCache(const CachedImageClient*); - void setContainerSizeForRenderer(const CachedImageClient*, const IntSize&, float); - IntSize imageSizeForRenderer(const RenderObject*) const; + void setContainerSizeForRenderer(const CachedImageClient*, const LayoutSize&, float); + FloatSize imageSizeForRenderer(const RenderObject*) const; - Image* imageForRenderer(const RenderObject*); + Image* imageForRenderer(const RenderObject*) const; private: + Image* findImageForRenderer(const RenderObject*) const; + typedef HashMap<const CachedImageClient*, RefPtr<SVGImageForContainer>> ImageForContainerMap; SVGImage* m_svgImage; @@ -57,6 +58,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGImageCache_h diff --git a/Source/WebCore/svg/graphics/SVGImageChromeClient.h b/Source/WebCore/svg/graphics/SVGImageClients.h index af64e463d..bee03d506 100644 --- a/Source/WebCore/svg/graphics/SVGImageChromeClient.h +++ b/Source/WebCore/svg/graphics/SVGImageClients.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,16 +26,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGImageChromeClient_h -#define SVGImageChromeClient_h - -#if ENABLE(SVG) +#pragma once #include "EmptyClients.h" namespace WebCore { -class SVGImageChromeClient : public EmptyChromeClient { +class SVGImageChromeClient final : public EmptyChromeClient { WTF_MAKE_NONCOPYABLE(SVGImageChromeClient); WTF_MAKE_FAST_ALLOCATED; public: SVGImageChromeClient(SVGImage* image) @@ -43,32 +40,23 @@ public: { } - virtual bool isSVGImageChromeClient() const override { return true; } + bool isSVGImageChromeClient() const final { return true; } SVGImage* image() const { return m_image; } private: - virtual void chromeDestroyed() override + void chromeDestroyed() final { - m_image = 0; + m_image = nullptr; } - virtual void invalidateContentsAndRootView(const IntRect& r, bool) override + void invalidateContentsAndRootView(const IntRect& r) final { // If m_image->m_page is null, we're being destructed, don't fire changedInRect() in that case. if (m_image && m_image->imageObserver() && m_image->m_page) - m_image->imageObserver()->changedInRect(m_image, r); + m_image->imageObserver()->changedInRect(m_image, &r); } SVGImage* m_image; }; -inline SVGImageChromeClient* toSVGImageChromeClient(ChromeClient* client) -{ - ASSERT_WITH_SECURITY_IMPLICATION(!client || client->isSVGImageChromeClient()); - return static_cast<SVGImageChromeClient*>(client); -} - -} - -#endif // ENABLE(SVG) -#endif // SVGImageChromeClient_h +} // namespace WebCore diff --git a/Source/WebCore/svg/graphics/SVGImageForContainer.cpp b/Source/WebCore/svg/graphics/SVGImageForContainer.cpp index 33d78778c..482c39415 100644 --- a/Source/WebCore/svg/graphics/SVGImageForContainer.cpp +++ b/Source/WebCore/svg/graphics/SVGImageForContainer.cpp @@ -20,40 +20,35 @@ #include "config.h" #include "SVGImageForContainer.h" -#if ENABLE(SVG) #include "AffineTransform.h" #include "FloatRect.h" #include "FloatSize.h" #include "Image.h" -#include "SVGImage.h" namespace WebCore { -IntSize SVGImageForContainer::size() const +FloatSize SVGImageForContainer::size() const { FloatSize scaledContainerSize(m_containerSize); scaledContainerSize.scale(m_zoom); - return roundedIntSize(scaledContainerSize); + return FloatSize(roundedIntSize(scaledContainerSize)); } -void SVGImageForContainer::draw(GraphicsContext* context, const FloatRect& dstRect, - const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) +void SVGImageForContainer::draw(GraphicsContext& context, const FloatRect& dstRect, + const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) { - m_image->drawForContainer(context, m_containerSize, m_zoom, dstRect, srcRect, colorSpace, compositeOp, blendMode); + m_image->drawForContainer(context, m_containerSize, m_zoom, dstRect, srcRect, compositeOp, blendMode); } -void SVGImageForContainer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, - const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode) +void SVGImageForContainer::drawPattern(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, BlendMode blendMode) { - m_image->setSpaceSize(spaceSize()); - m_image->drawPatternForContainer(context, m_containerSize, m_zoom, srcRect, patternTransform, phase, colorSpace, compositeOp, dstRect, blendMode); + m_image->drawPatternForContainer(context, m_containerSize, m_zoom, srcRect, patternTransform, phase, spacing, compositeOp, dstRect, blendMode); } -PassNativeImagePtr SVGImageForContainer::nativeImageForCurrentFrame() +NativeImagePtr SVGImageForContainer::nativeImageForCurrentFrame(const GraphicsContext* targetContext) { - return m_image->nativeImageForCurrentFrame(); + return m_image->nativeImageForCurrentFrame(targetContext); } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/graphics/SVGImageForContainer.h b/Source/WebCore/svg/graphics/SVGImageForContainer.h index b0c9bea96..aa1988a00 100644 --- a/Source/WebCore/svg/graphics/SVGImageForContainer.h +++ b/Source/WebCore/svg/graphics/SVGImageForContainer.h @@ -23,46 +23,46 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGImageForContainer_h -#define SVGImageForContainer_h - -#if ENABLE(SVG) +#pragma once #include "AffineTransform.h" #include "FloatRect.h" #include "FloatSize.h" #include "Image.h" #include "SVGImage.h" +#include "URL.h" namespace WebCore { class SVGImageForContainer final : public Image { public: - static PassRefPtr<SVGImageForContainer> create(SVGImage* image, const FloatSize& containerSize, float zoom) + static Ref<SVGImageForContainer> create(SVGImage* image, const FloatSize& containerSize, float zoom) { - return adoptRef(new SVGImageForContainer(image, containerSize, zoom)); + return adoptRef(*new SVGImageForContainer(image, containerSize, zoom)); } - virtual bool isSVGImage() const override { return true; } + bool isSVGImage() const final { return true; } + + FloatSize size() const final; - virtual IntSize size() const override; + void setURL(const URL& url) { m_image->setURL(url); } - virtual bool usesContainerSize() const override { return m_image->usesContainerSize(); } - virtual bool hasRelativeWidth() const override { return m_image->hasRelativeWidth(); } - virtual bool hasRelativeHeight() const override { return m_image->hasRelativeHeight(); } - virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override + bool usesContainerSize() const final { return m_image->usesContainerSize(); } + bool hasRelativeWidth() const final { return m_image->hasRelativeWidth(); } + bool hasRelativeHeight() const final { return m_image->hasRelativeHeight(); } + void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) final { m_image->computeIntrinsicDimensions(intrinsicWidth, intrinsicHeight, intrinsicRatio); } - virtual void draw(GraphicsContext*, const FloatRect&, const FloatRect&, ColorSpace, CompositeOperator, BlendMode, ImageOrientationDescription) override; + void draw(GraphicsContext&, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientationDescription) final; - virtual void drawPattern(GraphicsContext*, const FloatRect&, const AffineTransform&, const FloatPoint&, ColorSpace, CompositeOperator, const FloatRect&, BlendMode) override; + void drawPattern(GraphicsContext&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, const FloatSize&, CompositeOperator, BlendMode) final; // FIXME: Implement this to be less conservative. - virtual bool currentFrameKnownToBeOpaque() override { return false; } + bool currentFrameKnownToBeOpaque() const final { return false; } - virtual PassNativeImagePtr nativeImageForCurrentFrame() override; + NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) final; private: SVGImageForContainer(SVGImage* image, const FloatSize& containerSize, float zoom) @@ -72,13 +72,11 @@ private: { } - virtual void destroyDecodedData(bool /*destroyAll*/ = true) override { } + void destroyDecodedData(bool /*destroyAll*/ = true) final { } SVGImage* m_image; const FloatSize m_containerSize; const float m_zoom; }; -} -#endif // ENABLE(SVG) -#endif // SVGImageForContainer_h +} // namespace WebCore diff --git a/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp b/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp index 87be6e85e..d25893e2a 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp +++ b/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp @@ -21,8 +21,6 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEImage.h" #include "AffineTransform.h" @@ -31,22 +29,21 @@ #include "RenderElement.h" #include "RenderTreeAsText.h" #include "SVGElement.h" -#include "SVGPreserveAspectRatio.h" #include "SVGRenderingContext.h" #include "SVGURIReference.h" #include "TextStream.h" namespace WebCore { -FEImage::FEImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio) +FEImage::FEImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio) : FilterEffect(filter) , m_image(image) - , m_document(0) + , m_document(nullptr) , m_preserveAspectRatio(preserveAspectRatio) { } -FEImage::FEImage(Filter* filter, Document& document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio) +FEImage::FEImage(Filter& filter, Document& document, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio) : FilterEffect(filter) , m_document(&document) , m_href(href) @@ -54,25 +51,25 @@ FEImage::FEImage(Filter* filter, Document& document, const String& href, const S { } -PassRefPtr<FEImage> FEImage::createWithImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio) +Ref<FEImage> FEImage::createWithImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio) { - return adoptRef(new FEImage(filter, image, preserveAspectRatio)); + return adoptRef(*new FEImage(filter, image, preserveAspectRatio)); } -PassRefPtr<FEImage> FEImage::createWithIRIReference(Filter* filter, Document& document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio) +Ref<FEImage> FEImage::createWithIRIReference(Filter& filter, Document& document, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio) { - return adoptRef(new FEImage(filter, document, href, preserveAspectRatio)); + return adoptRef(*new FEImage(filter, document, href, preserveAspectRatio)); } void FEImage::determineAbsolutePaintRect() { - FloatRect paintRect = filter()->absoluteTransform().mapRect(filterPrimitiveSubregion()); + FloatRect paintRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion()); FloatRect srcRect; if (m_image) { srcRect.setSize(m_image->size()); m_preserveAspectRatio.transformRect(paintRect, srcRect); } else if (RenderElement* renderer = referencedRenderer()) - srcRect = filter()->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); + srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); if (clipsToBounds()) paintRect.intersect(maxEffectRect()); @@ -101,11 +98,11 @@ void FEImage::platformApplySoftware() if (!resultImage) return; - FloatRect destRect = filter()->absoluteTransform().mapRect(filterPrimitiveSubregion()); + FloatRect destRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion()); FloatRect srcRect; if (renderer) - srcRect = filter()->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); + srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); else { srcRect = FloatRect(FloatPoint(), m_image->size()); m_preserveAspectRatio.transformRect(destRect, srcRect); @@ -114,14 +111,14 @@ void FEImage::platformApplySoftware() IntPoint paintLocation = absolutePaintRect().location(); destRect.move(-paintLocation.x(), -paintLocation.y()); - // FEImage results are always in ColorSpaceDeviceRGB - setResultColorSpace(ColorSpaceDeviceRGB); + // FEImage results are always in ColorSpaceSRGB + setResultColorSpace(ColorSpaceSRGB); if (renderer) { - const AffineTransform& absoluteTransform = filter()->absoluteTransform(); - resultImage->context()->concatCTM(absoluteTransform); + const AffineTransform& absoluteTransform = filter().absoluteTransform(); + resultImage->context().concatCTM(absoluteTransform); - SVGElement* contextNode = toSVGElement(renderer->element()); + SVGElement* contextNode = downcast<SVGElement>(renderer->element()); if (contextNode->hasRelativeLengths()) { SVGLengthContext lengthContext(contextNode); FloatSize viewportSize; @@ -129,7 +126,7 @@ void FEImage::platformApplySoftware() // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport. // Build up a transformation that maps from the viewport space to the filter primitive subregion. if (lengthContext.determineViewport(viewportSize)) - resultImage->context()->concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect)); + resultImage->context().concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect)); } AffineTransform contentTransformation; @@ -137,7 +134,7 @@ void FEImage::platformApplySoftware() return; } - resultImage->context()->drawImage(m_image.get(), ColorSpaceDeviceRGB, destRect, srcRect); + resultImage->context().drawImage(*m_image, destRect, srcRect); } void FEImage::dump() @@ -146,7 +143,7 @@ void FEImage::dump() TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const { - IntSize imageSize; + FloatSize imageSize; if (m_image) imageSize = m_image->size(); else if (RenderObject* renderer = referencedRenderer()) @@ -160,5 +157,3 @@ TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const } } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) diff --git a/Source/WebCore/svg/graphics/filters/SVGFEImage.h b/Source/WebCore/svg/graphics/filters/SVGFEImage.h index 83c886da9..45d8a1be9 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFEImage.h +++ b/Source/WebCore/svg/graphics/filters/SVGFEImage.h @@ -20,12 +20,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEImage_h -#define SVGFEImage_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FilterEffect.h" -#include "SVGPreserveAspectRatio.h" +#include "SVGPreserveAspectRatioValue.h" namespace WebCore { @@ -33,27 +31,24 @@ class Document; class Image; class RenderElement; -class FEImage : public FilterEffect { +class FEImage final : public FilterEffect { public: - static PassRefPtr<FEImage> createWithImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&); - static PassRefPtr<FEImage> createWithIRIReference(Filter*, Document&, const String&, const SVGPreserveAspectRatio&); + static Ref<FEImage> createWithImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&); + static Ref<FEImage> createWithIRIReference(Filter&, Document&, const String&, const SVGPreserveAspectRatioValue&); - virtual void platformApplySoftware() override; -#if ENABLE(OPENCL) - virtual bool platformApplyOpenCL(); -#endif - virtual void dump() override; + void platformApplySoftware() final; + void dump() final; - virtual void determineAbsolutePaintRect() override; + void determineAbsolutePaintRect() final; - virtual FilterEffectType filterEffectType() const override { return FilterEffectTypeImage; } + FilterEffectType filterEffectType() const final { return FilterEffectTypeImage; } - virtual TextStream& externalRepresentation(TextStream&, int indention) const override; + TextStream& externalRepresentation(TextStream&, int indention) const final; private: virtual ~FEImage() { } - FEImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&); - FEImage(Filter*, Document&, const String&, const SVGPreserveAspectRatio&); + FEImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&); + FEImage(Filter&, Document&, const String&, const SVGPreserveAspectRatioValue&); RenderElement* referencedRenderer() const; RefPtr<Image> m_image; @@ -61,11 +56,7 @@ private: // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243 Document* m_document; String m_href; - SVGPreserveAspectRatio m_preserveAspectRatio; + SVGPreserveAspectRatioValue m_preserveAspectRatio; }; } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) - -#endif // SVGFEImage_h diff --git a/Source/WebCore/svg/graphics/filters/SVGFilter.cpp b/Source/WebCore/svg/graphics/filters/SVGFilter.cpp index e5b27662f..2d85ae550 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilter.cpp +++ b/Source/WebCore/svg/graphics/filters/SVGFilter.cpp @@ -20,8 +20,6 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFilter.h" namespace WebCore { @@ -50,11 +48,9 @@ float SVGFilter::applyVerticalScale(float value) const return Filter::applyVerticalScale(value) * m_absoluteFilterRegion.height() / m_filterRegion.height(); } -PassRefPtr<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode) +Ref<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode) { - return adoptRef(new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode)); + return adoptRef(*new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode)); } } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) diff --git a/Source/WebCore/svg/graphics/filters/SVGFilter.h b/Source/WebCore/svg/graphics/filters/SVGFilter.h index e4811ded4..a01509eb3 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilter.h +++ b/Source/WebCore/svg/graphics/filters/SVGFilter.h @@ -18,36 +18,33 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFilter_h -#define SVGFilter_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "AffineTransform.h" #include "Filter.h" #include "FilterEffect.h" #include "FloatRect.h" #include "FloatSize.h" - -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/TypeCasts.h> namespace WebCore { -class SVGFilter : public Filter { +class SVGFilter final : public Filter { public: - static PassRefPtr<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool); + static Ref<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool); FloatRect filterRegionInUserSpace() const { return m_filterRegion; } - virtual FloatRect filterRegion() const override { return m_absoluteFilterRegion; } + FloatRect filterRegion() const final { return m_absoluteFilterRegion; } - virtual float applyHorizontalScale(float value) const override; - virtual float applyVerticalScale(float value) const override; + float applyHorizontalScale(float value) const final; + float applyVerticalScale(float value) const final; - virtual FloatRect sourceImageRect() const override { return m_absoluteSourceDrawingRegion; } + FloatRect sourceImageRect() const final { return m_absoluteSourceDrawingRegion; } FloatRect targetBoundingBox() const { return m_targetBoundingBox; } - virtual bool isSVGFilter() const override final { return true; } + bool isSVGFilter() const final { return true; } private: SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode); @@ -59,10 +56,8 @@ private: bool m_effectBBoxMode; }; -FILTER_TYPE_CASTS(SVGFilter, isSVGFilter()) - } // namespace WebCore -#endif // ENABLE(SVG) && ENABLE(FILTERS) - -#endif // SVGFilter_h +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGFilter) + static bool isType(const WebCore::Filter& filter) { return filter.isSVGFilter(); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp index 31102c9c9..4f6a82771 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp +++ b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp @@ -18,26 +18,22 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFilterBuilder.h" #include "FilterEffect.h" #include "SourceAlpha.h" #include "SourceGraphic.h" -#include <wtf/PassRefPtr.h> -#include <wtf/text/WTFString.h> namespace WebCore { -SVGFilterBuilder::SVGFilterBuilder(PassRefPtr<FilterEffect> sourceGraphic, PassRefPtr<FilterEffect> sourceAlpha) +SVGFilterBuilder::SVGFilterBuilder(RefPtr<FilterEffect> sourceGraphic) { m_builtinEffects.add(SourceGraphic::effectName(), sourceGraphic); - m_builtinEffects.add(SourceAlpha::effectName(), sourceAlpha); + m_builtinEffects.add(SourceAlpha::effectName(), SourceAlpha::create(*sourceGraphic)); addBuiltinEffects(); } -void SVGFilterBuilder::add(const AtomicString& id, PassRefPtr<FilterEffect> effect) +void SVGFilterBuilder::add(const AtomicString& id, RefPtr<FilterEffect> effect) { if (id.isEmpty()) { m_lastEffect = effect; @@ -66,13 +62,11 @@ FilterEffect* SVGFilterBuilder::getEffectById(const AtomicString& id) const return m_namedEffects.get(id); } -void SVGFilterBuilder::appendEffectToEffectReferences(PassRefPtr<FilterEffect> prpEffect, RenderObject* object) +void SVGFilterBuilder::appendEffectToEffectReferences(RefPtr<FilterEffect>&& effect, RenderObject* object) { - RefPtr<FilterEffect> effect = prpEffect; - // The effect must be a newly created filter effect. ASSERT(!m_effectReferences.contains(effect)); - ASSERT(object && !m_effectRenderer.contains(object)); + ASSERT(!object || !m_effectRenderer.contains(object)); m_effectReferences.add(effect, FilterEffectSet()); unsigned numberOfInputEffects = effect->inputEffects().size(); @@ -80,12 +74,17 @@ void SVGFilterBuilder::appendEffectToEffectReferences(PassRefPtr<FilterEffect> p // It is not possible to add the same value to a set twice. for (unsigned i = 0; i < numberOfInputEffects; ++i) effectReferences(effect->inputEffect(i)).add(effect.get()); - m_effectRenderer.add(object, effect.get()); + + // If object is null, that means the element isn't attached for some + // reason, which in turn mean that certain types of invalidation will not + // work (the LayoutObject -> FilterEffect mapping will not be defined). + if (object) + m_effectRenderer.add(object, effect.get()); } void SVGFilterBuilder::clearEffects() { - m_lastEffect = 0; + m_lastEffect = nullptr; m_namedEffects.clear(); m_effectReferences.clear(); m_effectRenderer.clear(); @@ -99,12 +98,8 @@ void SVGFilterBuilder::clearResultsRecursive(FilterEffect* effect) effect->clearResult(); - HashSet<FilterEffect*>& effectReferences = this->effectReferences(effect); - HashSet<FilterEffect*>::iterator end = effectReferences.end(); - for (HashSet<FilterEffect*>::iterator it = effectReferences.begin(); it != end; ++it) - clearResultsRecursive(*it); + for (auto& reference : effectReferences(effect)) + clearResultsRecursive(reference); } } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) diff --git a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h index d789b7cb6..c5e40a808 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h +++ b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h @@ -18,15 +18,11 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFilterBuilder_h -#define SVGFilterBuilder_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FilterEffect.h" - #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> #include <wtf/text/AtomicStringHash.h> #include <wtf/text/WTFString.h> @@ -38,14 +34,14 @@ class SVGFilterBuilder { public: typedef HashSet<FilterEffect*> FilterEffectSet; - SVGFilterBuilder(PassRefPtr<FilterEffect> sourceGraphic, PassRefPtr<FilterEffect> sourceAlpha); + SVGFilterBuilder(RefPtr<FilterEffect> sourceGraphic); - void add(const AtomicString& id, PassRefPtr<FilterEffect>); + void add(const AtomicString& id, RefPtr<FilterEffect>); FilterEffect* getEffectById(const AtomicString& id) const; FilterEffect* lastEffect() const { return m_lastEffect.get(); } - void appendEffectToEffectReferences(PassRefPtr<FilterEffect>, RenderObject*); + void appendEffectToEffectReferences(RefPtr<FilterEffect>&&, RenderObject*); inline FilterEffectSet& effectReferences(FilterEffect* effect) { @@ -63,9 +59,8 @@ public: private: inline void addBuiltinEffects() { - HashMap<AtomicString, RefPtr<FilterEffect>>::iterator end = m_builtinEffects.end(); - for (HashMap<AtomicString, RefPtr<FilterEffect>>::iterator iterator = m_builtinEffects.begin(); iterator != end; ++iterator) - m_effectReferences.add(iterator->value, FilterEffectSet()); + for (auto& effect : m_builtinEffects.values()) + m_effectReferences.add(effect, FilterEffectSet()); } HashMap<AtomicString, RefPtr<FilterEffect>> m_builtinEffects; @@ -79,6 +74,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) -#endif // SVGFilterBuilder_h diff --git a/Source/WebCore/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h index 1c8ea99bf..164cd648f 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedEnumerationPropertyTearOff_h -#define SVGAnimatedEnumerationPropertyTearOff_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedStaticPropertyTearOff.h" #include "SVGException.h" #include "SVGPropertyTraits.h" @@ -28,22 +26,40 @@ namespace WebCore { template<typename EnumType> -class SVGAnimatedEnumerationPropertyTearOff : public SVGAnimatedStaticPropertyTearOff<unsigned> { +class SVGAnimatedEnumerationPropertyTearOff final : public SVGAnimatedStaticPropertyTearOff<unsigned> { public: - virtual void setBaseVal(const unsigned& property, ExceptionCode& ec) override + const unsigned& baseVal() final + { + const unsigned& baseVal = SVGAnimatedStaticPropertyTearOff::baseVal(); + + if (baseVal > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue()) + return m_outOfRangeEnumValue; + + return baseVal; + } + + const unsigned& animVal() final + { + const unsigned& animVal = SVGAnimatedStaticPropertyTearOff::animVal(); + + if (animVal > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue()) + return m_outOfRangeEnumValue; + + return animVal; + } + + ExceptionOr<void> setBaseVal(const unsigned& property) final { // All SVG enumeration values, that are allowed to be set via SVG DOM start with 1, 0 corresponds to unknown and is not settable through SVG DOM. - if (!property || property > SVGPropertyTraits<EnumType>::highestEnumValue()) { - ec = SVGException::SVG_INVALID_VALUE_ERR; - return; - } - SVGAnimatedStaticPropertyTearOff<unsigned>::setBaseVal(property, ec); + if (!property || property > SVGIDLEnumLimits<EnumType>::highestExposedEnumValue()) + return Exception { SVGException::SVG_INVALID_VALUE_ERR }; + return SVGAnimatedStaticPropertyTearOff<unsigned>::setBaseVal(property); } - static PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<EnumType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, EnumType& property) + static Ref<SVGAnimatedEnumerationPropertyTearOff<EnumType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, EnumType& property) { ASSERT(contextElement); - return adoptRef(new SVGAnimatedEnumerationPropertyTearOff<EnumType>(contextElement, attributeName, animatedPropertyType, reinterpret_cast<unsigned&>(property))); + return adoptRef(*new SVGAnimatedEnumerationPropertyTearOff<EnumType>(contextElement, attributeName, animatedPropertyType, reinterpret_cast<unsigned&>(property))); } EnumType& currentAnimatedValue() @@ -58,9 +74,12 @@ private: : SVGAnimatedStaticPropertyTearOff<unsigned>(contextElement, attributeName, animatedPropertyType, property) { } + + static unsigned m_outOfRangeEnumValue; }; -} +// By convention, all enum values that represent UNKNOWN in SVG are equal to zero. +template<typename EnumType> +unsigned SVGAnimatedEnumerationPropertyTearOff<EnumType>::m_outOfRangeEnumValue = 0; -#endif // ENABLE(SVG) -#endif // SVGAnimatedEnumerationPropertyTearOff_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h index 9c6a277d3..0ce993793 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedListPropertyTearOff.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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 @@ -17,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedListPropertyTearOff_h -#define SVGAnimatedListPropertyTearOff_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedProperty.h" #include "SVGListPropertyTearOff.h" #include "SVGStaticListPropertyTearOff.h" @@ -33,42 +32,59 @@ class SVGPropertyTearOff; template<typename PropertyType> class SVGAnimatedListPropertyTearOff : public SVGAnimatedProperty { public: - typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; - typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; - typedef Vector<RefPtr<ListItemTearOff>> ListWrapperCache; - typedef SVGListProperty<PropertyType> ListProperty; - typedef SVGListPropertyTearOff<PropertyType> ListPropertyTearOff; - typedef PropertyType ContentType; - - virtual ListProperty* baseVal() + using ListItemType = typename SVGPropertyTraits<PropertyType>::ListItemType; + using ListItemTearOff = typename SVGPropertyTraits<PropertyType>::ListItemTearOff; + using ListWrapperCache = Vector<RefPtr<ListItemTearOff>>; + using ListProperty = SVGListProperty<PropertyType>; + using ListPropertyTearOff = typename SVGPropertyTraits<PropertyType>::ListPropertyTearOff; + using ContentType = PropertyType; + + static Ref<SVGAnimatedListPropertyTearOff<PropertyType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& values) { - if (!m_baseVal) - m_baseVal = ListPropertyTearOff::create(this, BaseValRole, m_values, m_wrappers); - return static_cast<ListProperty*>(m_baseVal.get()); + ASSERT(contextElement); + return adoptRef(*new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, values)); } - virtual ListProperty* animVal() + virtual Ref<ListPropertyTearOff> baseVal() { - if (!m_animVal) - m_animVal = ListPropertyTearOff::create(this, AnimValRole, m_values, m_wrappers); - return static_cast<ListProperty*>(m_animVal.get()); + if (m_baseVal) + return *m_baseVal; + + auto property = ListPropertyTearOff::create(*this, BaseValRole, m_values, m_wrappers); + m_baseVal = property.ptr(); + return property; } - virtual bool isAnimatedListTearOff() const override { return true; } + virtual Ref<ListPropertyTearOff> animVal() + { + if (m_animVal) + return *m_animVal; + + auto property = ListPropertyTearOff::create(*this, AnimValRole, m_values, m_wrappers); + m_animVal = property.ptr(); + return property; + } + + bool isAnimating() const override { return m_animatedProperty; } + bool isAnimatedListTearOff() const override { return true; } + void propertyWillBeDeleted(const SVGProperty& property) override + { + if (&property == m_baseVal) + m_baseVal = nullptr; + else if (&property == m_animVal) + m_animVal = nullptr; + } - int findItem(SVGProperty* property) const + int findItem(SVGProperty* property) { // This should ever be called for our baseVal, as animVal can't modify the list. - // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method. - typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::ListItemType> ListItemTearOff; - return static_cast<ListPropertyTearOff*>(m_baseVal.get())->findItem(static_cast<ListItemTearOff*>(property)); + return baseVal()->findItem(static_cast<ListItemTearOff*>(property)); } void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) { // This should ever be called for our baseVal, as animVal can't modify the list. - // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method. - static_cast<ListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers); + baseVal()->removeItemFromList(itemIndex, shouldSynchronizeWrappers); } void detachListWrappers(unsigned newListSize) @@ -78,9 +94,8 @@ public: PropertyType& currentAnimatedValue() { - ASSERT(m_isAnimating); - ASSERT(m_animVal); - return static_cast<ListProperty*>(m_animVal.get())->values(); + ASSERT(isAnimating()); + return m_animatedProperty->values(); } const PropertyType& currentBaseValue() const @@ -90,7 +105,7 @@ public: void animationStarted(PropertyType* newAnimVal, bool shouldOwnValues = false) { - ASSERT(!m_isAnimating); + ASSERT(!isAnimating()); ASSERT(newAnimVal); ASSERT(m_values.size() == m_wrappers.size()); ASSERT(m_animatedWrappers.isEmpty()); @@ -99,67 +114,55 @@ public: if (!newAnimVal->isEmpty()) m_animatedWrappers.fill(0, newAnimVal->size()); - ListProperty* animVal = static_cast<ListProperty*>(this->animVal()); - animVal->setValuesAndWrappers(newAnimVal, &m_animatedWrappers, shouldOwnValues); - ASSERT(animVal->values().size() == animVal->wrappers().size()); - ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); - m_isAnimating = true; + m_animatedProperty = animVal(); + m_animatedProperty->setValuesAndWrappers(newAnimVal, &m_animatedWrappers, shouldOwnValues); + ASSERT(m_animatedProperty->values().size() == m_animatedProperty->wrappers().size()); + ASSERT(m_animatedProperty->wrappers().size() == m_animatedWrappers.size()); } void animationEnded() { - ASSERT(m_isAnimating); - ASSERT(m_animVal); + ASSERT(isAnimating()); ASSERT(m_values.size() == m_wrappers.size()); - ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get()); - ASSERT(animVal->values().size() == animVal->wrappers().size()); - ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); + ASSERT(m_animatedProperty->values().size() == m_animatedProperty->wrappers().size()); + ASSERT(m_animatedProperty->wrappers().size() == m_animatedWrappers.size()); - animVal->setValuesAndWrappers(&m_values, &m_wrappers, false); - ASSERT(animVal->values().size() == animVal->wrappers().size()); - ASSERT(animVal->wrappers().size() == m_wrappers.size()); + m_animatedProperty->setValuesAndWrappers(&m_values, &m_wrappers, false); + ASSERT(m_animatedProperty->values().size() == m_animatedProperty->wrappers().size()); + ASSERT(m_animatedProperty->wrappers().size() == m_wrappers.size()); m_animatedWrappers.clear(); - m_isAnimating = false; + m_animatedProperty = nullptr; } void synchronizeWrappersIfNeeded() { + ASSERT(isAnimating()); + // Eventually the wrapper list needs synchronization because any SVGAnimateLengthList::calculateAnimatedValue() call may // mutate the length of our values() list, and thus the wrapper() cache needs synchronization, to have the same size. - // Also existing wrappers which point directly at elements in the existing SVGLengthList have to be detached (so a copy + // Also existing wrappers which point directly at elements in the existing SVGLengthListValues have to be detached (so a copy // of them is created, so existing animVal variables in JS are kept-alive). If we'd detach them later the underlying - // SVGLengthList was already mutated, and our list item wrapper tear offs would point nowhere. Assertions would fire. - ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get()); - animVal->detachListWrappers(animVal->values().size()); + // SVGLengthListValues was already mutated, and our list item wrapper tear offs would point nowhere. Assertions would fire. + m_animatedProperty->detachListWrappers(m_animatedProperty->values().size()); - ASSERT(animVal->values().size() == animVal->wrappers().size()); - ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); + ASSERT(m_animatedProperty->values().size() == m_animatedProperty->wrappers().size()); + ASSERT(m_animatedProperty->wrappers().size() == m_animatedWrappers.size()); } void animValWillChange() { - ASSERT(m_isAnimating); - ASSERT(m_animVal); ASSERT(m_values.size() == m_wrappers.size()); synchronizeWrappersIfNeeded(); } void animValDidChange() { - ASSERT(m_isAnimating); - ASSERT(m_animVal); ASSERT(m_values.size() == m_wrappers.size()); synchronizeWrappersIfNeeded(); } - static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& values) - { - ASSERT(contextElement); - return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, values)); - } - protected: SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& values) : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType) @@ -174,11 +177,13 @@ protected: ListWrapperCache m_wrappers; ListWrapperCache m_animatedWrappers; - RefPtr<SVGProperty> m_baseVal; - RefPtr<SVGProperty> m_animVal; -}; + // Cache the raw pointer but return a RefPtr<>. This will break the cyclic reference + // between SVGListPropertyTearOff and SVGAnimatedListPropertyTearOff once the property + // pointer is not needed. + ListPropertyTearOff* m_baseVal { nullptr }; + ListPropertyTearOff* m_animVal { nullptr }; -} + RefPtr<ListProperty> m_animatedProperty; +}; -#endif // ENABLE(SVG) -#endif // SVGAnimatedListPropertyTearOff_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h index 83ef8d617..5ab1a43f0 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h @@ -17,104 +17,109 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPathSegListPropertyTearOff_h -#define SVGAnimatedPathSegListPropertyTearOff_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedListPropertyTearOff.h" #include "SVGPathByteStream.h" #include "SVGPathElement.h" #include "SVGPathSegList.h" -#include "SVGPathSegListPropertyTearOff.h" #include "SVGPathUtilities.h" namespace WebCore { -class SVGAnimatedPathSegListPropertyTearOff : public SVGAnimatedListPropertyTearOff<SVGPathSegList> { +class SVGAnimatedPathSegListPropertyTearOff final : public SVGAnimatedListPropertyTearOff<SVGPathSegListValues> { public: - virtual SVGListProperty<SVGPathSegList>* baseVal() override + using Base = SVGAnimatedListPropertyTearOff<SVGPathSegListValues>; + + static Ref<SVGAnimatedPathSegListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegListValues& values) { - if (!m_baseVal) - m_baseVal = SVGPathSegListPropertyTearOff::create(this, BaseValRole, PathSegUnalteredRole, m_values, m_wrappers); - return static_cast<SVGListProperty<SVGPathSegList>*>(m_baseVal.get()); + ASSERT(contextElement); + return adoptRef(*new SVGAnimatedPathSegListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values)); } - virtual SVGListProperty<SVGPathSegList>* animVal() override + Ref<ListPropertyTearOff> baseVal() final { - if (!m_animVal) - m_animVal = SVGPathSegListPropertyTearOff::create(this, AnimValRole, PathSegUnalteredRole, m_values, m_wrappers); - return static_cast<SVGListProperty<SVGPathSegList>*>(m_animVal.get()); + if (m_baseVal) + return *m_baseVal; + + auto property = SVGPathSegList::create(*this, BaseValRole, PathSegUnalteredRole, m_values, m_wrappers); + m_baseVal = property.ptr(); + return property; } - int findItem(const RefPtr<SVGPathSeg>& segment) const + Ref<ListPropertyTearOff> animVal() final { - // This should ever be called for our baseVal, as animVal can't modify the list. - ASSERT(m_baseVal); - return static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->findItem(segment); + if (m_animVal) + return *m_animVal; + + auto property = SVGPathSegList::create(*this, AnimValRole, PathSegUnalteredRole, m_values, m_wrappers); + m_animVal = property.ptr(); + return property; } - void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) + int findItem(const RefPtr<SVGPathSeg>& segment) { - // This should ever be called for our baseVal, as animVal can't modify the list. - ASSERT(m_baseVal); - static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers); + return baseVal()->findItem(segment); } - static PassRefPtr<SVGAnimatedPathSegListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegList& values) + void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) { - ASSERT(contextElement); - return adoptRef(new SVGAnimatedPathSegListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values)); + baseVal()->removeItemFromList(itemIndex, shouldSynchronizeWrappers); } - using SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationStarted; - void animationStarted(SVGPathByteStream* byteStream, const SVGPathSegList* baseValue) + using Base::animationStarted; + void animationStarted(SVGPathByteStream* byteStream, const SVGPathSegListValues* baseValue) { ASSERT(byteStream); ASSERT(baseValue); ASSERT(!m_animatedPathByteStream); m_animatedPathByteStream = byteStream; - // Pass shouldOwnValues=true, as the SVGPathSegList lifetime is solely managed by its tear off class. - SVGPathSegList* copy = new SVGPathSegList(*baseValue); - SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationStarted(copy, true); + // Pass shouldOwnValues=true, as the SVGPathSegListValues lifetime is solely managed by its tear off class. + auto* copy = new SVGPathSegListValues(*baseValue); + Base::animationStarted(copy, true); } void animationEnded() { ASSERT(m_animatedPathByteStream); - m_animatedPathByteStream = 0; - SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationEnded(); + m_animatedPathByteStream = nullptr; + Base::animationEnded(); } void animValDidChange() { ASSERT(m_animatedPathByteStream); - SVGPathElement* pathElement = toSVGPathElement(contextElement()); + SVGPathElement* pathElement = downcast<SVGPathElement>(contextElement()); // If the animVal is observed from JS, we have to update it on each animation step. // This is an expensive operation and only done, if someone actually observes the animatedPathSegList() while an animation is running. if (pathElement->isAnimValObserved()) { - SVGPathSegList& animatedList = currentAnimatedValue(); + auto& animatedList = currentAnimatedValue(); animatedList.clear(); - buildSVGPathSegListFromByteStream(m_animatedPathByteStream, pathElement, animatedList, UnalteredParsing); + buildSVGPathSegListValuesFromByteStream(*m_animatedPathByteStream, *pathElement, animatedList, UnalteredParsing); } - SVGAnimatedListPropertyTearOff<SVGPathSegList>::animValDidChange(); + Base::animValDidChange(); } SVGPathByteStream* animatedPathByteStream() const { return m_animatedPathByteStream; } private: - SVGAnimatedPathSegListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegList& values) - : SVGAnimatedListPropertyTearOff<SVGPathSegList>(contextElement, attributeName, animatedPropertyType, values) - , m_animatedPathByteStream(0) + SVGAnimatedPathSegListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegListValues& values) + : Base(contextElement, attributeName, animatedPropertyType, values) + , m_animatedPathByteStream(nullptr) + { + ASSERT(contextElement); + ASSERT(is<SVGPathElement>(contextElement)); + } + + virtual ~SVGAnimatedPathSegListPropertyTearOff() { + downcast<SVGPathElement>(contextElement())->animatedPropertyWillBeDeleted(); } SVGPathByteStream* m_animatedPathByteStream; }; -} - -#endif // ENABLE(SVG) -#endif // SVGAnimatedPathSegListPropertyTearOff_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGAnimatedProperty.cpp b/Source/WebCore/svg/properties/SVGAnimatedProperty.cpp index 60fae5bbf..f24a8d871 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedProperty.cpp +++ b/Source/WebCore/svg/properties/SVGAnimatedProperty.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. * Copyright (C) 2013 Samsung Electronics. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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 @@ -19,8 +20,6 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAnimatedProperty.h" #include "SVGElement.h" @@ -31,7 +30,6 @@ SVGAnimatedProperty::SVGAnimatedProperty(SVGElement* contextElement, const Quali : m_contextElement(contextElement) , m_attributeName(attributeName) , m_animatedPropertyType(animatedPropertyType) - , m_isAnimating(false) , m_isReadOnly(false) { } @@ -39,16 +37,15 @@ SVGAnimatedProperty::SVGAnimatedProperty(SVGElement* contextElement, const Quali SVGAnimatedProperty::~SVGAnimatedProperty() { // Remove wrapper from cache. - Cache& cache = *animatedPropertyCache(); - for (auto it = cache.begin(), end = cache.end(); it != end; ++it) { - if (it->value == this) { - cache.remove(it); + for (auto& cache : *animatedPropertyCache()) { + if (cache.value == this) { + animatedPropertyCache()->remove(cache.key); break; } } // Assure that animationEnded() was called, if animationStarted() was called before. - ASSERT(!m_isAnimating); + ASSERT(!isAnimating()); } void SVGAnimatedProperty::commitChange() @@ -57,6 +54,8 @@ void SVGAnimatedProperty::commitChange() ASSERT(!m_contextElement->m_deletionHasBegun); m_contextElement->invalidateSVGAttributes(); m_contextElement->svgAttributeChanged(m_attributeName); + // Needed to synchronize with CSSOM for presentation attributes with SVG DOM. + m_contextElement->synchronizeAnimatedSVGAttribute(m_attributeName); } SVGAnimatedProperty::Cache* SVGAnimatedProperty::animatedPropertyCache() @@ -66,5 +65,3 @@ SVGAnimatedProperty::Cache* SVGAnimatedProperty::animatedPropertyCache() } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/properties/SVGAnimatedProperty.h b/Source/WebCore/svg/properties/SVGAnimatedProperty.h index 93f076b2b..b39772b41 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedProperty.h +++ b/Source/WebCore/svg/properties/SVGAnimatedProperty.h @@ -1,6 +1,7 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. * Copyright (C) 2013 Samsung Electronics. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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 @@ -18,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedProperty_h -#define SVGAnimatedProperty_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedPropertyDescription.h" #include "SVGPropertyInfo.h" #include <wtf/RefCounted.h> @@ -29,19 +28,21 @@ namespace WebCore { class SVGElement; +class SVGProperty; class SVGAnimatedProperty : public RefCounted<SVGAnimatedProperty> { public: SVGElement* contextElement() const { return m_contextElement.get(); } const QualifiedName& attributeName() const { return m_attributeName; } AnimatedPropertyType animatedPropertyType() const { return m_animatedPropertyType; } - bool isAnimating() const { return m_isAnimating; } bool isReadOnly() const { return m_isReadOnly; } void setIsReadOnly() { m_isReadOnly = true; } void commitChange(); + virtual bool isAnimating() const { return false; } virtual bool isAnimatedListTearOff() const { return false; } + virtual void propertyWillBeDeleted(const SVGProperty&) { } // Caching facilities. typedef HashMap<SVGAnimatedPropertyDescription, SVGAnimatedProperty*, SVGAnimatedPropertyDescriptionHash, SVGAnimatedPropertyDescriptionHashTraits> Cache; @@ -49,22 +50,27 @@ public: virtual ~SVGAnimatedProperty(); template<typename OwnerType, typename TearOffType, typename PropertyType> - static PassRefPtr<TearOffType> lookupOrCreateWrapper(OwnerType* element, const SVGPropertyInfo* info, PropertyType& property) + static Ref<TearOffType> lookupOrCreateWrapper(OwnerType* element, const SVGPropertyInfo* info, PropertyType& property) { ASSERT(info); SVGAnimatedPropertyDescription key(element, info->propertyIdentifier); - RefPtr<SVGAnimatedProperty> wrapper = animatedPropertyCache()->get(key); - if (!wrapper) { - wrapper = TearOffType::create(element, info->attributeName, info->animatedPropertyType, property); - if (info->animatedPropertyState == PropertyIsReadOnly) - wrapper->setIsReadOnly(); - animatedPropertyCache()->set(key, wrapper.get()); - } - return static_pointer_cast<TearOffType>(wrapper); + + auto result = animatedPropertyCache()->add(key, nullptr); + if (!result.isNewEntry) + return static_cast<TearOffType&>(*result.iterator->value); + + Ref<SVGAnimatedProperty> wrapper = TearOffType::create(element, info->attributeName, info->animatedPropertyType, property); + if (info->animatedPropertyState == PropertyIsReadOnly) + wrapper->setIsReadOnly(); + + // Cache the raw pointer but return a Ref<>. This will break the cyclic reference + // between SVGAnimatedProperty and SVGElement once the property pointer is not needed. + result.iterator->value = wrapper.ptr(); + return static_reference_cast<TearOffType>(wrapper); } template<typename OwnerType, typename TearOffType> - static TearOffType* lookupWrapper(OwnerType* element, const SVGPropertyInfo* info) + static RefPtr<TearOffType> lookupWrapper(OwnerType* element, const SVGPropertyInfo* info) { ASSERT(info); SVGAnimatedPropertyDescription key(element, info->propertyIdentifier); @@ -72,7 +78,7 @@ public: } template<typename OwnerType, typename TearOffType> - static TearOffType* lookupWrapper(const OwnerType* element, const SVGPropertyInfo* info) + static RefPtr<TearOffType> lookupWrapper(const OwnerType* element, const SVGPropertyInfo* info) { return lookupWrapper<OwnerType, TearOffType>(const_cast<OwnerType*>(element), info); } @@ -88,11 +94,7 @@ private: AnimatedPropertyType m_animatedPropertyType; protected: - bool m_isAnimating; bool m_isReadOnly; }; -} - -#endif // ENABLE(SVG) -#endif // SVGAnimatedProperty_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyDescription.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyDescription.h index 610fb148d..f1d9a04b0 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedPropertyDescription.h +++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyDescription.h @@ -19,10 +19,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPropertyDescription_h -#define SVGAnimatedPropertyDescription_h +#pragma once -#if ENABLE(SVG) #include <wtf/HashMap.h> #include <wtf/text/AtomicString.h> @@ -33,8 +31,8 @@ class SVGElement; struct SVGAnimatedPropertyDescription { // Empty value SVGAnimatedPropertyDescription() - : m_element(0) - , m_attributeName(0) + : m_element(nullptr) + , m_attributeName(nullptr) { } @@ -82,7 +80,4 @@ struct SVGAnimatedPropertyDescriptionHash { struct SVGAnimatedPropertyDescriptionHashTraits : WTF::SimpleClassHashTraits<SVGAnimatedPropertyDescription> { }; -} - -#endif // ENABLE(SVG) -#endif // SVGAnimatedPropertyDescription_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyMacros.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyMacros.h index 1ddbc5c6c..30f855679 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedPropertyMacros.h +++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyMacros.h @@ -19,14 +19,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPropertyMacros_h -#define SVGAnimatedPropertyMacros_h +#pragma once -#if ENABLE(SVG) #include "Element.h" #include "SVGAnimatedProperty.h" #include "SVGAttributeToPropertyMap.h" #include "SVGPropertyTraits.h" +#include <wtf/NeverDestroyed.h> #include <wtf/StdLibExtras.h> namespace WebCore { @@ -71,40 +70,36 @@ struct SVGSynchronizableAnimatedProperty { #define BEGIN_REGISTER_ANIMATED_PROPERTIES(OwnerType) \ SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \ { \ - DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, s_attributeToPropertyMap, ()); \ - return s_attributeToPropertyMap; \ + static NeverDestroyed<SVGAttributeToPropertyMap> map; \ + return map; \ } \ \ static void registerAnimatedPropertiesFor##OwnerType() \ { \ - SVGAttributeToPropertyMap& map = OwnerType::attributeToPropertyMap(); \ + auto& map = OwnerType::attributeToPropertyMap(); \ if (!map.isEmpty()) \ return; \ typedef OwnerType UseOwnerType; -#define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) \ - map.addProperty(UseOwnerType::LowerProperty##PropertyInfo()); - -#define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) \ - map.addProperties(ClassName::attributeToPropertyMap()); \ - +#define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) map.addProperty(*UseOwnerType::LowerProperty##PropertyInfo()); +#define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) map.addProperties(ClassName::attributeToPropertyMap()); #define END_REGISTER_ANIMATED_PROPERTIES } // Property definition helpers (used in SVG*.cpp files) #define DEFINE_ANIMATED_PROPERTY(AnimatedPropertyTypeEnum, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty) \ const SVGPropertyInfo* OwnerType::LowerProperty##PropertyInfo() { \ - DEFINE_STATIC_LOCAL(const SVGPropertyInfo, s_propertyInfo, \ + static NeverDestroyed<const SVGPropertyInfo> s_propertyInfo = SVGPropertyInfo \ (AnimatedPropertyTypeEnum, \ PropertyIsReadWrite, \ DOMAttribute, \ SVGDOMAttributeIdentifier, \ &OwnerType::synchronize##UpperProperty, \ - &OwnerType::lookupOrCreate##UpperProperty##Wrapper)); \ - return &s_propertyInfo; \ + &OwnerType::lookupOrCreate##UpperProperty##Wrapper); \ + return &s_propertyInfo.get(); \ } // Property declaration helpers (used in SVG*.h files) -#define BEGIN_DECLARE_ANIMATED_PROPERTIES(OwnerType) \ +#define BEGIN_DECLARE_ANIMATED_PROPERTIES_BASE(OwnerType) \ public: \ static SVGAttributeToPropertyMap& attributeToPropertyMap(); \ virtual SVGAttributeToPropertyMap& localAttributeToPropertyMap() \ @@ -113,33 +108,42 @@ public: \ } \ typedef OwnerType UseOwnerType; -#define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \ +#define BEGIN_DECLARE_ANIMATED_PROPERTIES(OwnerType) \ +public: \ + static SVGAttributeToPropertyMap& attributeToPropertyMap(); \ + SVGAttributeToPropertyMap& localAttributeToPropertyMap() override \ + { \ + return attributeToPropertyMap(); \ + } \ + typedef OwnerType UseOwnerType; + +#define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty, OverrideSpecifier) \ public: \ static const SVGPropertyInfo* LowerProperty##PropertyInfo(); \ PropertyType& LowerProperty() const \ { \ - if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \ + if (auto wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \ if (wrapper->isAnimating()) \ return wrapper->currentAnimatedValue(); \ } \ return m_##LowerProperty.value; \ } \ \ - PropertyType& LowerProperty##BaseValue() const \ + PropertyType& LowerProperty##BaseValue() const OverrideSpecifier \ { \ return m_##LowerProperty.value; \ } \ \ - void set##UpperProperty##BaseValue(const PropertyType& type, const bool validValue = true) \ + void set##UpperProperty##BaseValue(const PropertyType& type, const bool validValue = true) OverrideSpecifier \ { \ m_##LowerProperty.value = type; \ m_##LowerProperty.isValid = validValue; \ } \ \ - PassRefPtr<TearOffType> LowerProperty##Animated() \ + Ref<TearOffType> LowerProperty##Animated() \ { \ m_##LowerProperty.shouldSynchronize = true; \ - return static_pointer_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \ + return static_reference_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \ } \ \ bool LowerProperty##IsValid() const \ @@ -156,7 +160,7 @@ private: \ m_##LowerProperty.synchronize(this, LowerProperty##PropertyInfo()->attributeName, value); \ } \ \ - static PassRefPtr<SVGAnimatedProperty> lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType) \ + static Ref<SVGAnimatedProperty> lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType) \ { \ ASSERT(maskedOwnerType); \ UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \ @@ -176,14 +180,11 @@ private: \ // List specific definition/declaration helpers #define DECLARE_ANIMATED_LIST_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \ -DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \ +DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty, ) \ void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \ { \ - if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) \ + if (auto wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) \ wrapper->detachListWrappers(newListSize); \ } -} - -#endif // ENABLE(SVG) -#endif // SVGAnimatedPropertyMacros_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGAnimatedPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedPropertyTearOff.h index d406ff5d0..fc62c9da4 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedPropertyTearOff.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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 @@ -17,58 +18,60 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedPropertyTearOff_h -#define SVGAnimatedPropertyTearOff_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedProperty.h" #include "SVGPropertyTearOff.h" namespace WebCore { -template<typename PropertyType> -class SVGAnimatedPropertyTearOff : public SVGAnimatedProperty { +template<typename T> +class SVGAnimatedPropertyTearOff final : public SVGAnimatedProperty { public: - typedef SVGPropertyTearOff<PropertyType> PropertyTearOff; - typedef PropertyType ContentType; + using PropertyTearOff = T; + using PropertyType = typename PropertyTearOff::PropertyType; + using ContentType = PropertyType; - virtual ~SVGAnimatedPropertyTearOff() + static Ref<SVGAnimatedPropertyTearOff<PropertyTearOff>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property) { - if (m_baseVal) { - ASSERT(m_baseVal->animatedProperty() == this); - m_baseVal->setAnimatedProperty(0); - } - if (m_animVal) { - ASSERT(m_animVal->animatedProperty() == this); - m_animVal->setAnimatedProperty(0); - } + ASSERT(contextElement); + return adoptRef(*new SVGAnimatedPropertyTearOff<PropertyTearOff>(contextElement, attributeName, animatedPropertyType, property)); } - PropertyTearOff* baseVal() + Ref<PropertyTearOff> baseVal() { - if (!m_baseVal) - m_baseVal = PropertyTearOff::create(this, BaseValRole, m_property); - return m_baseVal.get(); + if (m_baseVal) + return *m_baseVal; + + auto property = PropertyTearOff::create(*this, BaseValRole, m_property); + m_baseVal = property.ptr(); + return property; } - PropertyTearOff* animVal() + Ref<PropertyTearOff> animVal() { - if (!m_animVal) - m_animVal = PropertyTearOff::create(this, AnimValRole, m_property); - return m_animVal.get(); + if (m_animVal) + return *m_animVal; + + auto property = PropertyTearOff::create(*this, AnimValRole, m_property); + m_animVal = property.ptr(); + return property; } - static PassRefPtr<SVGAnimatedPropertyTearOff<PropertyType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property) + bool isAnimating() const final { return m_animatedProperty; } + + void propertyWillBeDeleted(const SVGProperty& property) final { - ASSERT(contextElement); - return adoptRef(new SVGAnimatedPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property)); + if (&property == m_baseVal) + m_baseVal = nullptr; + else if (&property == m_animVal) + m_animVal = nullptr; } PropertyType& currentAnimatedValue() { - ASSERT(m_isAnimating); - ASSERT(m_animVal); - return m_animVal->propertyReference(); + ASSERT(isAnimating()); + return m_animatedProperty->propertyReference(); } const PropertyType& currentBaseValue() const @@ -78,32 +81,29 @@ public: void animationStarted(PropertyType* newAnimVal) { - ASSERT(!m_isAnimating); + ASSERT(!isAnimating()); ASSERT(newAnimVal); - animVal()->setValue(*newAnimVal); - m_isAnimating = true; + m_animatedProperty = animVal(); + m_animatedProperty->setValue(*newAnimVal); } void animationEnded() { - ASSERT(m_isAnimating); - ASSERT(m_animVal); - m_animVal->setValue(m_property); - m_isAnimating = false; + ASSERT(isAnimating()); + m_animatedProperty->setValue(m_property); + m_animatedProperty = nullptr; } void animValWillChange() { // no-op for non list types. - ASSERT(m_isAnimating); - ASSERT(m_animVal); + ASSERT(isAnimating()); } void animValDidChange() { // no-op for non list types. - ASSERT(m_isAnimating); - ASSERT(m_animVal); + ASSERT(isAnimating()); } private: @@ -114,11 +114,10 @@ private: } PropertyType& m_property; - RefPtr<PropertyTearOff> m_baseVal; - RefPtr<PropertyTearOff> m_animVal; + PropertyTearOff* m_baseVal { nullptr }; + PropertyTearOff* m_animVal { nullptr }; + + RefPtr<PropertyTearOff> m_animatedProperty; }; } - -#endif // ENABLE(SVG) -#endif // SVGAnimatedPropertyTearOff_h diff --git a/Source/WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h index b035bd91d..c5b2fd906 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedStaticPropertyTearOff.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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 @@ -17,11 +18,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedStaticPropertyTearOff_h -#define SVGAnimatedStaticPropertyTearOff_h +#pragma once -#if ENABLE(SVG) -#include "ExceptionCode.h" +#include "ExceptionOr.h" #include "SVGAnimatedProperty.h" namespace WebCore { @@ -31,34 +30,36 @@ class SVGAnimatedStaticPropertyTearOff : public SVGAnimatedProperty { public: typedef PropertyType ContentType; - PropertyType& baseVal() + virtual const PropertyType& baseVal() { return m_property; } - PropertyType& animVal() + virtual const PropertyType& animVal() { if (m_animatedProperty) return *m_animatedProperty; return m_property; } - virtual void setBaseVal(const PropertyType& property, ExceptionCode&) + virtual ExceptionOr<void> setBaseVal(const PropertyType& property) { m_property = property; commitChange(); + return { }; } - static PassRefPtr<SVGAnimatedStaticPropertyTearOff<PropertyType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property) + bool isAnimating() const override { return m_animatedProperty; } + + static Ref<SVGAnimatedStaticPropertyTearOff<PropertyType>> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property) { ASSERT(contextElement); - return adoptRef(new SVGAnimatedStaticPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property)); + return adoptRef(*new SVGAnimatedStaticPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property)); } PropertyType& currentAnimatedValue() { - ASSERT(m_isAnimating); - ASSERT(m_animatedProperty); + ASSERT(isAnimating()); return *m_animatedProperty; } @@ -69,40 +70,34 @@ public: void animationStarted(PropertyType* newAnimVal) { - ASSERT(!m_isAnimating); - ASSERT(!m_animatedProperty); + ASSERT(!isAnimating()); ASSERT(newAnimVal); m_animatedProperty = newAnimVal; - m_isAnimating = true; } void animationEnded() { - ASSERT(m_isAnimating); - ASSERT(m_animatedProperty); - m_animatedProperty = 0; - m_isAnimating = false; + ASSERT(isAnimating()); + m_animatedProperty = nullptr; } void animValWillChange() { // no-op for non list types. - ASSERT(m_isAnimating); - ASSERT(m_animatedProperty); + ASSERT(isAnimating()); } void animValDidChange() { // no-op for non list types. - ASSERT(m_isAnimating); - ASSERT(m_animatedProperty); + ASSERT(isAnimating()); } protected: SVGAnimatedStaticPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property) : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType) , m_property(property) - , m_animatedProperty(0) + , m_animatedProperty(nullptr) { } @@ -112,6 +107,3 @@ private: }; } - -#endif // ENABLE(SVG) -#endif // SVGAnimatedStaticPropertyTearOff_h diff --git a/Source/WebCore/svg/properties/SVGAnimatedTransformListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGAnimatedTransformListPropertyTearOff.h index ba133d4e4..435b3ac58 100644 --- a/Source/WebCore/svg/properties/SVGAnimatedTransformListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGAnimatedTransformListPropertyTearOff.h @@ -17,46 +17,46 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAnimatedTransformListPropertyTearOff_h -#define SVGAnimatedTransformListPropertyTearOff_h +#pragma once -#if ENABLE(SVG) #include "SVGAnimatedListPropertyTearOff.h" #include "SVGTransformList.h" -#include "SVGTransformListPropertyTearOff.h" namespace WebCore { -class SVGAnimatedTransformListPropertyTearOff : public SVGAnimatedListPropertyTearOff<SVGTransformList> { +class SVGAnimatedTransformListPropertyTearOff final : public SVGAnimatedListPropertyTearOff<SVGTransformListValues> { public: - virtual SVGListPropertyTearOff<SVGTransformList>* baseVal() override + static Ref<SVGAnimatedTransformListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformListValues& values) { - if (!m_baseVal) - m_baseVal = SVGTransformListPropertyTearOff::create(this, BaseValRole, m_values, m_wrappers); - return static_cast<SVGListPropertyTearOff<SVGTransformList>*>(m_baseVal.get()); + ASSERT(contextElement); + return adoptRef(*new SVGAnimatedTransformListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values)); } - virtual SVGListPropertyTearOff<SVGTransformList>* animVal() override + Ref<ListPropertyTearOff> baseVal() final { - if (!m_animVal) - m_animVal = SVGTransformListPropertyTearOff::create(this, AnimValRole, m_values, m_wrappers); - return static_cast<SVGListPropertyTearOff<SVGTransformList>*>(m_animVal.get()); + if (m_baseVal) + return *m_baseVal; + + auto property = SVGTransformList::create(*this, BaseValRole, m_values, m_wrappers); + m_baseVal = property.ptr(); + return property; } - static PassRefPtr<SVGAnimatedTransformListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformList& values) + Ref<ListPropertyTearOff> animVal() final { - ASSERT(contextElement); - return adoptRef(new SVGAnimatedTransformListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values)); + if (m_animVal) + return *m_animVal; + + auto property = SVGTransformList::create(*this, AnimValRole, m_values, m_wrappers); + m_animVal = property.ptr(); + return property; } private: - SVGAnimatedTransformListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformList& values) - : SVGAnimatedListPropertyTearOff<SVGTransformList>(contextElement, attributeName, animatedPropertyType, values) + SVGAnimatedTransformListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformListValues& values) + : SVGAnimatedListPropertyTearOff<SVGTransformListValues>(contextElement, attributeName, animatedPropertyType, values) { } }; -} - -#endif // ENABLE(SVG) -#endif // SVGAnimatedTransformListPropertyTearOff_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.cpp b/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.cpp index 2c3949bed..9629e58ca 100644 --- a/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.cpp +++ b/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -18,113 +19,68 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGAttributeToPropertyMap.h" #include "SVGAnimatedProperty.h" -#include "SVGPropertyInfo.h" namespace WebCore { void SVGAttributeToPropertyMap::addProperties(const SVGAttributeToPropertyMap& map) { - AttributeToPropertiesMap::const_iterator end = map.m_map.end(); - for (AttributeToPropertiesMap::const_iterator it = map.m_map.begin(); it != end; ++it) { - const PropertiesVector* vector = it->value.get(); - ASSERT(vector); - - // FIXME: This looks up the attribute name in the hash table for each property, even though all the - // properties in a single vector are guaranteed to have the same attribute name. - // FIXME: This grows the vector one item at a time, even though we know up front exactly how many - // elements we are adding to the vector. - PropertiesVector::const_iterator vectorEnd = vector->end(); - for (PropertiesVector::const_iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) - addProperty(*vectorIt); + for (auto& vector : map.m_map.values()) { + ASSERT(!vector.isEmpty()); + auto& properties = m_map.add(vector[0]->attributeName, PropertyInfoVector()).iterator->value; + properties.reserveCapacity(properties.size() + vector.size()); + for (auto* property : vector) + properties.uncheckedAppend(property); } } -void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo* info) +void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo& info) { - ASSERT(info); - ASSERT(info->attributeName != anyQName()); - if (PropertiesVector* vector = m_map.get(info->attributeName)) { - vector->append(info); - return; - } - // FIXME: This does a second hash table lookup, but with HashMap::add we could instead do only one. - auto vector = std::make_unique<PropertiesVector>(); - vector->append(info); - m_map.set(info->attributeName, std::move(vector)); + m_map.add(info.attributeName, PropertyInfoVector()).iterator->value.append(&info); } -void SVGAttributeToPropertyMap::animatedPropertiesForAttribute(SVGElement* ownerType, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty>>& properties) +Vector<RefPtr<SVGAnimatedProperty>> SVGAttributeToPropertyMap::properties(SVGElement& contextElement, const QualifiedName& attributeName) const { - ASSERT(ownerType); - PropertiesVector* vector = m_map.get(attributeName); - if (!vector) - return; - - PropertiesVector::iterator vectorEnd = vector->end(); - for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) - properties.append(animatedProperty(ownerType, attributeName, *vectorIt)); + Vector<RefPtr<SVGAnimatedProperty>> properties; + auto it = m_map.find(attributeName); + if (it == m_map.end()) + return properties; + properties.reserveInitialCapacity(it->value.size()); + for (auto* property : it->value) + properties.uncheckedAppend(property->lookupOrCreateWrapperForAnimatedProperty(&contextElement)); + return properties; } -void SVGAttributeToPropertyMap::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes) +Vector<AnimatedPropertyType> SVGAttributeToPropertyMap::types(const QualifiedName& attributeName) const { - PropertiesVector* vector = m_map.get(attributeName); - if (!vector) - return; - - PropertiesVector::iterator vectorEnd = vector->end(); - for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) - propertyTypes.append((*vectorIt)->animatedPropertyType); + Vector<AnimatedPropertyType> types; + auto it = m_map.find(attributeName); + if (it == m_map.end()) + return types; + types.reserveInitialCapacity(it->value.size()); + for (auto* property : it->value) + types.uncheckedAppend(property->animatedPropertyType); + return types; } -void SVGAttributeToPropertyMap::synchronizeProperties(SVGElement* contextElement) +void SVGAttributeToPropertyMap::synchronizeProperties(SVGElement& contextElement) const { - ASSERT(contextElement); - AttributeToPropertiesMap::iterator end = m_map.end(); - for (AttributeToPropertiesMap::iterator it = m_map.begin(); it != end; ++it) { - PropertiesVector* vector = it->value.get(); - ASSERT(vector); - - PropertiesVector::iterator vectorEnd = vector->end(); - for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) - synchronizeProperty(contextElement, it->key, *vectorIt); + for (auto& vector : m_map.values()) { + for (auto* property : vector) + property->synchronizeProperty(&contextElement); } } -bool SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName) +bool SVGAttributeToPropertyMap::synchronizeProperty(SVGElement& contextElement, const QualifiedName& attributeName) const { - ASSERT(contextElement); - PropertiesVector* vector = m_map.get(attributeName); - if (!vector) + auto it = m_map.find(attributeName); + if (it == m_map.end()) return false; - - PropertiesVector::iterator vectorEnd = vector->end(); - for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) - synchronizeProperty(contextElement, attributeName, *vectorIt); - + for (auto* property : it->value) + property->synchronizeProperty(&contextElement); return true; } -void SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info) -{ - ASSERT(info); - ASSERT_UNUSED(attributeName, attributeName == info->attributeName); - ASSERT(info->synchronizeProperty); - (*info->synchronizeProperty)(contextElement); -} - -PassRefPtr<SVGAnimatedProperty> SVGAttributeToPropertyMap::animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info) -{ - ASSERT(info); - ASSERT_UNUSED(attributeName, attributeName == info->attributeName); - ASSERT(info->lookupOrCreateWrapperForAnimatedProperty); - return (*info->lookupOrCreateWrapperForAnimatedProperty)(contextElement); } - -} - -#endif diff --git a/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.h b/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.h index 0ba24254e..94768056a 100644 --- a/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.h +++ b/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2015 Apple Inc. 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 @@ -17,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGAttributeToPropertyMap_h -#define SVGAttributeToPropertyMap_h +#pragma once -#if ENABLE(SVG) #include "SVGPropertyInfo.h" #include <wtf/HashMap.h> @@ -33,27 +32,18 @@ class SVGAttributeToPropertyMap { public: bool isEmpty() const { return m_map.isEmpty(); } + void addProperty(const SVGPropertyInfo&); void addProperties(const SVGAttributeToPropertyMap&); - void addProperty(const SVGPropertyInfo*); - // FIXME: To match WebKit coding style either these functions should have return values instead of out parameters, - // or the word "get" should be added as a prefix to their names. - void animatedPropertiesForAttribute(SVGElement* contextElement, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty>>&); - void animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>&); + Vector<RefPtr<SVGAnimatedProperty>> properties(SVGElement&, const QualifiedName& attributeName) const; + Vector<AnimatedPropertyType> types(const QualifiedName& attributeName) const; - void synchronizeProperties(SVGElement* contextElement); - bool synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName); + void synchronizeProperties(SVGElement&) const; + bool synchronizeProperty(SVGElement&, const QualifiedName& attributeName) const; private: - void synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*); - PassRefPtr<SVGAnimatedProperty> animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*); - - typedef Vector<const SVGPropertyInfo*> PropertiesVector; - typedef HashMap<QualifiedName, std::unique_ptr<PropertiesVector>> AttributeToPropertiesMap; - AttributeToPropertiesMap m_map; + typedef Vector<const SVGPropertyInfo*> PropertyInfoVector; + HashMap<QualifiedName, PropertyInfoVector> m_map; }; -} - -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGListProperty.h b/Source/WebCore/svg/properties/SVGListProperty.h index 80c4b62d8..9b0d42032 100644 --- a/Source/WebCore/svg/properties/SVGListProperty.h +++ b/Source/WebCore/svg/properties/SVGListProperty.h @@ -17,13 +17,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGListProperty_h -#define SVGListProperty_h +#pragma once -#if ENABLE(SVG) +#include "ExceptionCode.h" #include "SVGException.h" #include "SVGPropertyTearOff.h" #include "SVGPropertyTraits.h" +#include <wtf/Ref.h> namespace WebCore { @@ -43,18 +43,15 @@ class SVGListProperty : public SVGProperty { public: typedef SVGListProperty<PropertyType> Self; - typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; - typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; - typedef PassRefPtr<ListItemTearOff> PassListItemTearOff; - typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff; - typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache; + using ListItemType = typename SVGPropertyTraits<PropertyType>::ListItemType; + using ListItemTearOff = typename SVGPropertyTraits<PropertyType>::ListItemTearOff; + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<PropertyType>; + using ListWrapperCache = typename AnimatedListPropertyTearOff::ListWrapperCache; - bool canAlterList(ExceptionCode& ec) const + ExceptionOr<bool> canAlterList() const { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return false; - } + if (m_role == AnimValRole) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; return true; } @@ -63,9 +60,8 @@ public: { // See SVGPropertyTearOff::detachWrapper() for an explanation about what's happening here. ASSERT(wrappers); - unsigned size = wrappers->size(); - for (unsigned i = 0; i < size; ++i) { - if (ListItemTearOff* item = wrappers->at(i).get()) + for (auto& item : *wrappers) { + if (item) item->detachWrapper(); } @@ -97,23 +93,29 @@ public: } // SVGList::clear() - void clearValues(ExceptionCode& ec) + ExceptionOr<void> clearValues() { - if (!canAlterList(ec)) - return; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); m_values->clear(); commitChange(); + return { }; } - void clearValuesAndWrappers(ExceptionCode& ec) + ExceptionOr<void> clearValuesAndWrappers() { - if (!canAlterList(ec)) - return; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); detachListWrappers(0); m_values->clear(); commitChange(); + return { }; } // SVGList::numberOfItems() @@ -123,10 +125,12 @@ public: } // SVGList::initialize() - ListItemType initializeValues(const ListItemType& newItem, ExceptionCode& ec) + ExceptionOr<ListItemType> initializeValues(const ListItemType& newItem) { - if (!canAlterList(ec)) - return ListItemType(); + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemValue(newItem, 0); @@ -136,24 +140,22 @@ public: m_values->append(newItem); commitChange(); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff initializeValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> initializeValuesAndWrappers(ListItemTearOff& item) { ASSERT(m_wrappers); - if (!canAlterList(ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - RefPtr<ListItemTearOff> newItem = passNewItem; ASSERT(m_values->size() == m_wrappers->size()); + Ref<ListItemTearOff> newItem(item); + // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemWrapper(newItem, 0); @@ -162,37 +164,40 @@ public: m_values->clear(); m_values->append(newItem->propertyReference()); - m_wrappers->append(newItem); + m_wrappers->append(newItem.ptr()); commitChange(); - return newItem.release(); + return WTFMove(newItem); } // SVGList::getItem() - bool canGetItem(unsigned index, ExceptionCode& ec) + ExceptionOr<bool> canGetItem(unsigned index) { - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return false; - } + if (index >= m_values->size()) + return Exception { INDEX_SIZE_ERR }; return true; } - ListItemType getItemValues(unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> getItemValues(unsigned index) { - if (!canGetItem(index, ec)) - return ListItemType(); + auto result = canGetItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy. - return m_values->at(index); + return ListItemType { m_values->at(index) }; } - PassListItemTearOff getItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> getItemValuesAndWrappers(AnimatedListPropertyTearOff& animatedList, unsigned index) { ASSERT(m_wrappers); - if (!canGetItem(index, ec)) - return 0; + + auto result = canGetItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy. // Any changes made to the item are immediately reflected in the list. @@ -206,14 +211,16 @@ public: m_wrappers->at(index) = wrapper; } - return wrapper.release(); + return wrapper.releaseNonNull(); } // SVGList::insertItemBefore() - ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> insertItemBeforeValues(const ListItemType& newItem, unsigned index) { - if (!canAlterList(ec)) - return ListItemType(); + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. if (index > m_values->size()) @@ -222,7 +229,7 @@ public: // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. if (!processIncomingListItemValue(newItem, &index)) { // Inserting the item before itself is a no-op. - return newItem; + return ListItemType { newItem }; } // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be @@ -230,107 +237,103 @@ public: m_values->insert(index, newItem); commitChange(); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> insertItemBeforeValuesAndWrappers(ListItemTearOff& item, unsigned index) { ASSERT(m_wrappers); - if (!canAlterList(ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. if (index > m_values->size()) - index = m_values->size(); + index = m_values->size(); - RefPtr<ListItemTearOff> newItem = passNewItem; ASSERT(m_values->size() == m_wrappers->size()); + Ref<ListItemTearOff> newItem(item); + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. if (!processIncomingListItemWrapper(newItem, &index)) - return newItem.release(); + return WTFMove(newItem); // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. m_values->insert(index, newItem->propertyReference()); // Store new wrapper at position 'index', change its underlying value, so mutations of newItem, directly affect the item in the list. - m_wrappers->insert(index, newItem); + m_wrappers->insert(index, newItem.ptr()); commitChange(); - return newItem.release(); + return WTFMove(newItem); } // SVGList::replaceItem() - bool canReplaceItem(unsigned index, ExceptionCode& ec) + ExceptionOr<bool> canReplaceItem(unsigned index) { - if (!canAlterList(ec)) - return false; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return false; - } + if (index >= m_values->size()) + return Exception { INDEX_SIZE_ERR }; return true; } - ListItemType replaceItemValues(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> replaceItemValues(const ListItemType& newItem, unsigned index) { - if (!canReplaceItem(index, ec)) - return ListItemType(); + auto result = canReplaceItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. if (!processIncomingListItemValue(newItem, &index)) { // Replacing the item with itself is a no-op. - return newItem; + return ListItemType { newItem }; } if (m_values->isEmpty()) { // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace. - ec = INDEX_SIZE_ERR; - return ListItemType(); + return Exception { INDEX_SIZE_ERR }; } // Update the value at the desired position 'index'. m_values->at(index) = newItem; commitChange(); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff replaceItemValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> replaceItemValuesAndWrappers(ListItemTearOff& item, unsigned index) { ASSERT(m_wrappers); - if (!canReplaceItem(index, ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canReplaceItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); ASSERT(m_values->size() == m_wrappers->size()); - RefPtr<ListItemTearOff> newItem = passNewItem; + + Ref<ListItemTearOff> newItem(item); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. if (!processIncomingListItemWrapper(newItem, &index)) - return newItem.release(); + return WTFMove(newItem); if (m_values->isEmpty()) { ASSERT(m_wrappers->isEmpty()); - // 'passNewItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace. - ec = INDEX_SIZE_ERR; - return 0; + // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace. + return Exception { INDEX_SIZE_ERR }; } // Detach the existing wrapper. @@ -340,43 +343,48 @@ public: // Update the value and the wrapper at the desired position 'index'. m_values->at(index) = newItem->propertyReference(); - m_wrappers->at(index) = newItem; + m_wrappers->at(index) = newItem.ptr(); commitChange(); - return newItem.release(); + return WTFMove(newItem); } // SVGList::removeItem() - bool canRemoveItem(unsigned index, ExceptionCode& ec) + ExceptionOr<bool> canRemoveItem(unsigned index) { - if (!canAlterList(ec)) - return false; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return false; - } + if (index >= m_values->size()) + return Exception { INDEX_SIZE_ERR }; return true; } - ListItemType removeItemValues(unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> removeItemValues(unsigned index) { - if (!canRemoveItem(index, ec)) - return ListItemType(); + auto result = canRemoveItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); ListItemType oldItem = m_values->at(index); m_values->remove(index); commitChange(); - return oldItem; + return WTFMove(oldItem); } - PassListItemTearOff removeItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> removeItemValuesAndWrappers(AnimatedListPropertyTearOff& animatedList, unsigned index) { ASSERT(m_wrappers); - if (!canRemoveItem(index, ec)) - return 0; + + auto result = canRemoveItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); ASSERT(m_values->size() == m_wrappers->size()); @@ -390,14 +398,16 @@ public: m_values->remove(index); commitChange(); - return oldItem.release(); + return oldItem.releaseNonNull(); } // SVGList::appendItem() - ListItemType appendItemValues(const ListItemType& newItem, ExceptionCode& ec) + ExceptionOr<ListItemType> appendItemValues(const ListItemType& newItem) { - if (!canAlterList(ec)) - return ListItemType(); + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemValue(newItem, 0); @@ -406,33 +416,31 @@ public: m_values->append(newItem); commitChange(ListModificationAppend); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff appendItemValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> appendItemValuesAndWrappers(ListItemTearOff& item) { ASSERT(m_wrappers); - if (!canAlterList(ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - RefPtr<ListItemTearOff> newItem = passNewItem; ASSERT(m_values->size() == m_wrappers->size()); + Ref<ListItemTearOff> newItem(item); + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemWrapper(newItem, 0); // Append the value and wrapper at the end of the list. m_values->append(newItem->propertyReference()); - m_wrappers->append(newItem); + m_wrappers->append(newItem.ptr()); commitChange(ListModificationAppend); - return newItem.release(); + return WTFMove(newItem); } PropertyType& values() @@ -462,14 +470,14 @@ protected: delete m_values; } - virtual void commitChange() = 0; + void commitChange() override = 0; virtual void commitChange(ListModification) { commitChange(); } virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) = 0; - virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) = 0; + virtual bool processIncomingListItemWrapper(Ref<ListItemTearOff>& newItem, unsigned* indexToModify) = 0; SVGPropertyRole m_role; bool m_ownsValues; @@ -478,6 +486,3 @@ protected: }; } - -#endif // ENABLE(SVG) -#endif // SVGListProperty_h diff --git a/Source/WebCore/svg/properties/SVGListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGListPropertyTearOff.h index 674d93d75..86f70b53d 100644 --- a/Source/WebCore/svg/properties/SVGListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGListPropertyTearOff.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGListPropertyTearOff_h -#define SVGListPropertyTearOff_h +#pragma once -#if ENABLE(SVG) #include "SVGListProperty.h" namespace WebCore { @@ -28,23 +26,22 @@ namespace WebCore { template<typename PropertyType> class SVGListPropertyTearOff : public SVGListProperty<PropertyType> { public: - typedef SVGListProperty<PropertyType> Base; - typedef SVGListPropertyTearOff<PropertyType> Self; + using Base = SVGListProperty<PropertyType>; + using Self = SVGListPropertyTearOff<PropertyType>; - typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; - typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; - typedef PassRefPtr<ListItemTearOff> PassListItemTearOff; - typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff; - typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache; + using ListItemType = typename SVGPropertyTraits<PropertyType>::ListItemType; + using ListItemTearOff = typename SVGPropertyTraits<PropertyType>::ListItemTearOff; + using PtrListItemTearOff = RefPtr<ListItemTearOff>; + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<PropertyType>; + using ListWrapperCache = typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache; using Base::m_role; using Base::m_values; using Base::m_wrappers; - static PassRefPtr<Self> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers) + static Ref<Self> create(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers) { - ASSERT(animatedProperty); - return adoptRef(new Self(animatedProperty, role, values, wrappers)); + return adoptRef(*new Self(animatedProperty, role, values, wrappers)); } int findItem(ListItemTearOff* item) const @@ -79,58 +76,63 @@ public: } // SVGList API - void clear(ExceptionCode& ec) + ExceptionOr<void> clear() { - Base::clearValuesAndWrappers(ec); + return Base::clearValuesAndWrappers(); } - PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> initialize(ListItemTearOff& newItem) { - return Base::initializeValuesAndWrappers(passNewItem, ec); + return Base::initializeValuesAndWrappers(newItem); } - PassListItemTearOff getItem(unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> getItem(unsigned index) { - return Base::getItemValuesAndWrappers(m_animatedProperty.get(), index, ec); + return Base::getItemValuesAndWrappers(m_animatedProperty.get(), index); } - PassListItemTearOff insertItemBefore(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> insertItemBefore(ListItemTearOff& newItem, unsigned index) { - return Base::insertItemBeforeValuesAndWrappers(passNewItem, index, ec); + return Base::insertItemBeforeValuesAndWrappers(newItem, index); } - PassListItemTearOff replaceItem(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> replaceItem(ListItemTearOff& newItem, unsigned index) { - return Base::replaceItemValuesAndWrappers(passNewItem, index, ec); + return Base::replaceItemValuesAndWrappers(newItem, index); } - PassListItemTearOff removeItem(unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> removeItem(unsigned index) { - return Base::removeItemValuesAndWrappers(m_animatedProperty.get(), index, ec); + return Base::removeItemValuesAndWrappers(m_animatedProperty.get(), index); } - PassListItemTearOff appendItem(PassListItemTearOff passNewItem, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> appendItem(ListItemTearOff& newItem) { - return Base::appendItemValuesAndWrappers(passNewItem, ec); + return Base::appendItemValuesAndWrappers(newItem); } protected: - SVGListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers) + SVGListPropertyTearOff(AnimatedListPropertyTearOff& animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers) : SVGListProperty<PropertyType>(role, values, &wrappers) , m_animatedProperty(animatedProperty) { } - virtual bool isReadOnly() const override + virtual ~SVGListPropertyTearOff() + { + m_animatedProperty->propertyWillBeDeleted(*this); + } + + bool isReadOnly() const override { if (m_role == AnimValRole) return true; - if (m_animatedProperty && m_animatedProperty->isReadOnly()) + if (m_animatedProperty->isReadOnly()) return true; return false; } - virtual void commitChange() override + void commitChange() override { ASSERT(m_values); ASSERT(m_wrappers); @@ -142,20 +144,20 @@ protected: ListItemTearOff* item = m_wrappers->at(i).get(); if (!item) continue; - item->setAnimatedProperty(m_animatedProperty.get()); + item->setAnimatedProperty(m_animatedProperty.ptr()); item->setValue(m_values->at(i)); } m_animatedProperty->commitChange(); } - virtual bool processIncomingListItemValue(const ListItemType&, unsigned*) override + bool processIncomingListItemValue(const ListItemType&, unsigned*) override { ASSERT_NOT_REACHED(); return true; } - virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) override + bool processIncomingListItemWrapper(Ref<ListItemTearOff>& newItem, unsigned* indexToModify) override { SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(); @@ -178,9 +180,9 @@ protected: // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. - bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; + bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty.ptr(); AnimatedListPropertyTearOff* propertyTearOff = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem); - int indexToRemove = propertyTearOff->findItem(newItem.get()); + int indexToRemove = propertyTearOff->findItem(newItem.ptr()); ASSERT(indexToRemove != -1); // Do not remove newItem if already in this list at the target index. @@ -205,10 +207,7 @@ protected: // Back pointer to the animated property that created us // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAnimatedLengthList object - RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; + Ref<AnimatedListPropertyTearOff> m_animatedProperty; }; } - -#endif // ENABLE(SVG) -#endif // SVGListPropertyTearOff_h diff --git a/Source/WebCore/svg/properties/SVGMatrixTearOff.h b/Source/WebCore/svg/properties/SVGMatrixTearOff.h index a7ae98855..0188031ce 100644 --- a/Source/WebCore/svg/properties/SVGMatrixTearOff.h +++ b/Source/WebCore/svg/properties/SVGMatrixTearOff.h @@ -17,46 +17,43 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGMatrixTearOff_h -#define SVGMatrixTearOff_h +#pragma once -#if ENABLE(SVG) -#include "SVGPropertyTearOff.h" +#include "SVGMatrix.h" #include "SVGTransform.h" namespace WebCore { -class SVGMatrixTearOff : public SVGPropertyTearOff<SVGMatrix> { +class SVGMatrixTearOff final : public SVGMatrix { public: - // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute - // and that contain a parent type that's exposed to the bindings via a SVGStaticPropertyTearOff object - // (for example: SVGTransform::matrix). - static PassRefPtr<SVGMatrixTearOff> create(SVGPropertyTearOff<SVGTransform>& parent, SVGMatrix& value) + static Ref<SVGMatrixTearOff> create(SVGTransform& parent, SVGMatrixValue& value) { - RefPtr<SVGMatrixTearOff> result = adoptRef(new SVGMatrixTearOff(&parent, value)); + ASSERT_UNUSED(value, &parent.propertyReference().svgMatrix() == &value); + Ref<SVGMatrixTearOff> result = adoptRef(*new SVGMatrixTearOff(parent)); parent.addChild(result->m_weakFactory.createWeakPtr()); - return result.release(); + return result; } - virtual void commitChange() + SVGMatrixValue& propertyReference() final { return m_parent->propertyReference().svgMatrix(); } + + void setValue(SVGMatrixValue& value) final { m_parent->propertyReference().setMatrix(value); } + + void commitChange() final { m_parent->propertyReference().updateSVGMatrix(); m_parent->commitChange(); } private: - SVGMatrixTearOff(SVGPropertyTearOff<SVGTransform>* parent, SVGMatrix& value) - : SVGPropertyTearOff<SVGMatrix>(0, UndefinedRole, value) - , m_parent(parent) + SVGMatrixTearOff(SVGTransform& parent) + : SVGMatrix(nullptr) + , m_parent(&parent) , m_weakFactory(this) { } - RefPtr<SVGPropertyTearOff<SVGTransform>> m_parent; + RefPtr<SVGTransform> m_parent; WeakPtrFactory<SVGPropertyTearOffBase> m_weakFactory; }; -} - -#endif // ENABLE(SVG) -#endif // SVGMatrixTearOff_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.cpp b/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.cpp deleted file mode 100644 index 573d453a4..000000000 --- a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#if ENABLE(SVG) -#include "SVGPathSegListPropertyTearOff.h" - -#include "SVGAnimatedPathSegListPropertyTearOff.h" -#include "SVGNames.h" -#include "SVGPathElement.h" -#include "SVGPathSegWithContext.h" - -namespace WebCore { - -void SVGPathSegListPropertyTearOff::clearContextAndRoles() -{ - ASSERT(m_values); - unsigned size = m_values->size(); - for (unsigned i = 0; i < size; ++i) { - ListItemType item = m_values->at(i); - static_cast<SVGPathSegWithContext*>(item.get())->setContextAndRole(0, PathSegUndefinedRole); - } -} - -void SVGPathSegListPropertyTearOff::clear(ExceptionCode& ec) -{ - ASSERT(m_values); - if (m_values->isEmpty()) - return; - - clearContextAndRoles(); - SVGPathSegListPropertyTearOff::Base::clearValues(ec); -} - -SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::getItem(unsigned index, ExceptionCode& ec) -{ - ListItemType returnedItem = Base::getItemValues(index, ec); - if (returnedItem) { - ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->contextElement() == contextElement()); - ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->role() == m_pathSegRole); - } - return returnedItem.release(); -} - -SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::replaceItem(PassListItemType passNewItem, unsigned index, ExceptionCode& ec) -{ - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } - - if (index < m_values->size()) { - ListItemType replacedItem = m_values->at(index); - ASSERT(replacedItem); - static_cast<SVGPathSegWithContext*>(replacedItem.get())->setContextAndRole(0, PathSegUndefinedRole); - } - - ListItemType newItem = passNewItem; - return Base::replaceItemValues(newItem, index, ec); -} - -SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::removeItem(unsigned index, ExceptionCode& ec) -{ - SVGPathSegListPropertyTearOff::ListItemType removedItem = SVGPathSegListPropertyTearOff::Base::removeItemValues(index, ec); - if (removedItem) - static_cast<SVGPathSegWithContext*>(removedItem.get())->setContextAndRole(0, PathSegUndefinedRole); - return removedItem.release(); -} - -SVGPathElement* SVGPathSegListPropertyTearOff::contextElement() const -{ - SVGElement* contextElement = m_animatedProperty->contextElement(); - ASSERT(contextElement); - return toSVGPathElement(contextElement); -} - -bool SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) -{ - SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get()); - SVGAnimatedProperty* animatedPropertyOfItem = newItemWithContext->animatedProperty(); - - // Alter the role, after calling animatedProperty(), as that may influence the returned animated property. - newItemWithContext->setContextAndRole(contextElement(), m_pathSegRole); - - if (!animatedPropertyOfItem) - return true; - - // newItem belongs to a SVGPathElement, but its associated SVGAnimatedProperty is not an animated list tear off. - // (for example: "pathElement.pathSegList.appendItem(pathElement.createSVGPathSegClosepath())") - if (!animatedPropertyOfItem->isAnimatedListTearOff()) - return true; - - // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. - // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. - bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; - SVGAnimatedPathSegListPropertyTearOff* propertyTearOff = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(animatedPropertyOfItem); - int indexToRemove = propertyTearOff->findItem(newItem.get()); - ASSERT(indexToRemove != -1); - - // Do not remove newItem if already in this list at the target index. - if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify) - return false; - - propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); - - if (!indexToModify) - return true; - - // If the item lived in our list, adjust the insertion index. - if (!livesInOtherList) { - unsigned& index = *indexToModify; - // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item. - if (static_cast<unsigned>(indexToRemove) < index) - --index; - } - - return true; -} - -} - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.h deleted file mode 100644 index aaed821bf..000000000 --- a/Source/WebCore/svg/properties/SVGPathSegListPropertyTearOff.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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 SVGPathSegListPropertyTearOff_h -#define SVGPathSegListPropertyTearOff_h - -#if ENABLE(SVG) -#include "SVGAnimatedListPropertyTearOff.h" -#include "SVGPathSegList.h" - -namespace WebCore { - -class SVGPathElement; - -class SVGPathSegListPropertyTearOff : public SVGListProperty<SVGPathSegList> { -public: - typedef SVGListProperty<SVGPathSegList> Base; - typedef SVGAnimatedListPropertyTearOff<SVGPathSegList> AnimatedListPropertyTearOff; - typedef SVGPropertyTraits<SVGPathSegList>::ListItemType ListItemType; - typedef PassRefPtr<SVGPathSeg> PassListItemType; - - static PassRefPtr<SVGPathSegListPropertyTearOff> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers) - { - ASSERT(animatedProperty); - return adoptRef(new SVGPathSegListPropertyTearOff(animatedProperty, role, pathSegRole, values, wrappers)); - } - - int findItem(const ListItemType& item) const - { - ASSERT(m_values); - - unsigned size = m_values->size(); - for (size_t i = 0; i < size; ++i) { - if (item == m_values->at(i)) - return i; - } - - return -1; - } - - void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) - { - ASSERT(m_values); - ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_values->size()); - - m_values->remove(itemIndex); - - if (shouldSynchronizeWrappers) - commitChange(); - } - - // SVGList API - void clear(ExceptionCode&); - - PassListItemType initialize(PassListItemType passNewItem, ExceptionCode& ec) - { - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } - - clearContextAndRoles(); - ListItemType newItem = passNewItem; - return Base::initializeValues(newItem, ec); - } - - PassListItemType getItem(unsigned index, ExceptionCode&); - - PassListItemType insertItemBefore(PassListItemType passNewItem, unsigned index, ExceptionCode& ec) - { - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } - - ListItemType newItem = passNewItem; - return Base::insertItemBeforeValues(newItem, index, ec); - } - - PassListItemType replaceItem(PassListItemType, unsigned index, ExceptionCode&); - - PassListItemType removeItem(unsigned index, ExceptionCode&); - - PassListItemType appendItem(PassListItemType passNewItem, ExceptionCode& ec) - { - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } - - ListItemType newItem = passNewItem; - return Base::appendItemValues(newItem, ec); - } - -private: - SVGPathSegListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers) - : SVGListProperty<SVGPathSegList>(role, values, &wrappers) - , m_animatedProperty(animatedProperty) - , m_pathSegRole(pathSegRole) - { - } - - SVGPathElement* contextElement() const; - - void clearContextAndRoles(); - - using Base::m_role; - - virtual bool isReadOnly() const override - { - if (m_role == AnimValRole) - return true; - if (m_animatedProperty && m_animatedProperty->isReadOnly()) - return true; - return false; - } - - virtual void commitChange() override - { - ASSERT(m_values); - m_values->commitChange(m_animatedProperty->contextElement(), ListModificationUnknown); - } - - virtual void commitChange(ListModification listModification) override - { - ASSERT(m_values); - m_values->commitChange(m_animatedProperty->contextElement(), listModification); - } - - virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) override; - virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) override - { - ASSERT_NOT_REACHED(); - return true; - } - -private: - RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; - SVGPathSegRole m_pathSegRole; -}; - -} - -#endif // ENABLE(SVG) -#endif // SVGListPropertyTearOff_h diff --git a/Source/WebCore/svg/properties/SVGProperty.h b/Source/WebCore/svg/properties/SVGProperty.h index 69394e3f5..b236cee04 100644 --- a/Source/WebCore/svg/properties/SVGProperty.h +++ b/Source/WebCore/svg/properties/SVGProperty.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGProperty_h -#define SVGProperty_h +#pragma once -#if ENABLE(SVG) #include <wtf/RefCounted.h> namespace WebCore { @@ -39,7 +37,4 @@ public: virtual void commitChange() = 0; }; -} - -#endif // ENABLE(SVG) -#endif // SVGProperty_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGPropertyInfo.cpp b/Source/WebCore/svg/properties/SVGPropertyInfo.cpp index 43063246c..45c862cd5 100644 --- a/Source/WebCore/svg/properties/SVGPropertyInfo.cpp +++ b/Source/WebCore/svg/properties/SVGPropertyInfo.cpp @@ -20,8 +20,6 @@ #include "config.h" #include "SVGPropertyInfo.h" -#if ENABLE(SVG) - namespace WebCore { SVGPropertyInfo::SVGPropertyInfo(AnimatedPropertyType newType, AnimatedPropertyState newState, const QualifiedName& newAttributeName, const AtomicString& newPropertyIdentifier, SynchronizeProperty newSynchronizeProperty, LookupOrCreateWrapperForAnimatedProperty newLookupOrCreateWrapperForAnimatedProperty) @@ -35,5 +33,3 @@ SVGPropertyInfo::SVGPropertyInfo(AnimatedPropertyType newType, AnimatedPropertyS } } // namespace - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/properties/SVGPropertyInfo.h b/Source/WebCore/svg/properties/SVGPropertyInfo.h index 54778ee9e..165f9b5b7 100644 --- a/Source/WebCore/svg/properties/SVGPropertyInfo.h +++ b/Source/WebCore/svg/properties/SVGPropertyInfo.h @@ -17,12 +17,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPropertyInfo_h -#define SVGPropertyInfo_h +#pragma once -#if ENABLE(SVG) #include "QualifiedName.h" -#include <wtf/PassRefPtr.h> namespace WebCore { @@ -59,7 +56,7 @@ struct SVGPropertyInfo { WTF_MAKE_FAST_ALLOCATED; public: typedef void (*SynchronizeProperty)(SVGElement*); - typedef PassRefPtr<SVGAnimatedProperty> (*LookupOrCreateWrapperForAnimatedProperty)(SVGElement*); + typedef Ref<SVGAnimatedProperty> (*LookupOrCreateWrapperForAnimatedProperty)(SVGElement*); SVGPropertyInfo(AnimatedPropertyType newType, AnimatedPropertyState newState, const QualifiedName& newAttributeName, const AtomicString& newPropertyIdentifier, SynchronizeProperty newSynchronizeProperty, @@ -73,7 +70,4 @@ public: LookupOrCreateWrapperForAnimatedProperty lookupOrCreateWrapperForAnimatedProperty; }; -} - -#endif // ENABLE(SVG) -#endif // SVGPropertyInfo_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGPropertyTearOff.h b/Source/WebCore/svg/properties/SVGPropertyTearOff.h index e0f09b3a7..46f693568 100644 --- a/Source/WebCore/svg/properties/SVGPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGPropertyTearOff.h @@ -1,5 +1,6 @@ /* * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2016 Apple Inc. 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 @@ -17,45 +18,57 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPropertyTearOff_h -#define SVGPropertyTearOff_h +#pragma once -#if ENABLE(SVG) +#include "ExceptionOr.h" #include "SVGAnimatedProperty.h" -#include "SVGElement.h" #include "SVGProperty.h" #include <wtf/WeakPtr.h> namespace WebCore { +class SVGElement; + class SVGPropertyTearOffBase : public SVGProperty { public: virtual void detachWrapper() = 0; }; -template<typename PropertyType> +template<typename T> class SVGPropertyTearOff : public SVGPropertyTearOffBase { public: - typedef SVGPropertyTearOff<PropertyType> Self; + using PropertyType = T; + using Self = SVGPropertyTearOff<PropertyType>; // Used for child types (baseVal/animVal) of a SVGAnimated* property (for example: SVGAnimatedLength::baseVal()). // Also used for list tear offs (for example: text.x.baseVal.getItem(0)). - static PassRefPtr<Self> create(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, PropertyType& value) + static Ref<Self> create(SVGAnimatedProperty& animatedProperty, SVGPropertyRole role, PropertyType& value) { - ASSERT(animatedProperty); - return adoptRef(new Self(animatedProperty, role, value)); + return adoptRef(*new Self(animatedProperty, role, value)); } // Used for non-animated POD types (for example: SVGSVGElement::createSVGLength()). - static PassRefPtr<Self> create(const PropertyType& initialValue) + static Ref<Self> create(const PropertyType& initialValue) { - return adoptRef(new Self(initialValue)); + return adoptRef(*new Self(initialValue)); } - PropertyType& propertyReference() { return *m_value; } - SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty; } + static Ref<Self> create(const PropertyType* initialValue) + { + return adoptRef(*new Self(initialValue)); + } - void setValue(PropertyType& value) + template<typename U> static ExceptionOr<Ref<Self>> create(ExceptionOr<U>&& initialValue) + { + if (initialValue.hasException()) + return initialValue.releaseException(); + return create(initialValue.releaseReturnValue()); + } + + virtual PropertyType& propertyReference() { return *m_value; } + SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty.get(); } + + virtual void setValue(PropertyType& value) { if (m_valueIsCopy) { detachChildren(); @@ -68,16 +81,13 @@ public: void setAnimatedProperty(SVGAnimatedProperty* animatedProperty) { m_animatedProperty = animatedProperty; - - if (m_animatedProperty) - m_contextElement = m_animatedProperty->contextElement(); } SVGElement* contextElement() const { if (!m_animatedProperty || m_valueIsCopy) - return 0; - return m_contextElement.get(); + return nullptr; + return m_animatedProperty->contextElement(); } void addChild(WeakPtr<SVGPropertyTearOffBase> child) @@ -85,7 +95,7 @@ public: m_childTearOffs.append(child); } - virtual void detachWrapper() override + void detachWrapper() override { if (m_valueIsCopy) return; @@ -101,17 +111,17 @@ public: // Whenever the XML DOM modifies the "x" attribute, all existing wrappers are detached, using this function. m_value = new PropertyType(*m_value); m_valueIsCopy = true; - m_animatedProperty = 0; + m_animatedProperty = nullptr; } - virtual void commitChange() override + void commitChange() override { if (!m_animatedProperty || m_valueIsCopy) return; m_animatedProperty->commitChange(); } - virtual bool isReadOnly() const override + bool isReadOnly() const override { if (m_role == AnimValRole) return true; @@ -127,17 +137,17 @@ protected: , m_value(&value) , m_valueIsCopy(false) { - // Using operator & is completely fine, as SVGAnimatedProperty owns this reference, - // and we're guaranteed to live as long as SVGAnimatedProperty does. - - if (m_animatedProperty) - m_contextElement = m_animatedProperty->contextElement(); } SVGPropertyTearOff(const PropertyType& initialValue) - : m_animatedProperty(0) + : SVGPropertyTearOff(&initialValue) + { + } + + SVGPropertyTearOff(const PropertyType* initialValue) + : m_animatedProperty(nullptr) , m_role(UndefinedRole) - , m_value(new PropertyType(initialValue)) + , m_value(initialValue ? new PropertyType(*initialValue) : nullptr) , m_valueIsCopy(true) { } @@ -148,6 +158,9 @@ protected: detachChildren(); delete m_value; } + + if (m_animatedProperty) + m_animatedProperty->propertyWillBeDeleted(*this); } void detachChildren() @@ -159,8 +172,7 @@ protected: m_childTearOffs.clear(); } - RefPtr<SVGElement> m_contextElement; - SVGAnimatedProperty* m_animatedProperty; + RefPtr<SVGAnimatedProperty> m_animatedProperty; SVGPropertyRole m_role; PropertyType* m_value; Vector<WeakPtr<SVGPropertyTearOffBase>> m_childTearOffs; @@ -168,6 +180,3 @@ protected: }; } - -#endif // ENABLE(SVG) -#endif // SVGPropertyTearOff_h diff --git a/Source/WebCore/svg/properties/SVGPropertyTraits.h b/Source/WebCore/svg/properties/SVGPropertyTraits.h index 3abb5a8a1..afdad958a 100644 --- a/Source/WebCore/svg/properties/SVGPropertyTraits.h +++ b/Source/WebCore/svg/properties/SVGPropertyTraits.h @@ -18,10 +18,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGPropertyTraits_h -#define SVGPropertyTraits_h +#pragma once -#if ENABLE(SVG) #include <wtf/text/WTFString.h> namespace WebCore { @@ -59,7 +57,10 @@ struct SVGPropertyTraits<String> { static String toString(const String& type) { return type; } }; -} +template<typename EnumType> +struct SVGIDLEnumLimits { + // Specialize this function for a particular enumeration to limit the values that are exposed through the DOM. + static unsigned highestExposedEnumValue() { return SVGPropertyTraits<EnumType>::highestEnumValue(); } +}; -#endif -#endif +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h index b0a85ddc5..786874dca 100644 --- a/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGStaticListPropertyTearOff.h @@ -17,101 +17,95 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGStaticListPropertyTearOff_h -#define SVGStaticListPropertyTearOff_h +#pragma once -#if ENABLE(SVG) #include "SVGListProperty.h" namespace WebCore { -template<typename PropertyType> +template<typename PropertyType> class SVGStaticListPropertyTearOff : public SVGListProperty<PropertyType> { public: - typedef SVGListProperty<PropertyType> Base; + using Self = SVGStaticListPropertyTearOff<PropertyType>; + using Base = SVGListProperty<PropertyType>; - typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; - typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; + using ListItemType = typename SVGPropertyTraits<PropertyType>::ListItemType; + using ListItemTearOff = typename SVGPropertyTraits<PropertyType>::ListItemTearOff; using Base::m_role; using Base::m_values; - static PassRefPtr<SVGStaticListPropertyTearOff<PropertyType>> create(SVGElement& contextElement, PropertyType& values) + static Ref<Self> create(SVGElement& contextElement, PropertyType& values) { - return adoptRef(new SVGStaticListPropertyTearOff<PropertyType>(&contextElement, values)); + return adoptRef(*new Self(contextElement, values)); } - // SVGList API - void clear(ExceptionCode& ec) + ExceptionOr<void> clear() { - Base::clearValues(ec); + return Base::clearValues(); } - ListItemType initialize(const ListItemType& newItem, ExceptionCode& ec) + ExceptionOr<ListItemType> initialize(const ListItemType& newItem) { - return Base::initializeValues(newItem, ec); + return Base::initializeValues(newItem); } - ListItemType getItem(unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> getItem(unsigned index) { - return Base::getItemValues(index, ec); + return Base::getItemValues(index); } - ListItemType insertItemBefore(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> insertItemBefore(const ListItemType& newItem, unsigned index) { - return Base::insertItemBeforeValues(newItem, index, ec); + return Base::insertItemBeforeValues(newItem, index); } - ListItemType replaceItem(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> replaceItem(const ListItemType& newItem, unsigned index) { - return Base::replaceItemValues(newItem, index, ec); + return Base::replaceItemValues(newItem, index); } - ListItemType removeItem(unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> removeItem(unsigned index) { - return Base::removeItemValues(index, ec); + return Base::removeItemValues(index); } - ListItemType appendItem(const ListItemType& newItem, ExceptionCode& ec) + ExceptionOr<ListItemType> appendItem(const ListItemType& newItem) { - return Base::appendItemValues(newItem, ec); + return Base::appendItemValues(newItem); } -private: +protected: SVGStaticListPropertyTearOff(SVGElement* contextElement, PropertyType& values) - : SVGListProperty<PropertyType>(UndefinedRole, values, 0) - , m_contextElement(contextElement) + : Base(UndefinedRole, values, nullptr) + , m_contextElement(*contextElement) { } - virtual bool isReadOnly() const + bool isReadOnly() const override { return m_role == AnimValRole; } - virtual void commitChange() + void commitChange() override { ASSERT(m_values); - m_values->commitChange(m_contextElement.get()); + m_values->commitChange(m_contextElement); } - virtual bool processIncomingListItemValue(const ListItemType&, unsigned*) + bool processIncomingListItemValue(const ListItemType&, unsigned*) override { // no-op for static lists return true; } - virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) + bool processIncomingListItemWrapper(Ref<ListItemTearOff>&, unsigned*) override { ASSERT_NOT_REACHED(); return true; } -private: - RefPtr<SVGElement> m_contextElement; + Ref<SVGElement> m_contextElement; }; } - -#endif // ENABLE(SVG) -#endif // SVGStaticListPropertyTearOff_h diff --git a/Source/WebCore/svg/properties/SVGStaticPropertyTearOff.h b/Source/WebCore/svg/properties/SVGStaticPropertyTearOff.h index 962c1679d..5e2ca09a0 100644 --- a/Source/WebCore/svg/properties/SVGStaticPropertyTearOff.h +++ b/Source/WebCore/svg/properties/SVGStaticPropertyTearOff.h @@ -17,11 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGStaticPropertyTearOff_h -#define SVGStaticPropertyTearOff_h - -#if ENABLE(SVG) -#include "SVGPropertyTearOff.h" +#pragma once namespace WebCore { @@ -30,26 +26,28 @@ namespace WebCore { // alignment warning (C4121). 16 is the next-largest size allowed for packing, so we use that. #pragma pack(push, 16) #endif -template<typename ContextElement, typename PropertyType> -class SVGStaticPropertyTearOff : public SVGPropertyTearOff<PropertyType> { +template<typename ContextElement, typename PropertyTearOff> +class SVGStaticPropertyTearOff final : public PropertyTearOff { public: - typedef SVGStaticPropertyTearOff<ContextElement, PropertyType> Self; + using Self = SVGStaticPropertyTearOff<ContextElement, PropertyTearOff>; + using PropertyType = typename PropertyTearOff::PropertyType; + typedef void (ContextElement::*UpdateMethod)(); // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute // (for example: SVGSVGElement::currentTranslate). - static PassRefPtr<Self> create(ContextElement& contextElement, PropertyType& value, UpdateMethod update) + static Ref<Self> create(ContextElement& contextElement, PropertyType& value, UpdateMethod update) { - return adoptRef(new Self(&contextElement, value, update)); + return adoptRef(*new Self(contextElement, value, update)); } - virtual void commitChange() { (m_contextElement.get()->*m_update)(); } + void commitChange() final { (m_contextElement.get()->*m_update)(); } private: - SVGStaticPropertyTearOff(ContextElement* contextElement, PropertyType& value, UpdateMethod update) - : SVGPropertyTearOff<PropertyType>(0, UndefinedRole, value) + SVGStaticPropertyTearOff(ContextElement& contextElement, PropertyType& value, UpdateMethod update) + : PropertyTearOff(UndefinedRole, value) , m_update(update) - , m_contextElement(contextElement) + , m_contextElement(&contextElement) { } @@ -60,7 +58,4 @@ private: #pragma pack(pop) #endif -} - -#endif // ENABLE(SVG) -#endif // SVGStaticPropertyTearOff_h +} // namespace WebCore diff --git a/Source/WebCore/svg/properties/SVGTransformListPropertyTearOff.h b/Source/WebCore/svg/properties/SVGTransformListPropertyTearOff.h deleted file mode 100644 index 7fc183b59..000000000 --- a/Source/WebCore/svg/properties/SVGTransformListPropertyTearOff.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 SVGTransformListPropertyTearOff_h -#define SVGTransformListPropertyTearOff_h - -#if ENABLE(SVG) -#include "SVGListPropertyTearOff.h" -#include "SVGTransformList.h" - -namespace WebCore { - -// SVGTransformList contains two additional methods, that can be exposed to the bindings. -class SVGTransformListPropertyTearOff : public SVGListPropertyTearOff<SVGTransformList> { -public: - typedef SVGAnimatedListPropertyTearOff<SVGTransformList> AnimatedListPropertyTearOff; - typedef SVGAnimatedListPropertyTearOff<SVGTransformList>::ListWrapperCache ListWrapperCache; - - static PassRefPtr<SVGListPropertyTearOff<SVGTransformList>> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGTransformList& values, ListWrapperCache& wrappers) - { - ASSERT(animatedProperty); - return adoptRef(new SVGTransformListPropertyTearOff(animatedProperty, role, values, wrappers)); - } - - PassRefPtr<SVGPropertyTearOff<SVGTransform>> createSVGTransformFromMatrix(SVGPropertyTearOff<SVGMatrix>* matrix, ExceptionCode& ec) - { - ASSERT(m_values); - if (!matrix) { - ec = TYPE_MISMATCH_ERR; - return 0; - } - return SVGPropertyTearOff<SVGTransform>::create(m_values->createSVGTransformFromMatrix(matrix->propertyReference())); - } - - PassRefPtr<SVGPropertyTearOff<SVGTransform>> consolidate(ExceptionCode& ec) - { - ASSERT(m_values); - ASSERT(m_wrappers); - if (!canAlterList(ec)) - return 0; - - ASSERT(m_values->size() == m_wrappers->size()); - - // Spec: If the list was empty, then a value of null is returned. - if (m_values->isEmpty()) - return 0; - - detachListWrappers(0); - RefPtr<SVGPropertyTearOff<SVGTransform>> wrapper = SVGPropertyTearOff<SVGTransform>::create(m_values->consolidate()); - m_wrappers->append(wrapper); - - ASSERT(m_values->size() == m_wrappers->size()); - return wrapper.release(); - } - -private: - SVGTransformListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGTransformList& values, ListWrapperCache& wrappers) - : SVGListPropertyTearOff<SVGTransformList>(animatedProperty, role, values, wrappers) - { - } -}; - -} - -#endif // ENABLE(SVG) -#endif // SVGListPropertyTearOff_h diff --git a/Source/WebCore/svg/svgattrs.in b/Source/WebCore/svg/svgattrs.in index 24fc5f9a9..c7561c2b5 100644 --- a/Source/WebCore/svg/svgattrs.in +++ b/Source/WebCore/svg/svgattrs.in @@ -1,6 +1,5 @@ namespace="SVG" namespaceURI="http://www.w3.org/2000/svg" -guardFactoryWith="ENABLE(SVG)" attrsNullNamespace accent-height @@ -129,12 +128,8 @@ mode name numOctaves offset -onactivate onbegin onend -onfocusin -onfocusout -onrepeat onzoom opacity operator @@ -145,6 +140,7 @@ origin overflow overline-position overline-thickness +paint-order panose-1 path pathLength diff --git a/Source/WebCore/svg/svgtags.in b/Source/WebCore/svg/svgtags.in index 7a6886047..6c3c04d86 100644 --- a/Source/WebCore/svg/svgtags.in +++ b/Source/WebCore/svg/svgtags.in @@ -1,30 +1,28 @@ namespace="SVG" namespaceURI="http://www.w3.org/2000/svg" -guardFactoryWith="ENABLE(SVG)" fallbackInterfaceName="SVGUnknownElement" fallbackJSInterfaceName="SVGElement" a #if ENABLE_SVG_FONTS -altGlyph generateTypeHelpers -altGlyphDef generateTypeHelpers -altGlyphItem generateTypeHelpers +altGlyph +altGlyphDef +altGlyphItem #endif animate animateColor -animateMotion generateTypeHelpers -animateTransform generateTypeHelpers +animateMotion +animateTransform set -circle generateTypeHelpers -clipPath generateTypeHelpers +circle +clipPath #if 0 color_profile #endif -cursor generateTypeHelpers +cursor defs desc -ellipse generateTypeHelpers -#if ENABLE_FILTERS +ellipse feBlend feColorMatrix feComponentTransfer @@ -32,70 +30,69 @@ feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap -feDistantLight generateTypeHelpers +feDistantLight feDropShadow feFlood -feFuncA generateTypeHelpers -feFuncB generateTypeHelpers -feFuncG generateTypeHelpers -feFuncR generateTypeHelpers +feFuncA +feFuncB +feFuncG +feFuncR feGaussianBlur feImage feMerge -feMergeNode generateTypeHelpers +feMergeNode feMorphology feOffset -fePointLight generateTypeHelpers +fePointLight feSpecularLighting -feSpotLight generateTypeHelpers +feSpotLight feTile feTurbulence -filter generateTypeHelpers -#endif +filter #if ENABLE_SVG_FONTS -font generateTypeHelpers -font_face generateTypeHelpers +font +font_face font_face_format -font_face_name generateTypeHelpers -font_face_src generateTypeHelpers -font_face_uri generateTypeHelpers +font_face_name +font_face_src +font_face_uri #endif -foreignObject generateTypeHelpers -g generateTypeHelpers +foreignObject +g #if ENABLE_SVG_FONTS -glyph generateTypeHelpers -glyphRef generateTypeHelpers -hkern interfaceName=SVGHKernElement, generateTypeHelpers +glyph +glyphRef +hkern interfaceName=SVGHKernElement #endif -image generateTypeHelpers -line generateTypeHelpers -linearGradient generateTypeHelpers -marker generateTypeHelpers -mask generateTypeHelpers +image +line +linearGradient +marker +mask metadata #if ENABLE_SVG_FONTS -missing_glyph generateTypeHelpers +missing_glyph #endif -mpath interfaceName=SVGMPathElement, generateTypeHelpers -path generateTypeHelpers -pattern generateTypeHelpers -polygon generateTypeHelpers -polyline generateTypeHelpers -radialGradient generateTypeHelpers -rect generateTypeHelpers -script constructorNeedsCreatedByParser, generateTypeHelpers -stop generateTypeHelpers -style constructorNeedsCreatedByParser, generateTypeHelpers -svg interfaceName=SVGSVGElement, generateTypeHelpers +mpath interfaceName=SVGMPathElement +path +pattern +polygon +polyline +radialGradient +rect +script constructorNeedsCreatedByParser +stop +style constructorNeedsCreatedByParser +svg interfaceName=SVGSVGElement switch symbol -text generateTypeHelpers -textPath generateTypeHelpers -title generateTypeHelpers +text +textPath +title tref interfaceName=SVGTRefElement tspan interfaceName=SVGTSpanElement -use constructorNeedsCreatedByParser, generateTypeHelpers -view generateTypeHelpers +use +view #if ENABLE_SVG_FONTS -vkern interfaceName=SVGVKernElement, generateTypeHelpers +vkern interfaceName=SVGVKernElement #endif |