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) 2006 Samuel Weinig <sam.weinig@gmail.com> 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 */ 23 24#include "config.h" 25 26#include "core/svg/SVGFilterElement.h" 27 28#include "core/XLinkNames.h" 29#include "core/rendering/svg/RenderSVGResourceFilter.h" 30#include "core/svg/SVGParserUtilities.h" 31 32namespace blink { 33 34inline SVGFilterElement::SVGFilterElement(Document& document) 35 : SVGElement(SVGNames::filterTag, document) 36 , SVGURIReference(this) 37 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths)) 38 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths)) 39 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths)) 40 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths)) 41 , m_filterUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::filterUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)) 42 , m_primitiveUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)) 43 , m_filterRes(SVGAnimatedIntegerOptionalInteger::create(this, SVGNames::filterResAttr)) 44{ 45 // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. 46 // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. 47 m_x->setDefaultValueAsString("-10%"); 48 m_y->setDefaultValueAsString("-10%"); 49 m_width->setDefaultValueAsString("120%"); 50 m_height->setDefaultValueAsString("120%"); 51 52 addToPropertyMap(m_x); 53 addToPropertyMap(m_y); 54 addToPropertyMap(m_width); 55 addToPropertyMap(m_height); 56 addToPropertyMap(m_filterUnits); 57 addToPropertyMap(m_primitiveUnits); 58 addToPropertyMap(m_filterRes); 59} 60 61DEFINE_NODE_FACTORY(SVGFilterElement) 62 63void SVGFilterElement::trace(Visitor* visitor) 64{ 65#if ENABLE(OILPAN) 66 visitor->trace(m_clientsToAdd); 67#endif 68 SVGElement::trace(visitor); 69} 70 71void SVGFilterElement::setFilterRes(unsigned x, unsigned y) 72{ 73 filterResX()->baseValue()->setValue(x); 74 filterResY()->baseValue()->setValue(y); 75 76 invalidateSVGAttributes(); 77 svgAttributeChanged(SVGNames::filterResAttr); 78} 79 80bool SVGFilterElement::isSupportedAttribute(const QualifiedName& attrName) 81{ 82 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 83 if (supportedAttributes.isEmpty()) { 84 SVGURIReference::addSupportedAttributes(supportedAttributes); 85 supportedAttributes.add(SVGNames::filterUnitsAttr); 86 supportedAttributes.add(SVGNames::primitiveUnitsAttr); 87 supportedAttributes.add(SVGNames::xAttr); 88 supportedAttributes.add(SVGNames::yAttr); 89 supportedAttributes.add(SVGNames::widthAttr); 90 supportedAttributes.add(SVGNames::heightAttr); 91 supportedAttributes.add(SVGNames::filterResAttr); 92 } 93 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 94} 95 96void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 97{ 98 parseAttributeNew(name, value); 99} 100 101void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName) 102{ 103 if (!isSupportedAttribute(attrName)) { 104 SVGElement::svgAttributeChanged(attrName); 105 return; 106 } 107 108 SVGElement::InvalidationGuard invalidationGuard(this); 109 110 if (attrName == SVGNames::xAttr 111 || attrName == SVGNames::yAttr 112 || attrName == SVGNames::widthAttr 113 || attrName == SVGNames::heightAttr) 114 updateRelativeLengthsInformation(); 115 116 RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer()); 117 if (renderer) 118 renderer->invalidateCacheAndMarkForLayout(); 119} 120 121void SVGFilterElement::childrenChanged(const ChildrenChange& change) 122{ 123 SVGElement::childrenChanged(change); 124 125 if (change.byParser) 126 return; 127 128 if (RenderObject* object = renderer()) 129 object->setNeedsLayoutAndFullPaintInvalidation(); 130} 131 132RenderObject* SVGFilterElement::createRenderer(RenderStyle*) 133{ 134 RenderSVGResourceFilter* renderer = new RenderSVGResourceFilter(this); 135 136 WillBeHeapHashSet<RefPtrWillBeMember<Node> >::iterator layerEnd = m_clientsToAdd.end(); 137 for (WillBeHeapHashSet<RefPtrWillBeMember<Node> >::iterator it = m_clientsToAdd.begin(); it != layerEnd; ++it) 138 renderer->addClientRenderLayer(it->get()); 139 m_clientsToAdd.clear(); 140 141 return renderer; 142} 143 144bool SVGFilterElement::selfHasRelativeLengths() const 145{ 146 return m_x->currentValue()->isRelative() 147 || m_y->currentValue()->isRelative() 148 || m_width->currentValue()->isRelative() 149 || m_height->currentValue()->isRelative(); 150} 151 152void SVGFilterElement::addClient(Node* client) 153{ 154 ASSERT(client); 155 m_clientsToAdd.add(client); 156} 157 158void SVGFilterElement::removeClient(Node* client) 159{ 160 ASSERT(client); 161 m_clientsToAdd.remove(client); 162} 163 164} // namespace blink 165