Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis (at) 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/SVGFEBlendElement.h"
     24 
     25 #include "SVGNames.h"
     26 #include "core/platform/graphics/filters/FilterEffect.h"
     27 #include "core/svg/SVGElementInstance.h"
     28 #include "core/svg/graphics/filters/SVGFilterBuilder.h"
     29 
     30 namespace WebCore {
     31 
     32 // Animated property definitions
     33 DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::inAttr, In1, in1)
     34 DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::in2Attr, In2, in2)
     35 DEFINE_ANIMATED_ENUMERATION(SVGFEBlendElement, SVGNames::modeAttr, Mode, mode, BlendModeType)
     36 
     37 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEBlendElement)
     38     REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
     39     REGISTER_LOCAL_ANIMATED_PROPERTY(in2)
     40     REGISTER_LOCAL_ANIMATED_PROPERTY(mode)
     41     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
     42 END_REGISTER_ANIMATED_PROPERTIES
     43 
     44 inline SVGFEBlendElement::SVGFEBlendElement(const QualifiedName& tagName, Document* document)
     45     : SVGFilterPrimitiveStandardAttributes(tagName, document)
     46     , m_mode(FEBLEND_MODE_NORMAL)
     47 {
     48     ASSERT(hasTagName(SVGNames::feBlendTag));
     49     ScriptWrappable::init(this);
     50     registerAnimatedPropertiesForSVGFEBlendElement();
     51 }
     52 
     53 PassRefPtr<SVGFEBlendElement> SVGFEBlendElement::create(const QualifiedName& tagName, Document* document)
     54 {
     55     return adoptRef(new SVGFEBlendElement(tagName, document));
     56 }
     57 
     58 bool SVGFEBlendElement::isSupportedAttribute(const QualifiedName& attrName)
     59 {
     60     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
     61     if (supportedAttributes.isEmpty()) {
     62         supportedAttributes.add(SVGNames::modeAttr);
     63         supportedAttributes.add(SVGNames::inAttr);
     64         supportedAttributes.add(SVGNames::in2Attr);
     65     }
     66     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
     67 }
     68 
     69 void SVGFEBlendElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
     70 {
     71     if (!isSupportedAttribute(name)) {
     72         SVGFilterPrimitiveStandardAttributes::parseAttribute(name, value);
     73         return;
     74     }
     75 
     76     if (name == SVGNames::modeAttr) {
     77         BlendModeType propertyValue = SVGPropertyTraits<BlendModeType>::fromString(value);
     78         if (propertyValue > 0)
     79             setModeBaseValue(propertyValue);
     80         return;
     81     }
     82 
     83     if (name == SVGNames::inAttr) {
     84         setIn1BaseValue(value);
     85         return;
     86     }
     87 
     88     if (name == SVGNames::in2Attr) {
     89         setIn2BaseValue(value);
     90         return;
     91     }
     92 
     93     ASSERT_NOT_REACHED();
     94 }
     95 
     96 bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
     97 {
     98     FEBlend* blend = static_cast<FEBlend*>(effect);
     99     if (attrName == SVGNames::modeAttr)
    100         return blend->setBlendMode(modeCurrentValue());
    101 
    102     ASSERT_NOT_REACHED();
    103     return false;
    104 }
    105 
    106 void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName)
    107 {
    108     if (!isSupportedAttribute(attrName)) {
    109         SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
    110         return;
    111     }
    112 
    113     SVGElementInstance::InvalidationGuard invalidationGuard(this);
    114 
    115     if (attrName == SVGNames::modeAttr) {
    116         primitiveAttributeChanged(attrName);
    117         return;
    118     }
    119 
    120     if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
    121         invalidate();
    122         return;
    123     }
    124 
    125     ASSERT_NOT_REACHED();
    126 }
    127 
    128 PassRefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
    129 {
    130     FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
    131     FilterEffect* input2 = filterBuilder->getEffectById(in2CurrentValue());
    132 
    133     if (!input1 || !input2)
    134         return 0;
    135 
    136     RefPtr<FilterEffect> effect = FEBlend::create(filter, modeCurrentValue());
    137     FilterEffectVector& inputEffects = effect->inputEffects();
    138     inputEffects.reserveCapacity(2);
    139     inputEffects.append(input1);
    140     inputEffects.append(input2);
    141     return effect.release();
    142 }
    143 
    144 }
    145