1 /* 2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann (at) kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis (at) kde.org> 4 * Copyright (C) 2005 Alexander Kellett <lypanov (at) kde.org> 5 * Copyright (C) 2009 Dirk Schulze <krit (at) 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 30 namespace WebCore { 31 32 inline 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 ScriptWrappable::init(this); 43 44 // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. 45 m_x->setDefaultValueAsString("-10%"); 46 m_y->setDefaultValueAsString("-10%"); 47 48 // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. 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_maskUnits); 57 addToPropertyMap(m_maskContentUnits); 58 } 59 60 DEFINE_NODE_FACTORY(SVGMaskElement) 61 62 bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName) 63 { 64 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 65 if (supportedAttributes.isEmpty()) { 66 SVGTests::addSupportedAttributes(supportedAttributes); 67 supportedAttributes.add(SVGNames::maskUnitsAttr); 68 supportedAttributes.add(SVGNames::maskContentUnitsAttr); 69 supportedAttributes.add(SVGNames::xAttr); 70 supportedAttributes.add(SVGNames::yAttr); 71 supportedAttributes.add(SVGNames::widthAttr); 72 supportedAttributes.add(SVGNames::heightAttr); 73 } 74 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 75 } 76 77 void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 78 { 79 SVGParsingError parseError = NoError; 80 81 if (!isSupportedAttribute(name)) 82 SVGElement::parseAttribute(name, value); 83 else if (name == SVGNames::maskUnitsAttr) 84 m_maskUnits->setBaseValueAsString(value, parseError); 85 else if (name == SVGNames::maskContentUnitsAttr) 86 m_maskContentUnits->setBaseValueAsString(value, parseError); 87 else if (name == SVGNames::xAttr) 88 m_x->setBaseValueAsString(value, parseError); 89 else if (name == SVGNames::yAttr) 90 m_y->setBaseValueAsString(value, parseError); 91 else if (name == SVGNames::widthAttr) 92 m_width->setBaseValueAsString(value, parseError); 93 else if (name == SVGNames::heightAttr) 94 m_height->setBaseValueAsString(value, parseError); 95 else if (SVGTests::parseAttribute(name, value)) { 96 } else 97 ASSERT_NOT_REACHED(); 98 99 reportAttributeParsingError(parseError, name, value); 100 } 101 102 void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName) 103 { 104 if (!isSupportedAttribute(attrName)) { 105 SVGElement::svgAttributeChanged(attrName); 106 return; 107 } 108 109 SVGElement::InvalidationGuard invalidationGuard(this); 110 111 if (attrName == SVGNames::xAttr 112 || attrName == SVGNames::yAttr 113 || attrName == SVGNames::widthAttr 114 || attrName == SVGNames::heightAttr) 115 updateRelativeLengthsInformation(); 116 117 RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer()); 118 if (renderer) 119 renderer->invalidateCacheAndMarkForLayout(); 120 } 121 122 void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) 123 { 124 SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); 125 126 if (changedByParser) 127 return; 128 129 if (RenderObject* object = renderer()) 130 object->setNeedsLayoutAndFullPaintInvalidation(); 131 } 132 133 RenderObject* SVGMaskElement::createRenderer(RenderStyle*) 134 { 135 return new RenderSVGResourceMasker(this); 136 } 137 138 bool SVGMaskElement::selfHasRelativeLengths() const 139 { 140 return m_x->currentValue()->isRelative() 141 || m_y->currentValue()->isRelative() 142 || m_width->currentValue()->isRelative() 143 || m_height->currentValue()->isRelative(); 144 } 145 146 } 147