Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / SVGFEDisplacementMapElement.cpp
1 /*
2  * Copyright (C) 2006 Oliver Hunt <oliver@nerget.com>
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 #include "core/svg/SVGFEDisplacementMapElement.h"
23
24 #include "core/SVGNames.h"
25 #include "platform/graphics/filters/FilterEffect.h"
26 #include "core/svg/graphics/filters/SVGFilterBuilder.h"
27
28 namespace blink {
29
30 template<> const SVGEnumerationStringEntries& getStaticStringEntries<ChannelSelectorType>()
31 {
32     DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
33     if (entries.isEmpty()) {
34         entries.append(std::make_pair(CHANNEL_R, "R"));
35         entries.append(std::make_pair(CHANNEL_G, "G"));
36         entries.append(std::make_pair(CHANNEL_B, "B"));
37         entries.append(std::make_pair(CHANNEL_A, "A"));
38     }
39     return entries;
40 }
41
42 inline SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(Document& document)
43     : SVGFilterPrimitiveStandardAttributes(SVGNames::feDisplacementMapTag, document)
44     , m_scale(SVGAnimatedNumber::create(this, SVGNames::scaleAttr, SVGNumber::create(0)))
45     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
46     , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
47     , m_xChannelSelector(SVGAnimatedEnumeration<ChannelSelectorType>::create(this, SVGNames::xChannelSelectorAttr, CHANNEL_A))
48     , m_yChannelSelector(SVGAnimatedEnumeration<ChannelSelectorType>::create(this, SVGNames::yChannelSelectorAttr, CHANNEL_A))
49 {
50     ScriptWrappable::init(this);
51
52     addToPropertyMap(m_scale);
53     addToPropertyMap(m_in1);
54     addToPropertyMap(m_in2);
55     addToPropertyMap(m_xChannelSelector);
56     addToPropertyMap(m_yChannelSelector);
57 }
58
59 DEFINE_NODE_FACTORY(SVGFEDisplacementMapElement)
60
61 bool SVGFEDisplacementMapElement::isSupportedAttribute(const QualifiedName& attrName)
62 {
63     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
64     if (supportedAttributes.isEmpty()) {
65         supportedAttributes.add(SVGNames::inAttr);
66         supportedAttributes.add(SVGNames::in2Attr);
67         supportedAttributes.add(SVGNames::xChannelSelectorAttr);
68         supportedAttributes.add(SVGNames::yChannelSelectorAttr);
69         supportedAttributes.add(SVGNames::scaleAttr);
70     }
71     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
72 }
73
74 void SVGFEDisplacementMapElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
75 {
76     if (!isSupportedAttribute(name)) {
77         SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
78         return;
79     }
80
81     SVGParsingError parseError = NoError;
82
83     if (name == SVGNames::inAttr)
84         m_in1->setBaseValueAsString(value, parseError);
85     else if (name == SVGNames::in2Attr)
86         m_in2->setBaseValueAsString(value, parseError);
87     else if (name == SVGNames::scaleAttr)
88         m_scale->setBaseValueAsString(value, parseError);
89     else if (name == SVGNames::xChannelSelectorAttr)
90         m_xChannelSelector->setBaseValueAsString(value, parseError);
91     else if (name == SVGNames::yChannelSelectorAttr)
92         m_yChannelSelector->setBaseValueAsString(value, parseError);
93     else
94         ASSERT_NOT_REACHED();
95
96     reportAttributeParsingError(parseError, name, value);
97 }
98
99 bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
100 {
101     FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect);
102     if (attrName == SVGNames::xChannelSelectorAttr)
103         return displacementMap->setXChannelSelector(m_xChannelSelector->currentValue()->enumValue());
104     if (attrName == SVGNames::yChannelSelectorAttr)
105         return displacementMap->setYChannelSelector(m_yChannelSelector->currentValue()->enumValue());
106     if (attrName == SVGNames::scaleAttr)
107         return displacementMap->setScale(m_scale->currentValue()->value());
108
109     ASSERT_NOT_REACHED();
110     return false;
111 }
112
113 void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName)
114 {
115     if (!isSupportedAttribute(attrName)) {
116         SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
117         return;
118     }
119
120     SVGElement::InvalidationGuard invalidationGuard(this);
121
122     if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr) {
123         primitiveAttributeChanged(attrName);
124         return;
125     }
126
127     if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
128         invalidate();
129         return;
130     }
131
132     ASSERT_NOT_REACHED();
133 }
134
135 PassRefPtr<FilterEffect> SVGFEDisplacementMapElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
136 {
137     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
138     FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
139
140     if (!input1 || !input2)
141         return nullptr;
142
143     RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, m_xChannelSelector->currentValue()->enumValue(), m_yChannelSelector->currentValue()->enumValue(), m_scale->currentValue()->value());
144     FilterEffectVector& inputEffects = effect->inputEffects();
145     inputEffects.reserveCapacity(2);
146     inputEffects.append(input1);
147     inputEffects.append(input2);
148     return effect.release();
149 }
150
151 }