Home | History | Annotate | Download | only in svg
      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