1 /* 2 * Copyright (C) 2006 Oliver Hunt <oliver (at) 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 addToPropertyMap(m_scale); 51 addToPropertyMap(m_in1); 52 addToPropertyMap(m_in2); 53 addToPropertyMap(m_xChannelSelector); 54 addToPropertyMap(m_yChannelSelector); 55 } 56 57 DEFINE_NODE_FACTORY(SVGFEDisplacementMapElement) 58 59 bool SVGFEDisplacementMapElement::isSupportedAttribute(const QualifiedName& attrName) 60 { 61 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 62 if (supportedAttributes.isEmpty()) { 63 supportedAttributes.add(SVGNames::inAttr); 64 supportedAttributes.add(SVGNames::in2Attr); 65 supportedAttributes.add(SVGNames::xChannelSelectorAttr); 66 supportedAttributes.add(SVGNames::yChannelSelectorAttr); 67 supportedAttributes.add(SVGNames::scaleAttr); 68 } 69 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 70 } 71 72 void SVGFEDisplacementMapElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 73 { 74 if (!isSupportedAttribute(name)) { 75 SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); 76 return; 77 } 78 79 SVGParsingError parseError = NoError; 80 81 if (name == SVGNames::inAttr) 82 m_in1->setBaseValueAsString(value, parseError); 83 else if (name == SVGNames::in2Attr) 84 m_in2->setBaseValueAsString(value, parseError); 85 else if (name == SVGNames::scaleAttr) 86 m_scale->setBaseValueAsString(value, parseError); 87 else if (name == SVGNames::xChannelSelectorAttr) 88 m_xChannelSelector->setBaseValueAsString(value, parseError); 89 else if (name == SVGNames::yChannelSelectorAttr) 90 m_yChannelSelector->setBaseValueAsString(value, parseError); 91 else 92 ASSERT_NOT_REACHED(); 93 94 reportAttributeParsingError(parseError, name, value); 95 } 96 97 bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) 98 { 99 FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect); 100 if (attrName == SVGNames::xChannelSelectorAttr) 101 return displacementMap->setXChannelSelector(m_xChannelSelector->currentValue()->enumValue()); 102 if (attrName == SVGNames::yChannelSelectorAttr) 103 return displacementMap->setYChannelSelector(m_yChannelSelector->currentValue()->enumValue()); 104 if (attrName == SVGNames::scaleAttr) 105 return displacementMap->setScale(m_scale->currentValue()->value()); 106 107 ASSERT_NOT_REACHED(); 108 return false; 109 } 110 111 void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName) 112 { 113 if (!isSupportedAttribute(attrName)) { 114 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); 115 return; 116 } 117 118 SVGElement::InvalidationGuard invalidationGuard(this); 119 120 if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr) { 121 primitiveAttributeChanged(attrName); 122 return; 123 } 124 125 if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) { 126 invalidate(); 127 return; 128 } 129 130 ASSERT_NOT_REACHED(); 131 } 132 133 PassRefPtr<FilterEffect> SVGFEDisplacementMapElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) 134 { 135 FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value())); 136 FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value())); 137 138 if (!input1 || !input2) 139 return nullptr; 140 141 RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, m_xChannelSelector->currentValue()->enumValue(), m_yChannelSelector->currentValue()->enumValue(), m_scale->currentValue()->value()); 142 FilterEffectVector& inputEffects = effect->inputEffects(); 143 inputEffects.reserveCapacity(2); 144 inputEffects.append(input1); 145 inputEffects.append(input2); 146 return effect.release(); 147 } 148 149 } // namespace blink 150