1/* 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 4 * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22#include "config.h" 23 24#if ENABLE(FILTERS) 25#include "SVGFEBlendElement.h" 26 27#include "Attribute.h" 28#include "FilterEffect.h" 29#include "SVGElementInstance.h" 30#include "SVGFilterBuilder.h" 31#include "SVGNames.h" 32#include <wtf/NeverDestroyed.h> 33 34namespace WebCore { 35 36// Animated property definitions 37DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::inAttr, In1, in1) 38DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::in2Attr, In2, in2) 39DEFINE_ANIMATED_ENUMERATION(SVGFEBlendElement, SVGNames::modeAttr, Mode, mode, BlendMode) 40 41BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEBlendElement) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(in1) 43 REGISTER_LOCAL_ANIMATED_PROPERTY(in2) 44 REGISTER_LOCAL_ANIMATED_PROPERTY(mode) 45 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes) 46END_REGISTER_ANIMATED_PROPERTIES 47 48inline SVGFEBlendElement::SVGFEBlendElement(const QualifiedName& tagName, Document& document) 49 : SVGFilterPrimitiveStandardAttributes(tagName, document) 50 , m_mode(BlendModeNormal) 51{ 52 ASSERT(hasTagName(SVGNames::feBlendTag)); 53 registerAnimatedPropertiesForSVGFEBlendElement(); 54} 55 56PassRefPtr<SVGFEBlendElement> SVGFEBlendElement::create(const QualifiedName& tagName, Document& document) 57{ 58 return adoptRef(new SVGFEBlendElement(tagName, document)); 59} 60 61bool SVGFEBlendElement::isSupportedAttribute(const QualifiedName& attrName) 62{ 63 static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; 64 if (supportedAttributes.get().isEmpty()) { 65 supportedAttributes.get().add(SVGNames::modeAttr); 66 supportedAttributes.get().add(SVGNames::inAttr); 67 supportedAttributes.get().add(SVGNames::in2Attr); 68 } 69 return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); 70} 71 72void SVGFEBlendElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 73{ 74 if (!isSupportedAttribute(name)) { 75 SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value); 76 return; 77 } 78 79 if (name == SVGNames::modeAttr) { 80 BlendMode mode = BlendModeNormal; 81 if (parseBlendMode(value, mode)) 82 setModeBaseValue(mode); 83 return; 84 } 85 86 if (name == SVGNames::inAttr) { 87 setIn1BaseValue(value); 88 return; 89 } 90 91 if (name == SVGNames::in2Attr) { 92 setIn2BaseValue(value); 93 return; 94 } 95 96 ASSERT_NOT_REACHED(); 97} 98 99bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName) 100{ 101 FEBlend* blend = static_cast<FEBlend*>(effect); 102 if (attrName == SVGNames::modeAttr) 103 return blend->setBlendMode(mode()); 104 105 ASSERT_NOT_REACHED(); 106 return false; 107} 108 109void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName) 110{ 111 if (!isSupportedAttribute(attrName)) { 112 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName); 113 return; 114 } 115 116 SVGElementInstance::InvalidationGuard invalidationGuard(this); 117 118 if (attrName == SVGNames::modeAttr) { 119 primitiveAttributeChanged(attrName); 120 return; 121 } 122 123 if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) { 124 invalidate(); 125 return; 126 } 127 128 ASSERT_NOT_REACHED(); 129} 130 131PassRefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilder, Filter* filter) 132{ 133 FilterEffect* input1 = filterBuilder->getEffectById(in1()); 134 FilterEffect* input2 = filterBuilder->getEffectById(in2()); 135 136 if (!input1 || !input2) 137 return 0; 138 139 RefPtr<FilterEffect> effect = FEBlend::create(filter, mode()); 140 FilterEffectVector& inputEffects = effect->inputEffects(); 141 inputEffects.reserveCapacity(2); 142 inputEffects.append(input1); 143 inputEffects.append(input2); 144 return effect.release(); 145} 146 147} 148 149#endif 150