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