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