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#if ENABLE(SVG) && ENABLE(FILTERS) 23#include "SVGFEDisplacementMapElement.h" 24 25#include "Attribute.h" 26#include "FilterEffect.h" 27#include "SVGFilterBuilder.h" 28#include "SVGNames.h" 29 30namespace WebCore { 31 32// Animated property definitions 33DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::inAttr, In1, in1) 34DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::in2Attr, In2, in2) 35DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::xChannelSelectorAttr, XChannelSelector, xChannelSelector) 36DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::yChannelSelectorAttr, YChannelSelector, yChannelSelector) 37DEFINE_ANIMATED_NUMBER(SVGFEDisplacementMapElement, SVGNames::scaleAttr, Scale, scale) 38 39inline SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(const QualifiedName& tagName, Document* document) 40 : SVGFilterPrimitiveStandardAttributes(tagName, document) 41 , m_xChannelSelector(CHANNEL_A) 42 , m_yChannelSelector(CHANNEL_A) 43{ 44} 45 46PassRefPtr<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(const QualifiedName& tagName, Document* document) 47{ 48 return adoptRef(new SVGFEDisplacementMapElement(tagName, document)); 49} 50 51ChannelSelectorType SVGFEDisplacementMapElement::stringToChannel(const String& key) 52{ 53 if (key == "R") 54 return CHANNEL_R; 55 if (key == "G") 56 return CHANNEL_G; 57 if (key == "B") 58 return CHANNEL_B; 59 if (key == "A") 60 return CHANNEL_A; 61 62 return CHANNEL_UNKNOWN; 63} 64 65void SVGFEDisplacementMapElement::parseMappedAttribute(Attribute* attr) 66{ 67 const String& value = attr->value(); 68 if (attr->name() == SVGNames::xChannelSelectorAttr) 69 setXChannelSelectorBaseValue(stringToChannel(value)); 70 else if (attr->name() == SVGNames::yChannelSelectorAttr) 71 setYChannelSelectorBaseValue(stringToChannel(value)); 72 else if (attr->name() == SVGNames::inAttr) 73 setIn1BaseValue(value); 74 else if (attr->name() == SVGNames::in2Attr) 75 setIn2BaseValue(value); 76 else if (attr->name() == SVGNames::scaleAttr) 77 setScaleBaseValue(value.toFloat()); 78 else 79 SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); 80} 81 82bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) 83{ 84 FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect); 85 if (attrName == SVGNames::xChannelSelectorAttr) 86 return displacementMap->setXChannelSelector(static_cast<ChannelSelectorType>(xChannelSelector())); 87 if (attrName == SVGNames::yChannelSelectorAttr) 88 return displacementMap->setYChannelSelector(static_cast<ChannelSelectorType>(yChannelSelector())); 89 if (attrName == SVGNames::scaleAttr) 90 return displacementMap->setScale(scale()); 91 92 ASSERT_NOT_REACHED(); 93 return false; 94} 95 96void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName) 97{ 98 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); 99 100 if (attrName == SVGNames::xChannelSelectorAttr) { 101 ChannelSelectorType selector = static_cast<ChannelSelectorType>(xChannelSelector()); 102 if (CHANNEL_UNKNOWN > selector || selector > CHANNEL_A) 103 setXChannelSelectorBaseValue(CHANNEL_UNKNOWN); 104 primitiveAttributeChanged(attrName); 105 } else if (attrName == SVGNames::yChannelSelectorAttr) { 106 ChannelSelectorType selector = static_cast<ChannelSelectorType>(yChannelSelector()); 107 if (CHANNEL_UNKNOWN > selector || selector > CHANNEL_A) 108 setYChannelSelectorBaseValue(CHANNEL_UNKNOWN); 109 primitiveAttributeChanged(attrName); 110 } else if (attrName == SVGNames::scaleAttr) 111 primitiveAttributeChanged(attrName); 112 else if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) 113 invalidate(); 114} 115 116void SVGFEDisplacementMapElement::synchronizeProperty(const QualifiedName& attrName) 117{ 118 SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); 119 120 if (attrName == anyQName()) { 121 synchronizeXChannelSelector(); 122 synchronizeYChannelSelector(); 123 synchronizeIn1(); 124 synchronizeIn2(); 125 synchronizeScale(); 126 return; 127 } 128 129 if (attrName == SVGNames::xChannelSelectorAttr) 130 synchronizeXChannelSelector(); 131 else if (attrName == SVGNames::yChannelSelectorAttr) 132 synchronizeYChannelSelector(); 133 else if (attrName == SVGNames::inAttr) 134 synchronizeIn1(); 135 else if (attrName == SVGNames::in2Attr) 136 synchronizeIn2(); 137 else if (attrName == SVGNames::scaleAttr) 138 synchronizeScale(); 139} 140 141AttributeToPropertyTypeMap& SVGFEDisplacementMapElement::attributeToPropertyTypeMap() 142{ 143 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 144 return s_attributeToPropertyTypeMap; 145} 146 147void SVGFEDisplacementMapElement::fillAttributeToPropertyTypeMap() 148{ 149 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap(); 150 151 SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap); 152 attributeToPropertyTypeMap.set(SVGNames::inAttr, AnimatedString); 153 attributeToPropertyTypeMap.set(SVGNames::in2Attr, AnimatedString); 154 attributeToPropertyTypeMap.set(SVGNames::xChannelSelectorAttr, AnimatedEnumeration); 155 attributeToPropertyTypeMap.set(SVGNames::yChannelSelectorAttr, AnimatedEnumeration); 156 attributeToPropertyTypeMap.set(SVGNames::scaleAttr, AnimatedNumber); 157} 158 159PassRefPtr<FilterEffect> SVGFEDisplacementMapElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) 160{ 161 FilterEffect* input1 = filterBuilder->getEffectById(in1()); 162 FilterEffect* input2 = filterBuilder->getEffectById(in2()); 163 164 if (!input1 || !input2) 165 return 0; 166 167 RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, static_cast<ChannelSelectorType>(xChannelSelector()), 168 static_cast<ChannelSelectorType>(yChannelSelector()), scale()); 169 FilterEffectVector& inputEffects = effect->inputEffects(); 170 inputEffects.reserveCapacity(2); 171 inputEffects.append(input1); 172 inputEffects.append(input2); 173 return effect.release(); 174} 175 176} 177 178#endif // ENABLE(SVG) 179 180// vim:ts=4:noet 181