Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis (at) kde.org>
      4  * Copyright (C) 2009 Dirk Schulze <krit (at) webkit.org>
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Library General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Library General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Library General Public License
     17  * along with this library; see the file COPYING.LIB.  If not, write to
     18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  * Boston, MA 02110-1301, USA.
     20  */
     21 
     22 #include "config.h"
     23 
     24 #if ENABLE(SVG) && ENABLE(FILTERS)
     25 #include "SVGFilterPrimitiveStandardAttributes.h"
     26 
     27 #include "Attribute.h"
     28 #include "FilterEffect.h"
     29 #include "RenderSVGResourceFilterPrimitive.h"
     30 #include "SVGFilterBuilder.h"
     31 #include "SVGLength.h"
     32 #include "SVGNames.h"
     33 #include "SVGStyledElement.h"
     34 #include "SVGUnitTypes.h"
     35 
     36 namespace WebCore {
     37 
     38 // Animated property definitions
     39 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::xAttr, X, x)
     40 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::yAttr, Y, y)
     41 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::widthAttr, Width, width)
     42 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::heightAttr, Height, height)
     43 DEFINE_ANIMATED_STRING(SVGFilterPrimitiveStandardAttributes, SVGNames::resultAttr, Result, result)
     44 
     45 SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document* document)
     46     : SVGStyledElement(tagName, document)
     47     , m_x(LengthModeWidth, "0%")
     48     , m_y(LengthModeHeight, "0%")
     49     , m_width(LengthModeWidth, "100%")
     50     , m_height(LengthModeHeight, "100%")
     51 {
     52     // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified.
     53     // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
     54 }
     55 
     56 void SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(Attribute* attr)
     57 {
     58     const AtomicString& value = attr->value();
     59     if (attr->name() == SVGNames::xAttr)
     60         setXBaseValue(SVGLength(LengthModeWidth, value));
     61     else if (attr->name() == SVGNames::yAttr)
     62         setYBaseValue(SVGLength(LengthModeHeight, value));
     63     else if (attr->name() == SVGNames::widthAttr)
     64         setWidthBaseValue(SVGLength(LengthModeWidth, value));
     65     else if (attr->name() == SVGNames::heightAttr)
     66         setHeightBaseValue(SVGLength(LengthModeHeight, value));
     67     else if (attr->name() == SVGNames::resultAttr)
     68         setResultBaseValue(value);
     69     else
     70         return SVGStyledElement::parseMappedAttribute(attr);
     71 }
     72 
     73 bool SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect*, const QualifiedName&)
     74 {
     75     // When all filters support this method, it will be changed to a pure virtual method.
     76     ASSERT_NOT_REACHED();
     77     return false;
     78 }
     79 
     80 void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedName& attrName)
     81 {
     82     SVGStyledElement::svgAttributeChanged(attrName);
     83 
     84     if (attrName == SVGNames::xAttr
     85         || attrName == SVGNames::yAttr
     86         || attrName == SVGNames::widthAttr
     87         || attrName == SVGNames::heightAttr
     88         || attrName == SVGNames::resultAttr)
     89         invalidate();
     90 }
     91 
     92 void SVGFilterPrimitiveStandardAttributes::synchronizeProperty(const QualifiedName& attrName)
     93 {
     94     SVGStyledElement::synchronizeProperty(attrName);
     95 
     96     if (attrName == anyQName()) {
     97         synchronizeX();
     98         synchronizeY();
     99         synchronizeWidth();
    100         synchronizeHeight();
    101         synchronizeResult();
    102         return;
    103     }
    104 
    105     if (attrName == SVGNames::xAttr)
    106         synchronizeX();
    107     else if (attrName == SVGNames::yAttr)
    108         synchronizeY();
    109     else if (attrName == SVGNames::widthAttr)
    110         synchronizeWidth();
    111     else if (attrName == SVGNames::heightAttr)
    112         synchronizeHeight();
    113     else if (attrName == SVGNames::resultAttr)
    114         synchronizeResult();
    115 }
    116 
    117 void SVGFilterPrimitiveStandardAttributes::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
    118 {
    119     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    120 
    121     if (!changedByParser)
    122         invalidate();
    123 }
    124 
    125 void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(bool primitiveBoundingBoxMode, FilterEffect* filterEffect) const
    126 {
    127     ASSERT(filterEffect);
    128     if (!filterEffect)
    129         return;
    130 
    131     if (this->hasAttribute(SVGNames::xAttr))
    132         filterEffect->setHasX(true);
    133     if (this->hasAttribute(SVGNames::yAttr))
    134         filterEffect->setHasY(true);
    135     if (this->hasAttribute(SVGNames::widthAttr))
    136         filterEffect->setHasWidth(true);
    137     if (this->hasAttribute(SVGNames::heightAttr))
    138         filterEffect->setHasHeight(true);
    139 
    140     FloatRect effectBBox;
    141     if (primitiveBoundingBoxMode)
    142         effectBBox = FloatRect(x().valueAsPercentage(),
    143                                y().valueAsPercentage(),
    144                                width().valueAsPercentage(),
    145                                height().valueAsPercentage());
    146     else
    147         effectBBox = FloatRect(x().value(this),
    148                                y().value(this),
    149                                width().value(this),
    150                                height().value(this));
    151 
    152     filterEffect->setEffectBoundaries(effectBBox);
    153 }
    154 
    155 void SVGFilterPrimitiveStandardAttributes::fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap& attributeToPropertyTypeMap)
    156 {
    157     SVGStyledElement::fillPassedAttributeToPropertyTypeMap(attributeToPropertyTypeMap);
    158 
    159     attributeToPropertyTypeMap.set(SVGNames::xAttr, AnimatedLength);
    160     attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedLength);
    161     attributeToPropertyTypeMap.set(SVGNames::widthAttr, AnimatedLength);
    162     attributeToPropertyTypeMap.set(SVGNames::heightAttr, AnimatedLength);
    163     attributeToPropertyTypeMap.set(SVGNames::resultAttr, AnimatedString);
    164 }
    165 
    166 RenderObject* SVGFilterPrimitiveStandardAttributes::createRenderer(RenderArena* arena, RenderStyle*)
    167 {
    168     return new (arena) RenderSVGResourceFilterPrimitive(this);
    169 }
    170 
    171 bool SVGFilterPrimitiveStandardAttributes::rendererIsNeeded(RenderStyle* style)
    172 {
    173     if (parentNode() && (parentNode()->hasTagName(SVGNames::filterTag)))
    174         return SVGStyledElement::rendererIsNeeded(style);
    175 
    176     return false;
    177 }
    178 
    179 }
    180 
    181 #endif // ENABLE(SVG)
    182