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