Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2006 Oliver Hunt <oliver (at) nerget.com>
      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 "SVGFEDisplacementMapElement.h"
     24 
     25 #include "Attribute.h"
     26 #include "FilterEffect.h"
     27 #include "SVGFilterBuilder.h"
     28 #include "SVGNames.h"
     29 
     30 namespace WebCore {
     31 
     32 // Animated property definitions
     33 DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::inAttr, In1, in1)
     34 DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::in2Attr, In2, in2)
     35 DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::xChannelSelectorAttr, XChannelSelector, xChannelSelector)
     36 DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::yChannelSelectorAttr, YChannelSelector, yChannelSelector)
     37 DEFINE_ANIMATED_NUMBER(SVGFEDisplacementMapElement, SVGNames::scaleAttr, Scale, scale)
     38 
     39 inline SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(const QualifiedName& tagName, Document* document)
     40     : SVGFilterPrimitiveStandardAttributes(tagName, document)
     41     , m_xChannelSelector(CHANNEL_A)
     42     , m_yChannelSelector(CHANNEL_A)
     43 {
     44 }
     45 
     46 PassRefPtr<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(const QualifiedName& tagName, Document* document)
     47 {
     48     return adoptRef(new SVGFEDisplacementMapElement(tagName, document));
     49 }
     50 
     51 ChannelSelectorType SVGFEDisplacementMapElement::stringToChannel(const String& key)
     52 {
     53     if (key == "R")
     54         return CHANNEL_R;
     55     if (key == "G")
     56         return CHANNEL_G;
     57     if (key == "B")
     58         return CHANNEL_B;
     59     if (key == "A")
     60         return CHANNEL_A;
     61 
     62     return CHANNEL_UNKNOWN;
     63 }
     64 
     65 void SVGFEDisplacementMapElement::parseMappedAttribute(Attribute* attr)
     66 {
     67     const String& value = attr->value();
     68     if (attr->name() == SVGNames::xChannelSelectorAttr)
     69         setXChannelSelectorBaseValue(stringToChannel(value));
     70     else if (attr->name() == SVGNames::yChannelSelectorAttr)
     71         setYChannelSelectorBaseValue(stringToChannel(value));
     72     else if (attr->name() == SVGNames::inAttr)
     73         setIn1BaseValue(value);
     74     else if (attr->name() == SVGNames::in2Attr)
     75         setIn2BaseValue(value);
     76     else if (attr->name() == SVGNames::scaleAttr)
     77         setScaleBaseValue(value.toFloat());
     78     else
     79         SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
     80 }
     81 
     82 bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
     83 {
     84     FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect);
     85     if (attrName == SVGNames::xChannelSelectorAttr)
     86         return displacementMap->setXChannelSelector(static_cast<ChannelSelectorType>(xChannelSelector()));
     87     if (attrName == SVGNames::yChannelSelectorAttr)
     88         return displacementMap->setYChannelSelector(static_cast<ChannelSelectorType>(yChannelSelector()));
     89     if (attrName == SVGNames::scaleAttr)
     90         return displacementMap->setScale(scale());
     91 
     92     ASSERT_NOT_REACHED();
     93     return false;
     94 }
     95 
     96 void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName)
     97 {
     98     SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
     99 
    100     if (attrName == SVGNames::xChannelSelectorAttr) {
    101         ChannelSelectorType selector = static_cast<ChannelSelectorType>(xChannelSelector());
    102         if (CHANNEL_UNKNOWN > selector || selector > CHANNEL_A)
    103             setXChannelSelectorBaseValue(CHANNEL_UNKNOWN);
    104         primitiveAttributeChanged(attrName);
    105     } else if (attrName == SVGNames::yChannelSelectorAttr) {
    106         ChannelSelectorType selector = static_cast<ChannelSelectorType>(yChannelSelector());
    107         if (CHANNEL_UNKNOWN > selector || selector > CHANNEL_A)
    108             setYChannelSelectorBaseValue(CHANNEL_UNKNOWN);
    109         primitiveAttributeChanged(attrName);
    110     } else if (attrName == SVGNames::scaleAttr)
    111         primitiveAttributeChanged(attrName);
    112     else if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr)
    113         invalidate();
    114 }
    115 
    116 void SVGFEDisplacementMapElement::synchronizeProperty(const QualifiedName& attrName)
    117 {
    118     SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
    119 
    120     if (attrName == anyQName()) {
    121         synchronizeXChannelSelector();
    122         synchronizeYChannelSelector();
    123         synchronizeIn1();
    124         synchronizeIn2();
    125         synchronizeScale();
    126         return;
    127     }
    128 
    129     if (attrName == SVGNames::xChannelSelectorAttr)
    130         synchronizeXChannelSelector();
    131     else if (attrName == SVGNames::yChannelSelectorAttr)
    132         synchronizeYChannelSelector();
    133     else if (attrName == SVGNames::inAttr)
    134         synchronizeIn1();
    135     else if (attrName == SVGNames::in2Attr)
    136         synchronizeIn2();
    137     else if (attrName == SVGNames::scaleAttr)
    138         synchronizeScale();
    139 }
    140 
    141 AttributeToPropertyTypeMap& SVGFEDisplacementMapElement::attributeToPropertyTypeMap()
    142 {
    143     DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
    144     return s_attributeToPropertyTypeMap;
    145 }
    146 
    147 void SVGFEDisplacementMapElement::fillAttributeToPropertyTypeMap()
    148 {
    149     AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap();
    150 
    151     SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
    152     attributeToPropertyTypeMap.set(SVGNames::inAttr, AnimatedString);
    153     attributeToPropertyTypeMap.set(SVGNames::in2Attr, AnimatedString);
    154     attributeToPropertyTypeMap.set(SVGNames::xChannelSelectorAttr, AnimatedEnumeration);
    155     attributeToPropertyTypeMap.set(SVGNames::yChannelSelectorAttr, AnimatedEnumeration);
    156     attributeToPropertyTypeMap.set(SVGNames::scaleAttr, AnimatedNumber);
    157 }
    158 
    159 PassRefPtr<FilterEffect> SVGFEDisplacementMapElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
    160 {
    161     FilterEffect* input1 = filterBuilder->getEffectById(in1());
    162     FilterEffect* input2 = filterBuilder->getEffectById(in2());
    163 
    164     if (!input1 || !input2)
    165         return 0;
    166 
    167     RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, static_cast<ChannelSelectorType>(xChannelSelector()),
    168                                                                 static_cast<ChannelSelectorType>(yChannelSelector()), scale());
    169     FilterEffectVector& inputEffects = effect->inputEffects();
    170     inputEffects.reserveCapacity(2);
    171     inputEffects.append(input1);
    172     inputEffects.append(input2);
    173     return effect.release();
    174 }
    175 
    176 }
    177 
    178 #endif // ENABLE(SVG)
    179 
    180 // vim:ts=4:noet
    181