Remove the SVG elements' attributes macros
[WebKit-https.git] / Source / WebCore / svg / SVGFEDiffuseLightingElement.cpp
1 /*
2  * Copyright (C) 2005 Oliver Hunt <ojh16@student.canterbury.ac.nz>
3  * Copyright (C) 2018 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "SVGFEDiffuseLightingElement.h"
23
24 #include "FEDiffuseLighting.h"
25 #include "FilterEffect.h"
26 #include "RenderStyle.h"
27 #include "SVGFELightElement.h"
28 #include "SVGFilterBuilder.h"
29 #include "SVGNames.h"
30 #include "SVGParserUtilities.h"
31 #include <wtf/IsoMallocInlines.h>
32
33 namespace WebCore {
34
35 WTF_MAKE_ISO_ALLOCATED_IMPL(SVGFEDiffuseLightingElement);
36
37 inline SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(const QualifiedName& tagName, Document& document)
38     : SVGFilterPrimitiveStandardAttributes(tagName, document)
39 {
40     ASSERT(hasTagName(SVGNames::feDiffuseLightingTag));
41     registerAttributes();
42 }
43
44 Ref<SVGFEDiffuseLightingElement> SVGFEDiffuseLightingElement::create(const QualifiedName& tagName, Document& document)
45 {
46     return adoptRef(*new SVGFEDiffuseLightingElement(tagName, document));
47 }
48
49 const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthXIdentifier()
50 {
51     static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral);
52     return s_identifier;
53 }
54
55 const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier()
56 {
57     static NeverDestroyed<AtomicString> s_identifier("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral);
58     return s_identifier;
59 }
60
61 void SVGFEDiffuseLightingElement::registerAttributes()
62 {
63     auto& registry = attributeRegistry();
64     if (!registry.isEmpty())
65         return;
66     registry.registerAttribute<SVGNames::inAttr, &SVGFEDiffuseLightingElement::m_in1>();
67     registry.registerAttribute<SVGNames::diffuseConstantAttr, &SVGFEDiffuseLightingElement::m_diffuseConstant>();
68     registry.registerAttribute<SVGNames::surfaceScaleAttr, &SVGFEDiffuseLightingElement::m_surfaceScale>();
69     registry.registerAttribute<SVGNames::kernelUnitLengthAttr,
70         &SVGFEDiffuseLightingElement::kernelUnitLengthXIdentifier, &SVGFEDiffuseLightingElement::m_kernelUnitLengthX,
71         &SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier, &SVGFEDiffuseLightingElement::m_kernelUnitLengthY>();
72 }
73
74 void SVGFEDiffuseLightingElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
75 {
76     if (name == SVGNames::inAttr) {
77         m_in1.setValue(value);
78         return;
79     }
80
81     if (name == SVGNames::surfaceScaleAttr) {
82         m_surfaceScale.setValue(value.toFloat());
83         return;
84     }
85
86     if (name == SVGNames::diffuseConstantAttr) {
87         m_diffuseConstant.setValue(value.toFloat());
88         return;
89     }
90
91     if (name == SVGNames::kernelUnitLengthAttr) {
92         float x, y;
93         if (parseNumberOptionalNumber(value, x, y)) {
94             m_kernelUnitLengthX.setValue(x);
95             m_kernelUnitLengthY.setValue(y);
96         }
97         return;
98     }
99
100     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
101 }
102
103 bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
104 {
105     FEDiffuseLighting* diffuseLighting = static_cast<FEDiffuseLighting*>(effect);
106
107     if (attrName == SVGNames::lighting_colorAttr) {
108         RenderObject* renderer = this->renderer();
109         ASSERT(renderer);
110         Color color = renderer->style().colorByApplyingColorFilter(renderer->style().svgStyle().lightingColor());
111         return diffuseLighting->setLightingColor(color);
112     }
113     if (attrName == SVGNames::surfaceScaleAttr)
114         return diffuseLighting->setSurfaceScale(surfaceScale());
115     if (attrName == SVGNames::diffuseConstantAttr)
116         return diffuseLighting->setDiffuseConstant(diffuseConstant());
117
118     auto& lightSource = const_cast<LightSource&>(diffuseLighting->lightSource());
119     const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
120     ASSERT(lightElement);
121
122     if (attrName == SVGNames::azimuthAttr)
123         return lightSource.setAzimuth(lightElement->azimuth());
124     if (attrName == SVGNames::elevationAttr)
125         return lightSource.setElevation(lightElement->elevation());
126     if (attrName == SVGNames::xAttr)
127         return lightSource.setX(lightElement->x());
128     if (attrName == SVGNames::yAttr)
129         return lightSource.setY(lightElement->y());
130     if (attrName == SVGNames::zAttr)
131         return lightSource.setZ(lightElement->z());
132     if (attrName == SVGNames::pointsAtXAttr)
133         return lightSource.setPointsAtX(lightElement->pointsAtX());
134     if (attrName == SVGNames::pointsAtYAttr)
135         return lightSource.setPointsAtY(lightElement->pointsAtY());
136     if (attrName == SVGNames::pointsAtZAttr)
137         return lightSource.setPointsAtZ(lightElement->pointsAtZ());
138     if (attrName == SVGNames::specularExponentAttr)
139         return lightSource.setSpecularExponent(lightElement->specularExponent());
140     if (attrName == SVGNames::limitingConeAngleAttr)
141         return lightSource.setLimitingConeAngle(lightElement->limitingConeAngle());
142
143     ASSERT_NOT_REACHED();
144     return false;
145 }
146
147 void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrName)
148 {
149     if (attrName == SVGNames::surfaceScaleAttr || attrName == SVGNames::diffuseConstantAttr || attrName == SVGNames::kernelUnitLengthAttr || attrName == SVGNames::lighting_colorAttr) {
150         InstanceInvalidationGuard guard(*this);
151         primitiveAttributeChanged(attrName);
152         return;
153     }
154
155     if (attrName == SVGNames::inAttr) {
156         InstanceInvalidationGuard guard(*this);
157         invalidate();
158         return;
159     }
160
161     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
162 }
163
164 void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
165 {
166     if (SVGFELightElement::findLightElement(this) != lightElement)
167         return;
168
169     // The light element has different attribute names.
170     primitiveAttributeChanged(attrName);
171 }
172
173 RefPtr<FilterEffect> SVGFEDiffuseLightingElement::build(SVGFilterBuilder* filterBuilder, Filter& filter)
174 {
175     auto input1 = filterBuilder->getEffectById(in1());
176
177     if (!input1)
178         return nullptr;
179
180     auto lightElement = makeRefPtr(SVGFELightElement::findLightElement(this));
181     if (!lightElement)
182         return nullptr;
183     
184     auto lightSource = lightElement->lightSource(*filterBuilder);
185
186     RenderObject* renderer = this->renderer();
187     if (!renderer)
188         return nullptr;
189
190     Color color = renderer->style().colorByApplyingColorFilter(renderer->style().svgStyle().lightingColor());
191
192     RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScale(), diffuseConstant(), kernelUnitLengthX(), kernelUnitLengthY(), WTFMove(lightSource));
193     effect->inputEffects().append(input1);
194     return effect;
195 }
196
197 }