Move InstanceInvalidationGuard/UpdateBlocker to SVGElement from SVGElementInstance
[WebKit-https.git] / Source / WebCore / svg / SVGFELightElement.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4  * Copyright (C) 2005 Oliver Hunt <oliver@nerget.com>
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 "SVGFELightElement.h"
24
25 #include "Attribute.h"
26 #include "ElementIterator.h"
27 #include "RenderObject.h"
28 #include "RenderSVGResource.h"
29 #include "SVGElementInstance.h"
30 #include "SVGFEDiffuseLightingElement.h"
31 #include "SVGFESpecularLightingElement.h"
32 #include "SVGFilterElement.h"
33 #include "SVGFilterPrimitiveStandardAttributes.h"
34 #include "SVGNames.h"
35 #include <wtf/NeverDestroyed.h>
36
37 namespace WebCore {
38
39 // Animated property definitions
40 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::azimuthAttr, Azimuth, azimuth)
41 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::elevationAttr, Elevation, elevation)
42 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::xAttr, X, x)
43 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::yAttr, Y, y)
44 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::zAttr, Z, z)
45 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtXAttr, PointsAtX, pointsAtX)
46 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtYAttr, PointsAtY, pointsAtY)
47 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtZAttr, PointsAtZ, pointsAtZ)
48 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::specularExponentAttr, SpecularExponent, specularExponent)
49 DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::limitingConeAngleAttr, LimitingConeAngle, limitingConeAngle)
50
51 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFELightElement)
52     REGISTER_LOCAL_ANIMATED_PROPERTY(azimuth)
53     REGISTER_LOCAL_ANIMATED_PROPERTY(elevation)
54     REGISTER_LOCAL_ANIMATED_PROPERTY(x)
55     REGISTER_LOCAL_ANIMATED_PROPERTY(y)
56     REGISTER_LOCAL_ANIMATED_PROPERTY(z)
57     REGISTER_LOCAL_ANIMATED_PROPERTY(pointsAtX)
58     REGISTER_LOCAL_ANIMATED_PROPERTY(pointsAtY)
59     REGISTER_LOCAL_ANIMATED_PROPERTY(pointsAtZ)
60     REGISTER_LOCAL_ANIMATED_PROPERTY(specularExponent)
61     REGISTER_LOCAL_ANIMATED_PROPERTY(limitingConeAngle)
62 END_REGISTER_ANIMATED_PROPERTIES
63
64 SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document& document)
65     : SVGElement(tagName, document)
66     , m_specularExponent(1)
67 {
68     registerAnimatedPropertiesForSVGFELightElement();
69 }
70
71 SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement* svgElement)
72 {
73     for (auto& child : childrenOfType<SVGElement>(*svgElement)) {
74         if (is<SVGFEDistantLightElement>(child) || is<SVGFEPointLightElement>(child) || is<SVGFESpotLightElement>(child))
75             return static_cast<SVGFELightElement*>(const_cast<SVGElement*>(&child));
76     }
77     return nullptr;
78 }
79
80 PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement)
81 {
82     SVGFELightElement* lightNode = findLightElement(svgElement);
83     if (!lightNode)
84         return 0;
85     return lightNode->lightSource();
86 }
87
88 bool SVGFELightElement::isSupportedAttribute(const QualifiedName& attrName)
89 {
90     static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
91     if (supportedAttributes.get().isEmpty()) {
92         supportedAttributes.get().add(SVGNames::azimuthAttr);
93         supportedAttributes.get().add(SVGNames::elevationAttr);
94         supportedAttributes.get().add(SVGNames::xAttr);
95         supportedAttributes.get().add(SVGNames::yAttr);
96         supportedAttributes.get().add(SVGNames::zAttr);
97         supportedAttributes.get().add(SVGNames::pointsAtXAttr);
98         supportedAttributes.get().add(SVGNames::pointsAtYAttr);
99         supportedAttributes.get().add(SVGNames::pointsAtZAttr);
100         supportedAttributes.get().add(SVGNames::specularExponentAttr);
101         supportedAttributes.get().add(SVGNames::limitingConeAngleAttr);
102     }
103     return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
104 }
105
106 void SVGFELightElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
107 {
108     if (!isSupportedAttribute(name)) {
109         SVGElement::parseAttribute(name, value);
110         return;
111     }
112
113     if (name == SVGNames::azimuthAttr) {
114         setAzimuthBaseValue(value.toFloat());
115         return;
116     }
117
118     if (name == SVGNames::elevationAttr) {
119         setElevationBaseValue(value.toFloat());
120         return;
121     }
122
123     if (name == SVGNames::xAttr) {
124         setXBaseValue(value.toFloat());
125         return;
126     }
127
128     if (name == SVGNames::yAttr) {
129         setYBaseValue(value.toFloat());
130         return;
131     }
132
133     if (name == SVGNames::zAttr) {
134         setZBaseValue(value.toFloat());
135         return;
136     }
137
138     if (name == SVGNames::pointsAtXAttr) {
139         setPointsAtXBaseValue(value.toFloat());
140         return;
141     }
142
143     if (name == SVGNames::pointsAtYAttr) {
144         setPointsAtYBaseValue(value.toFloat());
145         return;
146     }
147
148     if (name == SVGNames::pointsAtZAttr) {
149         setPointsAtZBaseValue(value.toFloat());
150         return;
151     }
152
153     if (name == SVGNames::specularExponentAttr) {
154         setSpecularExponentBaseValue(value.toFloat());
155         return;
156     }
157
158     if (name == SVGNames::limitingConeAngleAttr) {
159         setLimitingConeAngleBaseValue(value.toFloat());
160         return;
161     }
162
163     ASSERT_NOT_REACHED();
164 }
165
166 void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
167 {
168     if (!isSupportedAttribute(attrName)) {
169         SVGElement::svgAttributeChanged(attrName);
170         return;
171     }
172
173     InstanceInvalidationGuard guard(*this);
174     
175     if (attrName == SVGNames::azimuthAttr
176         || attrName == SVGNames::elevationAttr
177         || attrName == SVGNames::xAttr
178         || attrName == SVGNames::yAttr
179         || attrName == SVGNames::zAttr
180         || attrName == SVGNames::pointsAtXAttr
181         || attrName == SVGNames::pointsAtYAttr
182         || attrName == SVGNames::pointsAtZAttr
183         || attrName == SVGNames::specularExponentAttr
184         || attrName == SVGNames::limitingConeAngleAttr) {
185         ContainerNode* parent = parentNode();
186         if (!parent)
187             return;
188
189         RenderObject* renderer = parent->renderer();
190         if (!renderer || !renderer->isSVGResourceFilterPrimitive())
191             return;
192
193         if (parent->hasTagName(SVGNames::feDiffuseLightingTag)) {
194             SVGFEDiffuseLightingElement* diffuseLighting = static_cast<SVGFEDiffuseLightingElement*>(parent);
195             diffuseLighting->lightElementAttributeChanged(this, attrName);
196             return;
197         } else if (parent->hasTagName(SVGNames::feSpecularLightingTag)) {
198             SVGFESpecularLightingElement* specularLighting = static_cast<SVGFESpecularLightingElement*>(parent);
199             specularLighting->lightElementAttributeChanged(this, attrName);
200             return;
201         }
202     }
203
204     ASSERT_NOT_REACHED();
205 }
206
207 void SVGFELightElement::childrenChanged(const ChildChange& change)
208 {
209     SVGElement::childrenChanged(change);
210
211     if (change.source == ChildChangeSourceParser)
212         return;
213     ContainerNode* parent = parentNode();
214     if (!parent)
215         return;
216     RenderElement* renderer = parent->renderer();
217     if (renderer && renderer->isSVGResourceFilterPrimitive())
218         RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
219 }
220
221 }