2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
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.
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.
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.
23 #include "core/svg/SVGFEBlendElement.h"
25 #include "core/SVGNames.h"
26 #include "platform/graphics/filters/FEBlend.h"
27 #include "platform/graphics/filters/FilterEffect.h"
28 #include "core/svg/graphics/filters/SVGFilterBuilder.h"
32 static WebBlendMode toWebBlendMode(SVGFEBlendElement::Mode mode)
34 #define MAP_BLEND_MODE(MODENAME) \
35 case SVGFEBlendElement::Mode##MODENAME: \
36 return WebBlendMode##MODENAME
39 MAP_BLEND_MODE(Normal);
40 MAP_BLEND_MODE(Multiply);
41 MAP_BLEND_MODE(Screen);
42 MAP_BLEND_MODE(Darken);
43 MAP_BLEND_MODE(Lighten);
44 MAP_BLEND_MODE(Overlay);
45 MAP_BLEND_MODE(ColorDodge);
46 MAP_BLEND_MODE(ColorBurn);
47 MAP_BLEND_MODE(HardLight);
48 MAP_BLEND_MODE(SoftLight);
49 MAP_BLEND_MODE(Difference);
50 MAP_BLEND_MODE(Exclusion);
52 MAP_BLEND_MODE(Saturation);
53 MAP_BLEND_MODE(Color);
54 MAP_BLEND_MODE(Luminosity);
57 return WebBlendModeNormal;
62 template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGFEBlendElement::Mode>()
64 DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
65 if (entries.isEmpty()) {
66 entries.append(std::make_pair(SVGFEBlendElement::ModeNormal, "normal"));
67 entries.append(std::make_pair(SVGFEBlendElement::ModeMultiply, "multiply"));
68 entries.append(std::make_pair(SVGFEBlendElement::ModeScreen, "screen"));
69 entries.append(std::make_pair(SVGFEBlendElement::ModeDarken, "darken"));
70 entries.append(std::make_pair(SVGFEBlendElement::ModeLighten, "lighten"));
71 entries.append(std::make_pair(SVGFEBlendElement::ModeOverlay, "overlay"));
72 entries.append(std::make_pair(SVGFEBlendElement::ModeColorDodge, "color-dodge"));
73 entries.append(std::make_pair(SVGFEBlendElement::ModeColorBurn, "color-burn"));
74 entries.append(std::make_pair(SVGFEBlendElement::ModeHardLight, "hard-light"));
75 entries.append(std::make_pair(SVGFEBlendElement::ModeSoftLight, "soft-light"));
76 entries.append(std::make_pair(SVGFEBlendElement::ModeDifference, "difference"));
77 entries.append(std::make_pair(SVGFEBlendElement::ModeExclusion, "exclusion"));
78 entries.append(std::make_pair(SVGFEBlendElement::ModeHue, "hue"));
79 entries.append(std::make_pair(SVGFEBlendElement::ModeSaturation, "saturation"));
80 entries.append(std::make_pair(SVGFEBlendElement::ModeColor, "color"));
81 entries.append(std::make_pair(SVGFEBlendElement::ModeLuminosity, "luminosity"));
86 template<> unsigned short getMaxExposedEnumValue<SVGFEBlendElement::Mode>()
88 return SVGFEBlendElement::ModeLighten;
91 inline SVGFEBlendElement::SVGFEBlendElement(Document& document)
92 : SVGFilterPrimitiveStandardAttributes(SVGNames::feBlendTag, document)
93 , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
94 , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
95 , m_mode(SVGAnimatedEnumeration<Mode>::create(this, SVGNames::modeAttr, SVGFEBlendElement::ModeNormal))
97 addToPropertyMap(m_in1);
98 addToPropertyMap(m_in2);
99 addToPropertyMap(m_mode);
102 DEFINE_NODE_FACTORY(SVGFEBlendElement)
104 bool SVGFEBlendElement::isSupportedAttribute(const QualifiedName& attrName)
106 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
107 if (supportedAttributes.isEmpty()) {
108 supportedAttributes.add(SVGNames::modeAttr);
109 supportedAttributes.add(SVGNames::inAttr);
110 supportedAttributes.add(SVGNames::in2Attr);
112 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
115 void SVGFEBlendElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
117 parseAttributeNew(name, value);
120 bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
122 FEBlend* blend = static_cast<FEBlend*>(effect);
123 if (attrName == SVGNames::modeAttr)
124 return blend->setBlendMode(toWebBlendMode(m_mode->currentValue()->enumValue()));
126 ASSERT_NOT_REACHED();
130 void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName)
132 if (!isSupportedAttribute(attrName)) {
133 SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
137 SVGElement::InvalidationGuard invalidationGuard(this);
139 if (attrName == SVGNames::modeAttr) {
140 primitiveAttributeChanged(attrName);
144 if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
149 ASSERT_NOT_REACHED();
152 PassRefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
154 FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
155 FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
157 if (!input1 || !input2)
160 RefPtr<FilterEffect> effect = FEBlend::create(filter, toWebBlendMode(m_mode->currentValue()->enumValue()));
161 FilterEffectVector& inputEffects = effect->inputEffects();
162 inputEffects.reserveCapacity(2);
163 inputEffects.append(input1);
164 inputEffects.append(input2);
165 return effect.release();