1/*
2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4 * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#pragma once
23
24#include "RenderSVGResourceFilter.h"
25#include "RenderSVGResourceFilterPrimitive.h"
26#include "SVGElement.h"
27#include "SVGNames.h"
28#include <wtf/RefPtr.h>
29
30namespace WebCore {
31
32class Filter;
33class FilterEffect;
34class SVGFilterBuilder;
35
36class SVGFilterPrimitiveStandardAttributes : public SVGElement {
37 WTF_MAKE_ISO_ALLOCATED(SVGFilterPrimitiveStandardAttributes);
38public:
39 void setStandardAttributes(FilterEffect*) const;
40
41 virtual RefPtr<FilterEffect> build(SVGFilterBuilder*, Filter&) const = 0;
42 // Returns true, if the new value is different from the old one.
43 virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
44
45 using PropertyRegistry = SVGPropertyOwnerRegistry<SVGFilterPrimitiveStandardAttributes, SVGElement>;
46
47 const SVGLengthValue& x() const { return m_x->currentValue(); }
48 const SVGLengthValue& y() const { return m_y->currentValue(); }
49 const SVGLengthValue& width() const { return m_width->currentValue(); }
50 const SVGLengthValue& height() const { return m_height->currentValue(); }
51 String result() const { return m_result->currentValue(); }
52
53 SVGAnimatedLength& xAnimated() { return m_x; }
54 SVGAnimatedLength& yAnimated() { return m_y; }
55 SVGAnimatedLength& widthAnimated() { return m_width; }
56 SVGAnimatedLength& heightAnimated() { return m_height; }
57 SVGAnimatedString& resultAnimated() { return m_result; }
58
59protected:
60 SVGFilterPrimitiveStandardAttributes(const QualifiedName&, Document&);
61
62 void parseAttribute(const QualifiedName&, const AtomicString&) override;
63 void svgAttributeChanged(const QualifiedName&) override;
64 void childrenChanged(const ChildChange&) override;
65
66 void invalidate();
67 void primitiveAttributeChanged(const QualifiedName& attributeName);
68
69private:
70 bool isFilterEffect() const override { return true; }
71
72 RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
73 bool rendererIsNeeded(const RenderStyle&) override;
74 bool childShouldCreateRenderer(const Node&) const override { return false; }
75
76 // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified.
77 // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
78 Ref<SVGAnimatedLength> m_x { SVGAnimatedLength::create(this, LengthModeWidth, "0%") };
79 Ref<SVGAnimatedLength> m_y { SVGAnimatedLength::create(this, LengthModeHeight, "0%") };
80 Ref<SVGAnimatedLength> m_width { SVGAnimatedLength::create(this, LengthModeWidth, "100%") };
81 Ref<SVGAnimatedLength> m_height { SVGAnimatedLength::create(this, LengthModeHeight, "100%") };
82 Ref<SVGAnimatedString> m_result { SVGAnimatedString::create(this) };
83};
84
85void invalidateFilterPrimitiveParent(SVGElement*);
86
87inline void SVGFilterPrimitiveStandardAttributes::invalidate()
88{
89 if (auto* primitiveRenderer = renderer())
90 RenderSVGResource::markForLayoutAndParentResourceInvalidation(*primitiveRenderer);
91}
92
93inline void SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged(const QualifiedName& attribute)
94{
95 if (auto* primitiveRenderer = renderer())
96 static_cast<RenderSVGResourceFilterPrimitive*>(primitiveRenderer)->primitiveAttributeChanged(attribute);
97}
98
99} // namespace WebCore
100
101SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGFilterPrimitiveStandardAttributes)
102 static bool isType(const WebCore::SVGElement& element) { return element.isFilterEffect(); }
103 static bool isType(const WebCore::Node& node) { return is<WebCore::SVGElement>(node) && isType(downcast<WebCore::SVGElement>(node)); }
104SPECIALIZE_TYPE_TRAITS_END()
105