Use #pragma once in WebCore
[WebKit-https.git] / Source / WebCore / svg / SVGFEMorphologyElement.cpp
1 /*
2  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
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 #include "SVGFEMorphologyElement.h"
22
23 #include "FilterEffect.h"
24 #include "SVGFilterBuilder.h"
25 #include "SVGNames.h"
26 #include "SVGParserUtilities.h"
27
28 namespace WebCore {
29
30 // Animated property definitions
31 DEFINE_ANIMATED_STRING(SVGFEMorphologyElement, SVGNames::inAttr, In1, in1)
32 DEFINE_ANIMATED_ENUMERATION(SVGFEMorphologyElement, SVGNames::operatorAttr, SVGOperator, svgOperator, MorphologyOperatorType)
33 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusXIdentifier(), RadiusX, radiusX)
34 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusYIdentifier(), RadiusY, radiusY)
35
36 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEMorphologyElement)
37     REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
38     REGISTER_LOCAL_ANIMATED_PROPERTY(svgOperator)
39     REGISTER_LOCAL_ANIMATED_PROPERTY(radiusX)
40     REGISTER_LOCAL_ANIMATED_PROPERTY(radiusY)
41     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
42 END_REGISTER_ANIMATED_PROPERTIES
43
44 inline SVGFEMorphologyElement::SVGFEMorphologyElement(const QualifiedName& tagName, Document& document)
45     : SVGFilterPrimitiveStandardAttributes(tagName, document)
46     , m_svgOperator(FEMORPHOLOGY_OPERATOR_ERODE)
47 {
48     ASSERT(hasTagName(SVGNames::feMorphologyTag));
49     registerAnimatedPropertiesForSVGFEMorphologyElement();
50 }
51
52 Ref<SVGFEMorphologyElement> SVGFEMorphologyElement::create(const QualifiedName& tagName, Document& document)
53 {
54     return adoptRef(*new SVGFEMorphologyElement(tagName, document));
55 }
56
57 const AtomicString& SVGFEMorphologyElement::radiusXIdentifier()
58 {
59     static NeverDestroyed<AtomicString> s_identifier("SVGRadiusX", AtomicString::ConstructFromLiteral);
60     return s_identifier;
61 }
62
63 const AtomicString& SVGFEMorphologyElement::radiusYIdentifier()
64 {
65     static NeverDestroyed<AtomicString> s_identifier("SVGRadiusY", AtomicString::ConstructFromLiteral);
66     return s_identifier;
67 }
68
69 void SVGFEMorphologyElement::setRadius(float x, float y)
70 {
71     setRadiusXBaseValue(x);
72     setRadiusYBaseValue(y);
73     invalidate();
74 }
75
76 void SVGFEMorphologyElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
77 {
78     if (name == SVGNames::operatorAttr) {
79         MorphologyOperatorType propertyValue = SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
80         if (propertyValue > 0)
81             setSVGOperatorBaseValue(propertyValue);
82         return;
83     }
84
85     if (name == SVGNames::inAttr) {
86         setIn1BaseValue(value);
87         return;
88     }
89
90     if (name == SVGNames::radiusAttr) {
91         float x, y;
92         if (parseNumberOptionalNumber(value, x, y)) {
93             setRadiusXBaseValue(x);
94             setRadiusYBaseValue(y);
95         }
96         return;
97     }
98
99     SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
100 }
101
102 bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
103 {
104     FEMorphology* morphology = static_cast<FEMorphology*>(effect);
105     if (attrName == SVGNames::operatorAttr)
106         return morphology->setMorphologyOperator(svgOperator());
107     if (attrName == SVGNames::radiusAttr) {
108         // Both setRadius functions should be evaluated separately.
109         bool isRadiusXChanged = morphology->setRadiusX(radiusX());
110         bool isRadiusYChanged = morphology->setRadiusY(radiusY());
111         return isRadiusXChanged || isRadiusYChanged;
112     }
113
114     ASSERT_NOT_REACHED();
115     return false;
116 }
117
118 void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName)
119 {
120     if (attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr) {
121         InstanceInvalidationGuard guard(*this);
122         primitiveAttributeChanged(attrName);
123         return;
124     }
125
126     if (attrName == SVGNames::inAttr) {
127         InstanceInvalidationGuard guard(*this);
128         invalidate();
129         return;
130     }
131
132     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
133 }
134
135 RefPtr<FilterEffect> SVGFEMorphologyElement::build(SVGFilterBuilder* filterBuilder, Filter& filter)
136 {
137     FilterEffect* input1 = filterBuilder->getEffectById(in1());
138     float xRadius = radiusX();
139     float yRadius = radiusY();
140
141     if (!input1)
142         return nullptr;
143
144     if (xRadius < 0 || yRadius < 0)
145         return nullptr;
146
147     RefPtr<FilterEffect> effect = FEMorphology::create(filter, svgOperator(), xRadius, yRadius);
148     effect->inputEffects().append(input1);
149     return effect;
150 }
151
152 } // namespace WebCore