1 /* 2 * Copyright (C) 2005 Oliver Hunt <ojh16 (at) student.canterbury.ac.nz> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20 #include "config.h" 21 22 #if ENABLE(SVG) && ENABLE(FILTERS) 23 #include "SVGFEDiffuseLightingElement.h" 24 25 #include "Attr.h" 26 #include "FEDiffuseLighting.h" 27 #include "FilterEffect.h" 28 #include "RenderStyle.h" 29 #include "SVGColor.h" 30 #include "SVGFELightElement.h" 31 #include "SVGFilterBuilder.h" 32 #include "SVGNames.h" 33 #include "SVGParserUtilities.h" 34 35 namespace WebCore { 36 37 // Animated property definitions 38 DEFINE_ANIMATED_STRING(SVGFEDiffuseLightingElement, SVGNames::inAttr, In1, in1) 39 DEFINE_ANIMATED_NUMBER(SVGFEDiffuseLightingElement, SVGNames::diffuseConstantAttr, DiffuseConstant, diffuseConstant) 40 DEFINE_ANIMATED_NUMBER(SVGFEDiffuseLightingElement, SVGNames::surfaceScaleAttr, SurfaceScale, surfaceScale) 41 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), KernelUnitLengthX, kernelUnitLengthX) 42 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), KernelUnitLengthY, kernelUnitLengthY) 43 44 inline SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(const QualifiedName& tagName, Document* document) 45 : SVGFilterPrimitiveStandardAttributes(tagName, document) 46 , m_diffuseConstant(1) 47 , m_surfaceScale(1) 48 { 49 } 50 51 PassRefPtr<SVGFEDiffuseLightingElement> SVGFEDiffuseLightingElement::create(const QualifiedName& tagName, Document* document) 52 { 53 return adoptRef(new SVGFEDiffuseLightingElement(tagName, document)); 54 } 55 56 const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthXIdentifier() 57 { 58 DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX")); 59 return s_identifier; 60 } 61 62 const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier() 63 { 64 DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY")); 65 return s_identifier; 66 } 67 68 void SVGFEDiffuseLightingElement::parseMappedAttribute(Attribute* attr) 69 { 70 const String& value = attr->value(); 71 if (attr->name() == SVGNames::inAttr) 72 setIn1BaseValue(value); 73 else if (attr->name() == SVGNames::surfaceScaleAttr) 74 setSurfaceScaleBaseValue(value.toFloat()); 75 else if (attr->name() == SVGNames::diffuseConstantAttr) 76 setDiffuseConstantBaseValue(value.toFloat()); 77 else if (attr->name() == SVGNames::kernelUnitLengthAttr) { 78 float x, y; 79 if (parseNumberOptionalNumber(value, x, y)) { 80 setKernelUnitLengthXBaseValue(x); 81 setKernelUnitLengthYBaseValue(y); 82 } 83 } else 84 SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); 85 } 86 87 bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) 88 { 89 FEDiffuseLighting* diffuseLighting = static_cast<FEDiffuseLighting*>(effect); 90 91 if (attrName == SVGNames::lighting_colorAttr) { 92 RenderObject* renderer = this->renderer(); 93 ASSERT(renderer); 94 ASSERT(renderer->style()); 95 return diffuseLighting->setLightingColor(renderer->style()->svgStyle()->lightingColor()); 96 } 97 if (attrName == SVGNames::surfaceScaleAttr) 98 return diffuseLighting->setSurfaceScale(surfaceScale()); 99 if (attrName == SVGNames::diffuseConstantAttr) 100 return diffuseLighting->setDiffuseConstant(diffuseConstant()); 101 102 LightSource* lightSource = const_cast<LightSource*>(diffuseLighting->lightSource()); 103 const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this); 104 ASSERT(lightSource); 105 ASSERT(lightElement); 106 107 if (attrName == SVGNames::azimuthAttr) 108 return lightSource->setAzimuth(lightElement->azimuth()); 109 if (attrName == SVGNames::elevationAttr) 110 return lightSource->setElevation(lightElement->elevation()); 111 if (attrName == SVGNames::xAttr) 112 return lightSource->setX(lightElement->x()); 113 if (attrName == SVGNames::yAttr) 114 return lightSource->setY(lightElement->y()); 115 if (attrName == SVGNames::zAttr) 116 return lightSource->setZ(lightElement->z()); 117 if (attrName == SVGNames::pointsAtXAttr) 118 return lightSource->setPointsAtX(lightElement->pointsAtX()); 119 if (attrName == SVGNames::pointsAtYAttr) 120 return lightSource->setPointsAtY(lightElement->pointsAtY()); 121 if (attrName == SVGNames::pointsAtZAttr) 122 return lightSource->setPointsAtZ(lightElement->pointsAtZ()); 123 if (attrName == SVGNames::specularExponentAttr) 124 return lightSource->setSpecularExponent(lightElement->specularExponent()); 125 if (attrName == SVGNames::limitingConeAngleAttr) 126 return lightSource->setLimitingConeAngle(lightElement->limitingConeAngle()); 127 128 ASSERT_NOT_REACHED(); 129 return false; 130 } 131 132 void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrName) 133 { 134 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); 135 136 if (attrName == SVGNames::surfaceScaleAttr 137 || attrName == SVGNames::diffuseConstantAttr 138 || attrName == SVGNames::kernelUnitLengthAttr 139 || attrName == SVGNames::lighting_colorAttr) 140 primitiveAttributeChanged(attrName); 141 142 if (attrName == SVGNames::inAttr) 143 invalidate(); 144 } 145 146 void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName) 147 { 148 if (SVGFELightElement::findLightElement(this) != lightElement) 149 return; 150 151 // The light element has different attribute names. 152 primitiveAttributeChanged(attrName); 153 } 154 155 void SVGFEDiffuseLightingElement::synchronizeProperty(const QualifiedName& attrName) 156 { 157 SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); 158 159 if (attrName == anyQName()) { 160 synchronizeIn1(); 161 synchronizeSurfaceScale(); 162 synchronizeDiffuseConstant(); 163 synchronizeKernelUnitLengthX(); 164 synchronizeKernelUnitLengthY(); 165 return; 166 } 167 168 if (attrName == SVGNames::inAttr) 169 synchronizeIn1(); 170 else if (attrName == SVGNames::surfaceScaleAttr) 171 synchronizeSurfaceScale(); 172 else if (attrName == SVGNames::diffuseConstantAttr) 173 synchronizeDiffuseConstant(); 174 else if (attrName == SVGNames::kernelUnitLengthAttr) { 175 synchronizeKernelUnitLengthX(); 176 synchronizeKernelUnitLengthY(); 177 } 178 } 179 180 AttributeToPropertyTypeMap& SVGFEDiffuseLightingElement::attributeToPropertyTypeMap() 181 { 182 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 183 return s_attributeToPropertyTypeMap; 184 } 185 186 void SVGFEDiffuseLightingElement::fillAttributeToPropertyTypeMap() 187 { 188 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap(); 189 190 SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap); 191 attributeToPropertyTypeMap.set(SVGNames::inAttr, AnimatedString); 192 attributeToPropertyTypeMap.set(SVGNames::diffuseConstantAttr, AnimatedNumber); 193 attributeToPropertyTypeMap.set(SVGNames::surfaceScaleAttr, AnimatedNumber); 194 attributeToPropertyTypeMap.set(SVGNames::kernelUnitLengthAttr, AnimatedNumberOptionalNumber); 195 } 196 197 PassRefPtr<FilterEffect> SVGFEDiffuseLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) 198 { 199 FilterEffect* input1 = filterBuilder->getEffectById(in1()); 200 201 if (!input1) 202 return 0; 203 204 RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this); 205 if (!lightSource) 206 return 0; 207 208 RefPtr<RenderStyle> filterStyle = styleForRenderer(); 209 Color color = filterStyle->svgStyle()->lightingColor(); 210 211 RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(), 212 kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release()); 213 effect->inputEffects().append(input1); 214 return effect.release(); 215 } 216 217 } 218 219 #endif // ENABLE(SVG) 220