1/* 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#include "config.h" 22 23#include "core/svg/SVGFECompositeElement.h" 24 25#include "SVGNames.h" 26#include "platform/graphics/filters/FilterEffect.h" 27#include "core/svg/SVGElementInstance.h" 28#include "core/svg/graphics/filters/SVGFilterBuilder.h" 29 30namespace WebCore { 31 32// Animated property definitions 33DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::inAttr, In1, in1) 34DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::in2Attr, In2, in2) 35DEFINE_ANIMATED_ENUMERATION(SVGFECompositeElement, SVGNames::operatorAttr, SVGOperator, svgOperator, CompositeOperationType) 36DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k1Attr, K1, k1) 37DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k2Attr, K2, k2) 38DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k3Attr, K3, k3) 39DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k4Attr, K4, k4) 40 41BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFECompositeElement) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(in1) 43 REGISTER_LOCAL_ANIMATED_PROPERTY(in2) 44 REGISTER_LOCAL_ANIMATED_PROPERTY(svgOperator) 45 REGISTER_LOCAL_ANIMATED_PROPERTY(k1) 46 REGISTER_LOCAL_ANIMATED_PROPERTY(k2) 47 REGISTER_LOCAL_ANIMATED_PROPERTY(k3) 48 REGISTER_LOCAL_ANIMATED_PROPERTY(k4) 49 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes) 50END_REGISTER_ANIMATED_PROPERTIES 51 52inline SVGFECompositeElement::SVGFECompositeElement(Document& document) 53 : SVGFilterPrimitiveStandardAttributes(SVGNames::feCompositeTag, document) 54 , m_svgOperator(FECOMPOSITE_OPERATOR_OVER) 55{ 56 ScriptWrappable::init(this); 57 registerAnimatedPropertiesForSVGFECompositeElement(); 58} 59 60PassRefPtr<SVGFECompositeElement> SVGFECompositeElement::create(Document& document) 61{ 62 return adoptRef(new SVGFECompositeElement(document)); 63} 64 65bool SVGFECompositeElement::isSupportedAttribute(const QualifiedName& attrName) 66{ 67 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 68 if (supportedAttributes.isEmpty()) { 69 supportedAttributes.add(SVGNames::inAttr); 70 supportedAttributes.add(SVGNames::in2Attr); 71 supportedAttributes.add(SVGNames::operatorAttr); 72 supportedAttributes.add(SVGNames::k1Attr); 73 supportedAttributes.add(SVGNames::k2Attr); 74 supportedAttributes.add(SVGNames::k3Attr); 75 supportedAttributes.add(SVGNames::k4Attr); 76 } 77 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 78} 79 80void SVGFECompositeElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 81{ 82 if (!isSupportedAttribute(name)) { 83 SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); 84 return; 85 } 86 87 if (name == SVGNames::operatorAttr) { 88 CompositeOperationType propertyValue = SVGPropertyTraits<CompositeOperationType>::fromString(value); 89 if (propertyValue > 0) 90 setSVGOperatorBaseValue(propertyValue); 91 return; 92 } 93 94 if (name == SVGNames::inAttr) { 95 setIn1BaseValue(value); 96 return; 97 } 98 99 if (name == SVGNames::in2Attr) { 100 setIn2BaseValue(value); 101 return; 102 } 103 104 if (name == SVGNames::k1Attr) { 105 setK1BaseValue(value.toFloat()); 106 return; 107 } 108 109 if (name == SVGNames::k2Attr) { 110 setK2BaseValue(value.toFloat()); 111 return; 112 } 113 114 if (name == SVGNames::k3Attr) { 115 setK3BaseValue(value.toFloat()); 116 return; 117 } 118 119 if (name == SVGNames::k4Attr) { 120 setK4BaseValue(value.toFloat()); 121 return; 122 } 123 124 ASSERT_NOT_REACHED(); 125} 126 127bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) 128{ 129 FEComposite* composite = static_cast<FEComposite*>(effect); 130 if (attrName == SVGNames::operatorAttr) 131 return composite->setOperation(svgOperatorCurrentValue()); 132 if (attrName == SVGNames::k1Attr) 133 return composite->setK1(k1CurrentValue()); 134 if (attrName == SVGNames::k2Attr) 135 return composite->setK2(k2CurrentValue()); 136 if (attrName == SVGNames::k3Attr) 137 return composite->setK3(k3CurrentValue()); 138 if (attrName == SVGNames::k4Attr) 139 return composite->setK4(k4CurrentValue()); 140 141 ASSERT_NOT_REACHED(); 142 return false; 143} 144 145 146void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName) 147{ 148 if (!isSupportedAttribute(attrName)) { 149 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); 150 return; 151 } 152 153 SVGElementInstance::InvalidationGuard invalidationGuard(this); 154 155 if (attrName == SVGNames::operatorAttr 156 || attrName == SVGNames::k1Attr 157 || attrName == SVGNames::k2Attr 158 || attrName == SVGNames::k3Attr 159 || attrName == SVGNames::k4Attr) { 160 primitiveAttributeChanged(attrName); 161 return; 162 } 163 164 if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) { 165 invalidate(); 166 return; 167 } 168 169 ASSERT_NOT_REACHED(); 170} 171 172PassRefPtr<FilterEffect> SVGFECompositeElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) 173{ 174 FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue()); 175 FilterEffect* input2 = filterBuilder->getEffectById(in2CurrentValue()); 176 177 if (!input1 || !input2) 178 return 0; 179 180 RefPtr<FilterEffect> effect = FEComposite::create(filter, svgOperatorCurrentValue(), k1CurrentValue(), k2CurrentValue(), k3CurrentValue(), k4CurrentValue()); 181 FilterEffectVector& inputEffects = effect->inputEffects(); 182 inputEffects.reserveCapacity(2); 183 inputEffects.append(input1); 184 inputEffects.append(input2); 185 return effect.release(); 186} 187 188} 189