98343fbbd8f3164a7ccbe17c30901c040b8c5d0d
[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 // 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)
36
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
42
43 inline SVGMaskElement::SVGMaskElement(Document& document)
44     : SVGElement(SVGNames::maskTag, document)
45     , SVGTests(this)
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)
52 {
53     ScriptWrappable::init(this);
54
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%");
58
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%");
62
63     addToPropertyMap(m_x);
64     addToPropertyMap(m_y);
65     addToPropertyMap(m_width);
66     addToPropertyMap(m_height);
67     registerAnimatedPropertiesForSVGMaskElement();
68 }
69
70 PassRefPtr<SVGMaskElement> SVGMaskElement::create(Document& document)
71 {
72     return adoptRef(new SVGMaskElement(document));
73 }
74
75 bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName)
76 {
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);
86     }
87     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
88 }
89
90 void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
91 {
92     SVGParsingError parseError = NoError;
93
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);
100         return;
101     } else if (name == SVGNames::maskContentUnitsAttr) {
102         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
103         if (propertyValue > 0)
104             setMaskContentUnitsBaseValue(propertyValue);
105         return;
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)) {
115     } else
116         ASSERT_NOT_REACHED();
117
118     reportAttributeParsingError(parseError, name, value);
119 }
120
121 void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
122 {
123     if (!isSupportedAttribute(attrName)) {
124         SVGElement::svgAttributeChanged(attrName);
125         return;
126     }
127
128     SVGElementInstance::InvalidationGuard invalidationGuard(this);
129
130     if (attrName == SVGNames::xAttr
131         || attrName == SVGNames::yAttr
132         || attrName == SVGNames::widthAttr
133         || attrName == SVGNames::heightAttr)
134         updateRelativeLengthsInformation();
135
136     RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer());
137     if (renderer)
138         renderer->invalidateCacheAndMarkForLayout();
139 }
140
141 void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
142 {
143     SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
144
145     if (changedByParser)
146         return;
147
148     if (RenderObject* object = renderer())
149         object->setNeedsLayout();
150 }
151
152 RenderObject* SVGMaskElement::createRenderer(RenderStyle*)
153 {
154     return new RenderSVGResourceMasker(this);
155 }
156
157 bool SVGMaskElement::selfHasRelativeLengths() const
158 {
159     return m_x->currentValue()->isRelative()
160         || m_y->currentValue()->isRelative()
161         || m_width->currentValue()->isRelative()
162         || m_height->currentValue()->isRelative();
163 }
164
165 }