1/* 2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> 4 * Copyright (C) 2005 Alexander Kellett <lypanov@kde.org> 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) Research In Motion Limited 2009-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/SVGMaskElement.h" 27 28#include "core/rendering/svg/RenderSVGResourceMasker.h" 29 30namespace blink { 31 32inline SVGMaskElement::SVGMaskElement(Document& document) 33 : SVGElement(SVGNames::maskTag, document) 34 , SVGTests(this) 35 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths)) 36 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths)) 37 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths)) 38 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths)) 39 , m_maskUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)) 40 , m_maskContentUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)) 41{ 42 // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. 43 m_x->setDefaultValueAsString("-10%"); 44 m_y->setDefaultValueAsString("-10%"); 45 46 // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. 47 m_width->setDefaultValueAsString("120%"); 48 m_height->setDefaultValueAsString("120%"); 49 50 addToPropertyMap(m_x); 51 addToPropertyMap(m_y); 52 addToPropertyMap(m_width); 53 addToPropertyMap(m_height); 54 addToPropertyMap(m_maskUnits); 55 addToPropertyMap(m_maskContentUnits); 56} 57 58DEFINE_NODE_FACTORY(SVGMaskElement) 59 60bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName) 61{ 62 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 63 if (supportedAttributes.isEmpty()) { 64 SVGTests::addSupportedAttributes(supportedAttributes); 65 supportedAttributes.add(SVGNames::maskUnitsAttr); 66 supportedAttributes.add(SVGNames::maskContentUnitsAttr); 67 supportedAttributes.add(SVGNames::xAttr); 68 supportedAttributes.add(SVGNames::yAttr); 69 supportedAttributes.add(SVGNames::widthAttr); 70 supportedAttributes.add(SVGNames::heightAttr); 71 } 72 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 73} 74 75void SVGMaskElement::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::maskUnitsAttr) 82 m_maskUnits->setBaseValueAsString(value, parseError); 83 else if (name == SVGNames::maskContentUnitsAttr) 84 m_maskContentUnits->setBaseValueAsString(value, parseError); 85 else if (name == SVGNames::xAttr) 86 m_x->setBaseValueAsString(value, parseError); 87 else if (name == SVGNames::yAttr) 88 m_y->setBaseValueAsString(value, parseError); 89 else if (name == SVGNames::widthAttr) 90 m_width->setBaseValueAsString(value, parseError); 91 else if (name == SVGNames::heightAttr) 92 m_height->setBaseValueAsString(value, parseError); 93 else if (SVGTests::parseAttribute(name, value)) { 94 } else 95 ASSERT_NOT_REACHED(); 96 97 reportAttributeParsingError(parseError, name, value); 98} 99 100void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName) 101{ 102 if (!isSupportedAttribute(attrName)) { 103 SVGElement::svgAttributeChanged(attrName); 104 return; 105 } 106 107 SVGElement::InvalidationGuard invalidationGuard(this); 108 109 if (attrName == SVGNames::xAttr 110 || attrName == SVGNames::yAttr 111 || attrName == SVGNames::widthAttr 112 || attrName == SVGNames::heightAttr) 113 updateRelativeLengthsInformation(); 114 115 RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer()); 116 if (renderer) 117 renderer->invalidateCacheAndMarkForLayout(); 118} 119 120void SVGMaskElement::childrenChanged(const ChildrenChange& change) 121{ 122 SVGElement::childrenChanged(change); 123 124 if (change.byParser) 125 return; 126 127 if (RenderObject* object = renderer()) 128 object->setNeedsLayoutAndFullPaintInvalidation(); 129} 130 131RenderObject* SVGMaskElement::createRenderer(RenderStyle*) 132{ 133 return new RenderSVGResourceMasker(this); 134} 135 136bool SVGMaskElement::selfHasRelativeLengths() const 137{ 138 return m_x->currentValue()->isRelative() 139 || m_y->currentValue()->isRelative() 140 || m_width->currentValue()->isRelative() 141 || m_height->currentValue()->isRelative(); 142} 143 144} // namespace blink 145