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 33namespace WebCore { 34 35// Animated property definitions 36DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::azimuthAttr, Azimuth, azimuth) 37DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::elevationAttr, Elevation, elevation) 38DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::xAttr, X, x) 39DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::yAttr, Y, y) 40DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::zAttr, Z, z) 41DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtXAttr, PointsAtX, pointsAtX) 42DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtYAttr, PointsAtY, pointsAtY) 43DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtZAttr, PointsAtZ, pointsAtZ) 44DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::specularExponentAttr, SpecularExponent, specularExponent) 45DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::limitingConeAngleAttr, LimitingConeAngle, limitingConeAngle) 46 47BEGIN_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) 58END_REGISTER_ANIMATED_PROPERTIES 59 60SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document& document) 61 : SVGElement(tagName, document) 62 , m_specularExponent(1) 63{ 64 registerAnimatedPropertiesForSVGFELightElement(); 65} 66 67SVGFELightElement* 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 79PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement) 80{ 81 SVGFELightElement* lightNode = findLightElement(svgElement); 82 if (!lightNode) 83 return 0; 84 return lightNode->lightSource(); 85} 86 87bool 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 105void 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 165void 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 204void 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