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 #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 
     31 namespace WebCore {
     32 
     33 // Animated property definitions
     34 DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::inAttr, In1, in1)
     35 DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::in2Attr, In2, in2)
     36 DEFINE_ANIMATED_ENUMERATION(SVGFECompositeElement, SVGNames::operatorAttr, _operator, _operator)
     37 DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k1Attr, K1, k1)
     38 DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k2Attr, K2, k2)
     39 DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k3Attr, K3, k3)
     40 DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k4Attr, K4, k4)
     41 
     42 inline SVGFECompositeElement::SVGFECompositeElement(const QualifiedName& tagName, Document* document)
     43     : SVGFilterPrimitiveStandardAttributes(tagName, document)
     44     , m__operator(FECOMPOSITE_OPERATOR_OVER)
     45 {
     46 }
     47 
     48 PassRefPtr<SVGFECompositeElement> SVGFECompositeElement::create(const QualifiedName& tagName, Document* document)
     49 {
     50     return adoptRef(new SVGFECompositeElement(tagName, document));
     51 }
     52 
     53 void 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 
     85 bool 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 
    104 void 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 
    120 void 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 
    151 AttributeToPropertyTypeMap& SVGFECompositeElement::attributeToPropertyTypeMap()
    152 {
    153     DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
    154     return s_attributeToPropertyTypeMap;
    155 }
    156 
    157 void 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 
    171 PassRefPtr<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