Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis (at) kde.org>
      4  * Copyright (C) 2005 Oliver Hunt <oliver (at) 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(SVG) && ENABLE(FILTERS)
     25 #include "SVGFESpecularLightingElement.h"
     26 
     27 #include "Attribute.h"
     28 #include "FilterEffect.h"
     29 #include "RenderStyle.h"
     30 #include "SVGColor.h"
     31 #include "SVGFELightElement.h"
     32 #include "SVGFilterBuilder.h"
     33 #include "SVGNames.h"
     34 #include "SVGParserUtilities.h"
     35 
     36 namespace WebCore {
     37 
     38 // Animated property definitions
     39 DEFINE_ANIMATED_STRING(SVGFESpecularLightingElement, SVGNames::inAttr, In1, in1)
     40 DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::specularConstantAttr, SpecularConstant, specularConstant)
     41 DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::specularExponentAttr, SpecularExponent, specularExponent)
     42 DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::surfaceScaleAttr, SurfaceScale, surfaceScale)
     43 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), KernelUnitLengthX, kernelUnitLengthX)
     44 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), KernelUnitLengthY, kernelUnitLengthY)
     45 
     46 inline SVGFESpecularLightingElement::SVGFESpecularLightingElement(const QualifiedName& tagName, Document* document)
     47     : SVGFilterPrimitiveStandardAttributes(tagName, document)
     48     , m_specularConstant(1)
     49     , m_specularExponent(1)
     50     , m_surfaceScale(1)
     51 {
     52 }
     53 
     54 PassRefPtr<SVGFESpecularLightingElement> SVGFESpecularLightingElement::create(const QualifiedName& tagName, Document* document)
     55 {
     56     return adoptRef(new SVGFESpecularLightingElement(tagName, document));
     57 }
     58 
     59 const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthXIdentifier()
     60 {
     61     DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX"));
     62     return s_identifier;
     63 }
     64 
     65 const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthYIdentifier()
     66 {
     67     DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY"));
     68     return s_identifier;
     69 }
     70 
     71 void SVGFESpecularLightingElement::parseMappedAttribute(Attribute* attr)
     72 {
     73     const String& value = attr->value();
     74     if (attr->name() == SVGNames::inAttr)
     75         setIn1BaseValue(value);
     76     else if (attr->name() == SVGNames::surfaceScaleAttr)
     77         setSurfaceScaleBaseValue(value.toFloat());
     78     else if (attr->name() == SVGNames::specularConstantAttr)
     79         setSpecularConstantBaseValue(value.toFloat());
     80     else if (attr->name() == SVGNames::specularExponentAttr)
     81         setSpecularExponentBaseValue(value.toFloat());
     82     else if (attr->name() == SVGNames::kernelUnitLengthAttr) {
     83         float x, y;
     84         if (parseNumberOptionalNumber(value, x, y)) {
     85             setKernelUnitLengthXBaseValue(x);
     86             setKernelUnitLengthYBaseValue(y);
     87         }
     88     } else
     89         SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
     90 }
     91 
     92 bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
     93 {
     94     FESpecularLighting* specularLighting = static_cast<FESpecularLighting*>(effect);
     95 
     96     if (attrName == SVGNames::lighting_colorAttr) {
     97         RenderObject* renderer = this->renderer();
     98         ASSERT(renderer);
     99         ASSERT(renderer->style());
    100         return specularLighting->setLightingColor(renderer->style()->svgStyle()->lightingColor());
    101     }
    102     if (attrName == SVGNames::surfaceScaleAttr)
    103         return specularLighting->setSurfaceScale(surfaceScale());
    104     if (attrName == SVGNames::specularConstantAttr)
    105         return specularLighting->setSpecularConstant(specularConstant());
    106     if (attrName == SVGNames::specularExponentAttr)
    107         return specularLighting->setSpecularExponent(specularExponent());
    108 
    109     LightSource* lightSource = const_cast<LightSource*>(specularLighting->lightSource());
    110     const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
    111     ASSERT(lightSource);
    112     ASSERT(lightElement);
    113 
    114     if (attrName == SVGNames::azimuthAttr)
    115         return lightSource->setAzimuth(lightElement->azimuth());
    116     if (attrName == SVGNames::elevationAttr)
    117         return lightSource->setElevation(lightElement->elevation());
    118     if (attrName == SVGNames::xAttr)
    119         return lightSource->setX(lightElement->x());
    120     if (attrName == SVGNames::yAttr)
    121         return lightSource->setY(lightElement->y());
    122     if (attrName == SVGNames::zAttr)
    123         return lightSource->setZ(lightElement->z());
    124     if (attrName == SVGNames::pointsAtXAttr)
    125         return lightSource->setPointsAtX(lightElement->pointsAtX());
    126     if (attrName == SVGNames::pointsAtYAttr)
    127         return lightSource->setPointsAtY(lightElement->pointsAtY());
    128     if (attrName == SVGNames::pointsAtZAttr)
    129         return lightSource->setPointsAtZ(lightElement->pointsAtZ());
    130     if (attrName == SVGNames::specularExponentAttr)
    131         return lightSource->setSpecularExponent(lightElement->specularExponent());
    132     if (attrName == SVGNames::limitingConeAngleAttr)
    133         return lightSource->setLimitingConeAngle(lightElement->limitingConeAngle());
    134 
    135     ASSERT_NOT_REACHED();
    136     return false;
    137 }
    138 
    139 void SVGFESpecularLightingElement::svgAttributeChanged(const QualifiedName& attrName)
    140 {
    141     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
    142 
    143     if (attrName == SVGNames::surfaceScaleAttr
    144         || attrName == SVGNames::specularConstantAttr
    145         || attrName == SVGNames::specularExponentAttr
    146         || attrName == SVGNames::kernelUnitLengthAttr)
    147         primitiveAttributeChanged(attrName);
    148 
    149     if (attrName == SVGNames::inAttr)
    150         invalidate();
    151 }
    152 
    153 void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
    154 {
    155     if (SVGFELightElement::findLightElement(this) != lightElement)
    156         return;
    157 
    158     // The light element has different attribute names so attrName can identify the requested attribute.
    159     primitiveAttributeChanged(attrName);
    160 }
    161 
    162 void SVGFESpecularLightingElement::synchronizeProperty(const QualifiedName& attrName)
    163 {
    164     SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
    165 
    166     if (attrName == anyQName()) {
    167         synchronizeIn1();
    168         synchronizeSurfaceScale();
    169         synchronizeSpecularConstant();
    170         synchronizeSpecularExponent();
    171         synchronizeKernelUnitLengthX();
    172         synchronizeKernelUnitLengthY();
    173         return;
    174     }
    175 
    176     if (attrName == SVGNames::inAttr)
    177         synchronizeIn1();
    178     else if (attrName == SVGNames::surfaceScaleAttr)
    179         synchronizeSurfaceScale();
    180     else if (attrName == SVGNames::specularConstantAttr)
    181         synchronizeSpecularConstant();
    182     else if (attrName == SVGNames::specularExponentAttr)
    183         synchronizeSpecularExponent();
    184     else if (attrName == SVGNames::kernelUnitLengthAttr) {
    185         synchronizeKernelUnitLengthX();
    186         synchronizeKernelUnitLengthY();
    187     }
    188 }
    189 
    190 AttributeToPropertyTypeMap& SVGFESpecularLightingElement::attributeToPropertyTypeMap()
    191 {
    192     DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
    193     return s_attributeToPropertyTypeMap;
    194 }
    195 
    196 void SVGFESpecularLightingElement::fillAttributeToPropertyTypeMap()
    197 {
    198     AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap();
    199 
    200     SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
    201     attributeToPropertyTypeMap.set(SVGNames::inAttr, AnimatedString);
    202     attributeToPropertyTypeMap.set(SVGNames::specularConstantAttr, AnimatedNumber);
    203     attributeToPropertyTypeMap.set(SVGNames::specularExponentAttr, AnimatedNumber);
    204     attributeToPropertyTypeMap.set(SVGNames::surfaceScaleAttr, AnimatedNumber);
    205     attributeToPropertyTypeMap.set(SVGNames::kernelUnitLengthAttr, AnimatedNumberOptionalNumber);
    206 }
    207 
    208 PassRefPtr<FilterEffect> SVGFESpecularLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
    209 {
    210     FilterEffect* input1 = filterBuilder->getEffectById(in1());
    211 
    212     if (!input1)
    213         return 0;
    214 
    215     RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this);
    216     if (!lightSource)
    217         return 0;
    218 
    219     RefPtr<RenderStyle> filterStyle = styleForRenderer();
    220 
    221     Color color = filterStyle->svgStyle()->lightingColor();
    222 
    223     RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(),
    224                                           specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), lightSource.release());
    225     effect->inputEffects().append(input1);
    226     return effect.release();
    227 }
    228 
    229 }
    230 
    231 #endif // ENABLE(SVG)
    232