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 #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 30 namespace WebCore { 31 32 // Animated property definitions 33 DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::inAttr, In1, in1) 34 DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::in2Attr, In2, in2) 35 DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::xChannelSelectorAttr, XChannelSelector, xChannelSelector) 36 DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::yChannelSelectorAttr, YChannelSelector, yChannelSelector) 37 DEFINE_ANIMATED_NUMBER(SVGFEDisplacementMapElement, SVGNames::scaleAttr, Scale, scale) 38 39 inline SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(const QualifiedName& tagName, Document* document) 40 : SVGFilterPrimitiveStandardAttributes(tagName, document) 41 , m_xChannelSelector(CHANNEL_A) 42 , m_yChannelSelector(CHANNEL_A) 43 { 44 } 45 46 PassRefPtr<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(const QualifiedName& tagName, Document* document) 47 { 48 return adoptRef(new SVGFEDisplacementMapElement(tagName, document)); 49 } 50 51 ChannelSelectorType 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 65 void 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 82 bool 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 96 void 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 116 void 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 141 AttributeToPropertyTypeMap& SVGFEDisplacementMapElement::attributeToPropertyTypeMap() 142 { 143 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 144 return s_attributeToPropertyTypeMap; 145 } 146 147 void 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 159 PassRefPtr<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