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