Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2009 Dirk Schulze <krit (at) webkit.org>
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 
     22 #if ENABLE(SVG) && ENABLE(FILTERS)
     23 #include "SVGFEMorphologyElement.h"
     24 
     25 #include "Attribute.h"
     26 #include "FilterEffect.h"
     27 #include "SVGFilterBuilder.h"
     28 #include "SVGNames.h"
     29 #include "SVGParserUtilities.h"
     30 
     31 namespace WebCore {
     32 
     33 // Animated property definitions
     34 DEFINE_ANIMATED_STRING(SVGFEMorphologyElement, SVGNames::inAttr, In1, in1)
     35 DEFINE_ANIMATED_ENUMERATION(SVGFEMorphologyElement, SVGNames::operatorAttr, _operator, _operator)
     36 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusXIdentifier(), RadiusX, radiusX)
     37 DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusYIdentifier(), RadiusY, radiusY)
     38 
     39 inline SVGFEMorphologyElement::SVGFEMorphologyElement(const QualifiedName& tagName, Document* document)
     40     : SVGFilterPrimitiveStandardAttributes(tagName, document)
     41     , m__operator(FEMORPHOLOGY_OPERATOR_ERODE)
     42 {
     43 }
     44 
     45 PassRefPtr<SVGFEMorphologyElement> SVGFEMorphologyElement::create(const QualifiedName& tagName, Document* document)
     46 {
     47     return adoptRef(new SVGFEMorphologyElement(tagName, document));
     48 }
     49 
     50 const AtomicString& SVGFEMorphologyElement::radiusXIdentifier()
     51 {
     52     DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusX"));
     53     return s_identifier;
     54 }
     55 
     56 const AtomicString& SVGFEMorphologyElement::radiusYIdentifier()
     57 {
     58     DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusY"));
     59     return s_identifier;
     60 }
     61 
     62 void SVGFEMorphologyElement::setRadius(float x, float y)
     63 {
     64     setRadiusXBaseValue(x);
     65     setRadiusYBaseValue(y);
     66     invalidate();
     67 }
     68 
     69 void SVGFEMorphologyElement::parseMappedAttribute(Attribute* attr)
     70 {
     71     const String& value = attr->value();
     72     if (attr->name() == SVGNames::operatorAttr) {
     73         if (value == "erode")
     74             set_operatorBaseValue(FEMORPHOLOGY_OPERATOR_ERODE);
     75         else if (value == "dilate")
     76             set_operatorBaseValue(FEMORPHOLOGY_OPERATOR_DILATE);
     77     } else if (attr->name() == SVGNames::inAttr)
     78         setIn1BaseValue(value);
     79     else if (attr->name() == SVGNames::radiusAttr) {
     80         float x, y;
     81         if (parseNumberOptionalNumber(value, x, y)) {
     82             setRadiusXBaseValue(x);
     83             setRadiusYBaseValue(y);
     84         }
     85     } else
     86         SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
     87 }
     88 
     89 bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
     90 {
     91     FEMorphology* morphology = static_cast<FEMorphology*>(effect);
     92     if (attrName == SVGNames::operatorAttr)
     93         return morphology->setMorphologyOperator(static_cast<MorphologyOperatorType>(_operator()));
     94     if (attrName == SVGNames::radiusAttr)
     95         return (morphology->setRadiusX(radiusX()) || morphology->setRadiusY(radiusY()));
     96 
     97     ASSERT_NOT_REACHED();
     98     return false;
     99 }
    100 
    101 void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName)
    102 {
    103     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
    104 
    105     if (attrName == SVGNames::operatorAttr
    106         || attrName == SVGNames::radiusAttr)
    107         primitiveAttributeChanged(attrName);
    108 
    109     if (attrName == SVGNames::inAttr)
    110         invalidate();
    111 }
    112 
    113 void SVGFEMorphologyElement::synchronizeProperty(const QualifiedName& attrName)
    114 {
    115     SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
    116 
    117     if (attrName == anyQName()) {
    118         synchronize_operator();
    119         synchronizeIn1();
    120         synchronizeRadiusX();
    121         synchronizeRadiusY();
    122         return;
    123     }
    124 
    125     if (attrName == SVGNames::operatorAttr)
    126         synchronize_operator();
    127     else if (attrName == SVGNames::inAttr)
    128         synchronizeIn1();
    129     else if (attrName == SVGNames::radiusAttr) {
    130         synchronizeRadiusX();
    131         synchronizeRadiusY();
    132     }
    133 }
    134 
    135 AttributeToPropertyTypeMap& SVGFEMorphologyElement::attributeToPropertyTypeMap()
    136 {
    137     DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
    138     return s_attributeToPropertyTypeMap;
    139 }
    140 
    141 void SVGFEMorphologyElement::fillAttributeToPropertyTypeMap()
    142 {
    143     AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap();
    144 
    145     SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
    146     attributeToPropertyTypeMap.set(SVGNames::inAttr, AnimatedString);
    147     attributeToPropertyTypeMap.set(SVGNames::operatorAttr, AnimatedEnumeration);
    148     attributeToPropertyTypeMap.set(SVGNames::radiusAttr, AnimatedNumberOptionalNumber);
    149 }
    150 
    151 PassRefPtr<FilterEffect> SVGFEMorphologyElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
    152 {
    153     FilterEffect* input1 = filterBuilder->getEffectById(in1());
    154     float xRadius = radiusX();
    155     float yRadius = radiusY();
    156 
    157     if (!input1)
    158         return 0;
    159 
    160     if (xRadius < 0 || yRadius < 0)
    161         return 0;
    162 
    163     RefPtr<FilterEffect> effect = FEMorphology::create(filter, static_cast<MorphologyOperatorType>(_operator()), xRadius, yRadius);
    164     effect->inputEffects().append(input1);
    165     return effect.release();
    166 }
    167 
    168 } // namespace WebCore
    169 
    170 #endif // ENABLE(SVG)
    171