Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / SVGMaskElement.cpp
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 #include "core/svg/SVGElementInstance.h"
30
31 namespace WebCore {
32
33 inline SVGMaskElement::SVGMaskElement(Document& document)
34     : SVGElement(SVGNames::maskTag, document)
35     , SVGTests(this)
36     , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
37     , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
38     , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
39     , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
40     , m_maskUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
41     , m_maskContentUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
42 {
43     ScriptWrappable::init(this);
44
45     // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified.
46     m_x->setDefaultValueAsString("-10%");
47     m_y->setDefaultValueAsString("-10%");
48
49     // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified.
50     m_width->setDefaultValueAsString("120%");
51     m_height->setDefaultValueAsString("120%");
52
53     addToPropertyMap(m_x);
54     addToPropertyMap(m_y);
55     addToPropertyMap(m_width);
56     addToPropertyMap(m_height);
57     addToPropertyMap(m_maskUnits);
58     addToPropertyMap(m_maskContentUnits);
59 }
60
61 PassRefPtr<SVGMaskElement> SVGMaskElement::create(Document& document)
62 {
63     return adoptRef(new SVGMaskElement(document));
64 }
65
66 bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName)
67 {
68     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
69     if (supportedAttributes.isEmpty()) {
70         SVGTests::addSupportedAttributes(supportedAttributes);
71         supportedAttributes.add(SVGNames::maskUnitsAttr);
72         supportedAttributes.add(SVGNames::maskContentUnitsAttr);
73         supportedAttributes.add(SVGNames::xAttr);
74         supportedAttributes.add(SVGNames::yAttr);
75         supportedAttributes.add(SVGNames::widthAttr);
76         supportedAttributes.add(SVGNames::heightAttr);
77     }
78     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
79 }
80
81 void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
82 {
83     SVGParsingError parseError = NoError;
84
85     if (!isSupportedAttribute(name))
86         SVGElement::parseAttribute(name, value);
87     else if (name == SVGNames::maskUnitsAttr)
88         m_maskUnits->setBaseValueAsString(value, parseError);
89     else if (name == SVGNames::maskContentUnitsAttr)
90         m_maskContentUnits->setBaseValueAsString(value, parseError);
91     else if (name == SVGNames::xAttr)
92         m_x->setBaseValueAsString(value, parseError);
93     else if (name == SVGNames::yAttr)
94         m_y->setBaseValueAsString(value, parseError);
95     else if (name == SVGNames::widthAttr)
96         m_width->setBaseValueAsString(value, parseError);
97     else if (name == SVGNames::heightAttr)
98         m_height->setBaseValueAsString(value, parseError);
99     else if (SVGTests::parseAttribute(name, value)) {
100     } else
101         ASSERT_NOT_REACHED();
102
103     reportAttributeParsingError(parseError, name, value);
104 }
105
106 void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
107 {
108     if (!isSupportedAttribute(attrName)) {
109         SVGElement::svgAttributeChanged(attrName);
110         return;
111     }
112
113     SVGElement::InvalidationGuard invalidationGuard(this);
114
115     if (attrName == SVGNames::xAttr
116         || attrName == SVGNames::yAttr
117         || attrName == SVGNames::widthAttr
118         || attrName == SVGNames::heightAttr)
119         updateRelativeLengthsInformation();
120
121     RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer());
122     if (renderer)
123         renderer->invalidateCacheAndMarkForLayout();
124 }
125
126 void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
127 {
128     SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
129
130     if (changedByParser)
131         return;
132
133     if (RenderObject* object = renderer())
134         object->setNeedsLayout();
135 }
136
137 RenderObject* SVGMaskElement::createRenderer(RenderStyle*)
138 {
139     return new RenderSVGResourceMasker(this);
140 }
141
142 bool SVGMaskElement::selfHasRelativeLengths() const
143 {
144     return m_x->currentValue()->isRelative()
145         || m_y->currentValue()->isRelative()
146         || m_width->currentValue()->isRelative()
147         || m_height->currentValue()->isRelative();
148 }
149
150 }