SVGFESpecularLightingElement.cpp revision 65f03d4f644ce73618e5f4f50dd694b26f55ae12
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(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
36namespace WebCore {
37
38// Animated property definitions
39DEFINE_ANIMATED_STRING(SVGFESpecularLightingElement, SVGNames::inAttr, In1, in1)
40DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::specularConstantAttr, SpecularConstant, specularConstant)
41DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::specularExponentAttr, SpecularExponent, specularExponent)
42DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::surfaceScaleAttr, SurfaceScale, surfaceScale)
43DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), KernelUnitLengthX, kernelUnitLengthX)
44DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), KernelUnitLengthY, kernelUnitLengthY)
45
46inline 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
54PassRefPtr<SVGFESpecularLightingElement> SVGFESpecularLightingElement::create(const QualifiedName& tagName, Document* document)
55{
56    return adoptRef(new SVGFESpecularLightingElement(tagName, document));
57}
58
59const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthXIdentifier()
60{
61    DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX"));
62    return s_identifier;
63}
64
65const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthYIdentifier()
66{
67    DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY"));
68    return s_identifier;
69}
70
71void 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
92void SVGFESpecularLightingElement::synchronizeProperty(const QualifiedName& attrName)
93{
94    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
95
96    if (attrName == anyQName()) {
97        synchronizeIn1();
98        synchronizeSurfaceScale();
99        synchronizeSpecularConstant();
100        synchronizeSpecularExponent();
101        synchronizeKernelUnitLengthX();
102        synchronizeKernelUnitLengthY();
103        return;
104    }
105
106    if (attrName == SVGNames::inAttr)
107        synchronizeIn1();
108    else if (attrName == SVGNames::surfaceScaleAttr)
109        synchronizeSurfaceScale();
110    else if (attrName == SVGNames::specularConstantAttr)
111        synchronizeSpecularConstant();
112    else if (attrName == SVGNames::specularExponentAttr)
113        synchronizeSpecularExponent();
114    else if (attrName == SVGNames::kernelUnitLengthAttr) {
115        synchronizeKernelUnitLengthX();
116        synchronizeKernelUnitLengthY();
117    }
118}
119
120PassRefPtr<LightSource> SVGFESpecularLightingElement::findLights() const
121{
122    for (Node* node = firstChild(); node; node = node->nextSibling()) {
123        if (node->hasTagName(SVGNames::feDistantLightTag)
124            || node->hasTagName(SVGNames::fePointLightTag)
125            || node->hasTagName(SVGNames::feSpotLightTag)) {
126            SVGFELightElement* lightNode = static_cast<SVGFELightElement*>(node);
127            return lightNode->lightSource();
128        }
129    }
130
131    return 0;
132}
133
134PassRefPtr<FilterEffect> SVGFESpecularLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
135{
136    FilterEffect* input1 = filterBuilder->getEffectById(in1());
137
138    if (!input1)
139        return 0;
140
141    RefPtr<RenderStyle> filterStyle = styleForRenderer();
142
143    Color color = filterStyle->svgStyle()->lightingColor();
144
145    RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScale(), specularConstant(),
146                                          specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), findLights());
147    effect->inputEffects().append(input1);
148    return effect.release();
149}
150
151}
152
153#endif // ENABLE(SVG)
154