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#if ENABLE(SVG) && ENABLE(FILTERS) 24#include "SVGFECompositeElement.h" 25 26#include "Attribute.h" 27#include "FilterEffect.h" 28#include "SVGFilterBuilder.h" 29#include "SVGNames.h" 30 31namespace WebCore { 32 33// Animated property definitions 34DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::inAttr, In1, in1) 35DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::in2Attr, In2, in2) 36DEFINE_ANIMATED_ENUMERATION(SVGFECompositeElement, SVGNames::operatorAttr, _operator, _operator) 37DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k1Attr, K1, k1) 38DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k2Attr, K2, k2) 39DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k3Attr, K3, k3) 40DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k4Attr, K4, k4) 41 42inline SVGFECompositeElement::SVGFECompositeElement(const QualifiedName& tagName, Document* document) 43 : SVGFilterPrimitiveStandardAttributes(tagName, document) 44 , m__operator(FECOMPOSITE_OPERATOR_OVER) 45{ 46} 47 48PassRefPtr<SVGFECompositeElement> SVGFECompositeElement::create(const QualifiedName& tagName, Document* document) 49{ 50 return adoptRef(new SVGFECompositeElement(tagName, document)); 51} 52 53void SVGFECompositeElement::parseMappedAttribute(Attribute* attr) 54{ 55 const String& value = attr->value(); 56 if (attr->name() == SVGNames::operatorAttr) { 57 if (value == "over") 58 set_operatorBaseValue(FECOMPOSITE_OPERATOR_OVER); 59 else if (value == "in") 60 set_operatorBaseValue(FECOMPOSITE_OPERATOR_IN); 61 else if (value == "out") 62 set_operatorBaseValue(FECOMPOSITE_OPERATOR_OUT); 63 else if (value == "atop") 64 set_operatorBaseValue(FECOMPOSITE_OPERATOR_ATOP); 65 else if (value == "xor") 66 set_operatorBaseValue(FECOMPOSITE_OPERATOR_XOR); 67 else if (value == "arithmetic") 68 set_operatorBaseValue(FECOMPOSITE_OPERATOR_ARITHMETIC); 69 } else if (attr->name() == SVGNames::inAttr) 70 setIn1BaseValue(value); 71 else if (attr->name() == SVGNames::in2Attr) 72 setIn2BaseValue(value); 73 else if (attr->name() == SVGNames::k1Attr) 74 setK1BaseValue(value.toFloat()); 75 else if (attr->name() == SVGNames::k2Attr) 76 setK2BaseValue(value.toFloat()); 77 else if (attr->name() == SVGNames::k3Attr) 78 setK3BaseValue(value.toFloat()); 79 else if (attr->name() == SVGNames::k4Attr) 80 setK4BaseValue(value.toFloat()); 81 else 82 SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); 83} 84 85bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) 86{ 87 FEComposite* composite = static_cast<FEComposite*>(effect); 88 if (attrName == SVGNames::operatorAttr) 89 return composite->setOperation(static_cast<CompositeOperationType>(_operator())); 90 if (attrName == SVGNames::k1Attr) 91 return composite->setK1(k1()); 92 if (attrName == SVGNames::k2Attr) 93 return composite->setK2(k2()); 94 if (attrName == SVGNames::k3Attr) 95 return composite->setK3(k3()); 96 if (attrName == SVGNames::k4Attr) 97 return composite->setK4(k4()); 98 99 ASSERT_NOT_REACHED(); 100 return false; 101} 102 103 104void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName) 105{ 106 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); 107 108 if (attrName == SVGNames::operatorAttr 109 || attrName == SVGNames::k1Attr 110 || attrName == SVGNames::k2Attr 111 || attrName == SVGNames::k3Attr 112 || attrName == SVGNames::k4Attr) 113 primitiveAttributeChanged(attrName); 114 115 if (attrName == SVGNames::inAttr 116 || attrName == SVGNames::in2Attr) 117 invalidate(); 118} 119 120void SVGFECompositeElement::synchronizeProperty(const QualifiedName& attrName) 121{ 122 SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName); 123 124 if (attrName == anyQName()) { 125 synchronize_operator(); 126 synchronizeIn1(); 127 synchronizeIn2(); 128 synchronizeK1(); 129 synchronizeK2(); 130 synchronizeK3(); 131 synchronizeK4(); 132 return; 133 } 134 135 if (attrName == SVGNames::operatorAttr) 136 synchronize_operator(); 137 else if (attrName == SVGNames::inAttr) 138 synchronizeIn1(); 139 else if (attrName == SVGNames::in2Attr) 140 synchronizeIn2(); 141 else if (attrName == SVGNames::k1Attr) 142 synchronizeK1(); 143 else if (attrName == SVGNames::k2Attr) 144 synchronizeK2(); 145 else if (attrName == SVGNames::k3Attr) 146 synchronizeK3(); 147 else if (attrName == SVGNames::k4Attr) 148 synchronizeK4(); 149} 150 151AttributeToPropertyTypeMap& SVGFECompositeElement::attributeToPropertyTypeMap() 152{ 153 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ()); 154 return s_attributeToPropertyTypeMap; 155} 156 157void SVGFECompositeElement::fillAttributeToPropertyTypeMap() 158{ 159 AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap(); 160 161 SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap); 162 attributeToPropertyTypeMap.set(SVGNames::inAttr, AnimatedString); 163 attributeToPropertyTypeMap.set(SVGNames::in2Attr, AnimatedString); 164 attributeToPropertyTypeMap.set(SVGNames::operatorAttr, AnimatedEnumeration); 165 attributeToPropertyTypeMap.set(SVGNames::k1Attr, AnimatedNumber); 166 attributeToPropertyTypeMap.set(SVGNames::k2Attr, AnimatedNumber); 167 attributeToPropertyTypeMap.set(SVGNames::k3Attr, AnimatedNumber); 168 attributeToPropertyTypeMap.set(SVGNames::k4Attr, AnimatedNumber); 169} 170 171PassRefPtr<FilterEffect> SVGFECompositeElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) 172{ 173 FilterEffect* input1 = filterBuilder->getEffectById(in1()); 174 FilterEffect* input2 = filterBuilder->getEffectById(in2()); 175 176 if (!input1 || !input2) 177 return 0; 178 179 RefPtr<FilterEffect> effect = FEComposite::create(filter, static_cast<CompositeOperationType>(_operator()), 180 k1(), k2(), k3(), k4()); 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 190#endif // ENABLE(SVG) 191