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 #include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
     25 
     26 #include "SVGNames.h"
     27 #include "core/platform/graphics/filters/FilterEffect.h"
     28 #include "core/rendering/svg/RenderSVGResourceFilterPrimitive.h"
     29 #include "core/svg/SVGElementInstance.h"
     30 #include "core/svg/SVGLength.h"
     31 
     32 namespace WebCore {
     33 
     34 // Animated property definitions
     35 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::xAttr, X, x)
     36 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::yAttr, Y, y)
     37 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::widthAttr, Width, width)
     38 DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::heightAttr, Height, height)
     39 DEFINE_ANIMATED_STRING(SVGFilterPrimitiveStandardAttributes, SVGNames::resultAttr, Result, result)
     40 
     41 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
     42     REGISTER_LOCAL_ANIMATED_PROPERTY(x)
     43     REGISTER_LOCAL_ANIMATED_PROPERTY(y)
     44     REGISTER_LOCAL_ANIMATED_PROPERTY(width)
     45     REGISTER_LOCAL_ANIMATED_PROPERTY(height)
     46     REGISTER_LOCAL_ANIMATED_PROPERTY(result)
     47     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
     48 END_REGISTER_ANIMATED_PROPERTIES
     49 
     50 SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document* document)
     51     : SVGElement(tagName, document)
     52     , m_x(LengthModeWidth, "0%")
     53     , m_y(LengthModeHeight, "0%")
     54     , m_width(LengthModeWidth, "100%")
     55     , m_height(LengthModeHeight, "100%")
     56 {
     57     // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified.
     58     // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
     59     registerAnimatedPropertiesForSVGFilterPrimitiveStandardAttributes();
     60 }
     61 
     62 bool SVGFilterPrimitiveStandardAttributes::isSupportedAttribute(const QualifiedName& attrName)
     63 {
     64     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
     65     if (supportedAttributes.isEmpty()) {
     66         supportedAttributes.add(SVGNames::xAttr);
     67         supportedAttributes.add(SVGNames::yAttr);
     68         supportedAttributes.add(SVGNames::widthAttr);
     69         supportedAttributes.add(SVGNames::heightAttr);
     70         supportedAttributes.add(SVGNames::resultAttr);
     71     }
     72     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
     73 }
     74 
     75 void SVGFilterPrimitiveStandardAttributes::parseAttribute(const QualifiedName& name, const AtomicString& value)
     76 {
     77     SVGParsingError parseError = NoError;
     78 
     79     if (!isSupportedAttribute(name))
     80         SVGElement::parseAttribute(name, value);
     81     else if (name == SVGNames::xAttr)
     82         setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
     83     else if (name == SVGNames::yAttr)
     84         setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
     85     else if (name == SVGNames::widthAttr)
     86         setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
     87     else if (name == SVGNames::heightAttr)
     88         setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
     89     else if (name == SVGNames::resultAttr)
     90         setResultBaseValue(value);
     91     else
     92         ASSERT_NOT_REACHED();
     93 
     94     reportAttributeParsingError(parseError, name, value);
     95 }
     96 
     97 bool SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect*, const QualifiedName&)
     98 {
     99     // When all filters support this method, it will be changed to a pure virtual method.
    100     ASSERT_NOT_REACHED();
    101     return false;
    102 }
    103 
    104 void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedName& attrName)
    105 {
    106     if (!isSupportedAttribute(attrName)) {
    107         SVGElement::svgAttributeChanged(attrName);
    108         return;
    109     }
    110 
    111     SVGElementInstance::InvalidationGuard invalidationGuard(this);
    112     invalidate();
    113 }
    114 
    115 void SVGFilterPrimitiveStandardAttributes::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
    116 {
    117     SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    118 
    119     if (!changedByParser)
    120         invalidate();
    121 }
    122 
    123 void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(FilterEffect* filterEffect) const
    124 {
    125     ASSERT(filterEffect);
    126     if (!filterEffect)
    127         return;
    128 
    129     if (hasAttribute(SVGNames::xAttr))
    130         filterEffect->setHasX(true);
    131     if (hasAttribute(SVGNames::yAttr))
    132         filterEffect->setHasY(true);
    133     if (hasAttribute(SVGNames::widthAttr))
    134         filterEffect->setHasWidth(true);
    135     if (hasAttribute(SVGNames::heightAttr))
    136         filterEffect->setHasHeight(true);
    137 }
    138 
    139 RenderObject* SVGFilterPrimitiveStandardAttributes::createRenderer(RenderStyle*)
    140 {
    141     return new RenderSVGResourceFilterPrimitive(this);
    142 }
    143 
    144 bool SVGFilterPrimitiveStandardAttributes::rendererIsNeeded(const NodeRenderingContext& context)
    145 {
    146     if (parentNode() && (parentNode()->hasTagName(SVGNames::filterTag)))
    147         return SVGElement::rendererIsNeeded(context);
    148 
    149     return false;
    150 }
    151 
    152 void SVGFilterPrimitiveStandardAttributes::primitiveAttributeChanged(const QualifiedName& attribute)
    153 {
    154     if (RenderObject* primitiveRenderer = renderer())
    155         static_cast<RenderSVGResourceFilterPrimitive*>(primitiveRenderer)->primitiveAttributeChanged(attribute);
    156 }
    157 
    158 void invalidateFilterPrimitiveParent(SVGElement* element)
    159 {
    160     if (!element)
    161         return;
    162 
    163     ContainerNode* parent = element->parentNode();
    164 
    165     if (!parent)
    166         return;
    167 
    168     RenderObject* renderer = parent->renderer();
    169     if (!renderer || !renderer->isSVGResourceFilterPrimitive())
    170         return;
    171 
    172     RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
    173 }
    174 
    175 }
    176