Use #pragma once in WebCore
[WebKit-https.git] / Source / WebCore / svg / SVGFilterPrimitiveStandardAttributes.cpp
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) 2009 Dirk Schulze <krit@webkit.org>
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 #include "config.h"
23 #include "SVGFilterPrimitiveStandardAttributes.h"
24
25 #include "FilterEffect.h"
26 #include "RenderSVGResourceFilterPrimitive.h"
27 #include "SVGElement.h"
28 #include "SVGFilterBuilder.h"
29 #include "SVGLength.h"
30 #include "SVGNames.h"
31 #include "SVGUnitTypes.h"
32 #include <wtf/NeverDestroyed.h>
33
34 namespace WebCore {
35
36 // Animated property definitions
37 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::xAttr, X, x)
38 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::yAttr, Y, y)
39 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::widthAttr, Width, width)
40 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::heightAttr, Height, height)
41 DEFINE_ANIMATED_STRING(SVGFilterPrimitiveStandardAttributes, SVGNames::resultAttr, Result, result)
42
43 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
44     REGISTER_LOCAL_ANIMATED_PROPERTY(x)
45     REGISTER_LOCAL_ANIMATED_PROPERTY(y)
46     REGISTER_LOCAL_ANIMATED_PROPERTY(width)
47     REGISTER_LOCAL_ANIMATED_PROPERTY(height)
48     REGISTER_LOCAL_ANIMATED_PROPERTY(result)
49     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
50 END_REGISTER_ANIMATED_PROPERTIES
51
52 SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document& document)
53     : SVGElement(tagName, document)
54     , m_x(LengthModeWidth, "0%")
55     , m_y(LengthModeHeight, "0%")
56     , m_width(LengthModeWidth, "100%")
57     , m_height(LengthModeHeight, "100%")
58 {
59     // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified.
60     // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
61     registerAnimatedPropertiesForSVGFilterPrimitiveStandardAttributes();
62 }
63
64 bool SVGFilterPrimitiveStandardAttributes::isSupportedAttribute(const QualifiedName& attrName)
65 {
66     static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
67     if (supportedAttributes.get().isEmpty()) {
68         supportedAttributes.get().add(SVGNames::xAttr);
69         supportedAttributes.get().add(SVGNames::yAttr);
70         supportedAttributes.get().add(SVGNames::widthAttr);
71         supportedAttributes.get().add(SVGNames::heightAttr);
72         supportedAttributes.get().add(SVGNames::resultAttr);
73     }
74     return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
75 }
76
77 void SVGFilterPrimitiveStandardAttributes::parseAttribute(const QualifiedName& name, const AtomicString& value)
78 {
79     SVGParsingError parseError = NoError;
80
81     if (name == SVGNames::xAttr)
82         setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
83     else if (name == SVGNames::yAttr)
84         setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
85     else if (name == SVGNames::widthAttr)
86         setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
87     else if (name == SVGNames::heightAttr)
88         setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
89     else if (name == SVGNames::resultAttr)
90         setResultBaseValue(value);
91
92     reportAttributeParsingError(parseError, name, value);
93
94     SVGElement::parseAttribute(name, value);
95 }
96
97 bool SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect*, const QualifiedName&)
98 {
99     // When all filters support this method, it will be changed to a pure virtual method.
100     ASSERT_NOT_REACHED();
101     return false;
102 }
103
104 void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedName& attrName)
105 {
106     if (!isSupportedAttribute(attrName)) {
107         SVGElement::svgAttributeChanged(attrName);
108         return;
109     }
110
111     InstanceInvalidationGuard guard(*this);
112     invalidate();
113 }
114
115 void SVGFilterPrimitiveStandardAttributes::childrenChanged(const ChildChange& change)
116 {
117     SVGElement::childrenChanged(change);
118
119     if (change.source == ChildChangeSourceParser)
120         return;
121     invalidate();
122 }
123
124 void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(FilterEffect* filterEffect) const
125 {
126     ASSERT(filterEffect);
127     if (!filterEffect)
128         return;
129
130     if (hasAttribute(SVGNames::xAttr))
131         filterEffect->setHasX(true);
132     if (hasAttribute(SVGNames::yAttr))
133         filterEffect->setHasY(true);
134     if (hasAttribute(SVGNames::widthAttr))
135         filterEffect->setHasWidth(true);
136     if (hasAttribute(SVGNames::heightAttr))
137         filterEffect->setHasHeight(true);
138 }
139
140 RenderPtr<RenderElement> SVGFilterPrimitiveStandardAttributes::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
141 {
142     return createRenderer<RenderSVGResourceFilterPrimitive>(*this, WTFMove(style));
143 }
144
145 bool SVGFilterPrimitiveStandardAttributes::rendererIsNeeded(const RenderStyle& style)
146 {
147     if (parentNode() && (parentNode()->hasTagName(SVGNames::filterTag)))
148         return SVGElement::rendererIsNeeded(style);
149
150     return false;
151 }
152
153 void invalidateFilterPrimitiveParent(SVGElement* element)
154 {
155     if (!element)
156         return;
157
158     ContainerNode* parent = element->parentNode();
159
160     if (!parent)
161         return;
162
163     RenderElement* renderer = parent->renderer();
164     if (!renderer || !renderer->isSVGResourceFilterPrimitive())
165         return;
166
167     RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer, false);
168 }
169
170 }