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.
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.
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.
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.
26 #include "core/svg/SVGMaskElement.h"
28 #include "core/rendering/svg/RenderSVGResourceMasker.h"
29 #include "core/svg/SVGElementInstance.h"
33 // Animated property definitions
34 DEFINE_ANIMATED_ENUMERATION(SVGMaskElement, SVGNames::maskUnitsAttr, MaskUnits, maskUnits, SVGUnitTypes::SVGUnitType)
35 DEFINE_ANIMATED_ENUMERATION(SVGMaskElement, SVGNames::maskContentUnitsAttr, MaskContentUnits, maskContentUnits, SVGUnitTypes::SVGUnitType)
37 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMaskElement)
38 REGISTER_LOCAL_ANIMATED_PROPERTY(maskUnits)
39 REGISTER_LOCAL_ANIMATED_PROPERTY(maskContentUnits)
40 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
41 END_REGISTER_ANIMATED_PROPERTIES
43 inline SVGMaskElement::SVGMaskElement(Document& document)
44 : SVGElement(SVGNames::maskTag, document)
46 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth)))
47 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight)))
48 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth)))
49 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight)))
50 , m_maskUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
51 , m_maskContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
53 ScriptWrappable::init(this);
55 // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified.
56 m_x->setDefaultValueAsString("-10%");
57 m_y->setDefaultValueAsString("-10%");
59 // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified.
60 m_width->setDefaultValueAsString("120%");
61 m_height->setDefaultValueAsString("120%");
63 addToPropertyMap(m_x);
64 addToPropertyMap(m_y);
65 addToPropertyMap(m_width);
66 addToPropertyMap(m_height);
67 registerAnimatedPropertiesForSVGMaskElement();
70 PassRefPtr<SVGMaskElement> SVGMaskElement::create(Document& document)
72 return adoptRef(new SVGMaskElement(document));
75 bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName)
77 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
78 if (supportedAttributes.isEmpty()) {
79 SVGTests::addSupportedAttributes(supportedAttributes);
80 supportedAttributes.add(SVGNames::maskUnitsAttr);
81 supportedAttributes.add(SVGNames::maskContentUnitsAttr);
82 supportedAttributes.add(SVGNames::xAttr);
83 supportedAttributes.add(SVGNames::yAttr);
84 supportedAttributes.add(SVGNames::widthAttr);
85 supportedAttributes.add(SVGNames::heightAttr);
87 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
90 void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
92 SVGParsingError parseError = NoError;
94 if (!isSupportedAttribute(name))
95 SVGElement::parseAttribute(name, value);
96 else if (name == SVGNames::maskUnitsAttr) {
97 SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
98 if (propertyValue > 0)
99 setMaskUnitsBaseValue(propertyValue);
101 } else if (name == SVGNames::maskContentUnitsAttr) {
102 SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
103 if (propertyValue > 0)
104 setMaskContentUnitsBaseValue(propertyValue);
106 } else if (name == SVGNames::xAttr)
107 m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError);
108 else if (name == SVGNames::yAttr)
109 m_y->setBaseValueAsString(value, AllowNegativeLengths, parseError);
110 else if (name == SVGNames::widthAttr)
111 m_width->setBaseValueAsString(value, ForbidNegativeLengths, parseError);
112 else if (name == SVGNames::heightAttr)
113 m_height->setBaseValueAsString(value, ForbidNegativeLengths, parseError);
114 else if (SVGTests::parseAttribute(name, value)) {
116 ASSERT_NOT_REACHED();
118 reportAttributeParsingError(parseError, name, value);
121 void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
123 if (!isSupportedAttribute(attrName)) {
124 SVGElement::svgAttributeChanged(attrName);
128 SVGElementInstance::InvalidationGuard invalidationGuard(this);
130 if (attrName == SVGNames::xAttr
131 || attrName == SVGNames::yAttr
132 || attrName == SVGNames::widthAttr
133 || attrName == SVGNames::heightAttr)
134 updateRelativeLengthsInformation();
136 RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer());
138 renderer->invalidateCacheAndMarkForLayout();
141 void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
143 SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
148 if (RenderObject* object = renderer())
149 object->setNeedsLayout();
152 RenderObject* SVGMaskElement::createRenderer(RenderStyle*)
154 return new RenderSVGResourceMasker(this);
157 bool SVGMaskElement::selfHasRelativeLengths() const
159 return m_x->currentValue()->isRelative()
160 || m_y->currentValue()->isRelative()
161 || m_width->currentValue()->isRelative()
162 || m_height->currentValue()->isRelative();