Initial patch.
[vuplus_webkit] / Source / WebCore / svg / SVGPolyElement.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  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22
23 #if ENABLE(SVG)
24 #include "SVGPolyElement.h"
25
26 #include "Attribute.h"
27 #include "Document.h"
28 #include "FloatPoint.h"
29 #include "RenderSVGPath.h"
30 #include "RenderSVGResource.h"
31 #include "SVGElementInstance.h"
32 #include "SVGNames.h"
33 #include "SVGParserUtilities.h"
34 #include "SVGPointList.h"
35
36 namespace WebCore {
37
38 // Define custom animated property 'points'.
39 const SVGPropertyInfo* SVGPolyElement::pointsPropertyInfo()
40 {
41     static const SVGPropertyInfo* s_propertyInfo = 0;
42     if (!s_propertyInfo) {
43         s_propertyInfo = new SVGPropertyInfo(AnimatedPoints,
44                                              SVGNames::pointsAttr,
45                                              SVGNames::pointsAttr.localName(),
46                                              &SVGPolyElement::synchronizePoints,
47                                              &SVGPolyElement::lookupOrCreatePointsWrapper);
48     }
49     return s_propertyInfo;
50 }
51
52 // Animated property definitions
53 DEFINE_ANIMATED_BOOLEAN(SVGPolyElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
54
55 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGPolyElement)
56     REGISTER_LOCAL_ANIMATED_PROPERTY(points)
57     REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
58     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGStyledTransformableElement)
59     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
60 END_REGISTER_ANIMATED_PROPERTIES
61
62 SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document* document)
63     : SVGStyledTransformableElement(tagName, document)
64 {
65     registerAnimatedPropertiesForSVGPolyElement();    
66 }
67
68 bool SVGPolyElement::isSupportedAttribute(const QualifiedName& attrName)
69 {
70     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
71     if (supportedAttributes.isEmpty()) {
72         SVGTests::addSupportedAttributes(supportedAttributes);
73         SVGLangSpace::addSupportedAttributes(supportedAttributes);
74         SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
75         supportedAttributes.add(SVGNames::pointsAttr);
76     }
77     return supportedAttributes.contains(attrName);
78 }
79
80 void SVGPolyElement::parseMappedAttribute(Attribute* attr)
81 {
82     if (!isSupportedAttribute(attr->name())) {
83         SVGStyledTransformableElement::parseMappedAttribute(attr);
84         return;
85     }
86
87     const AtomicString& value = attr->value();
88     if (attr->name() == SVGNames::pointsAttr) {
89         SVGPointList newList;
90         if (!pointsListFromSVGData(newList, value))
91             document()->accessSVGExtensions()->reportError("Problem parsing points=\"" + value + "\"");
92
93         if (SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGPolyElement, SVGAnimatedListPropertyTearOff<SVGPointList>, true>(this, pointsPropertyInfo()))
94             static_cast<SVGAnimatedListPropertyTearOff<SVGPointList>*>(wrapper)->detachListWrappers(newList.size());
95
96         m_points.value = newList;
97         return;
98     }
99
100     if (SVGTests::parseMappedAttribute(attr))
101         return;
102     if (SVGLangSpace::parseMappedAttribute(attr))
103         return;
104     if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
105         return;
106
107     ASSERT_NOT_REACHED();
108 }
109
110 void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
111 {
112     if (!isSupportedAttribute(attrName)) {
113         SVGStyledTransformableElement::svgAttributeChanged(attrName);
114         return;
115     }
116
117     SVGElementInstance::InvalidationGuard invalidationGuard(this);
118     
119     if (SVGTests::handleAttributeChange(this, attrName))
120         return;
121
122     RenderSVGPath* renderer = static_cast<RenderSVGPath*>(this->renderer());
123     if (!renderer)
124         return;
125
126     if (attrName == SVGNames::pointsAttr) {
127         renderer->setNeedsPathUpdate();
128         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
129         return;
130     }
131
132     if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
133         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
134         return;
135     }
136
137     ASSERT_NOT_REACHED();
138 }
139
140 void SVGPolyElement::synchronizePoints(void* contextElement)
141 {
142     ASSERT(contextElement);
143     SVGPolyElement* ownerType = static_cast<SVGPolyElement*>(contextElement);
144     if (!ownerType->m_points.shouldSynchronize)
145         return;
146     SVGAnimatedPropertySynchronizer<true>::synchronize(ownerType, pointsPropertyInfo()->attributeName, ownerType->m_points.value.valueAsString());
147 }
148
149 PassRefPtr<SVGAnimatedProperty> SVGPolyElement::lookupOrCreatePointsWrapper(void* contextElement)
150 {
151     ASSERT(contextElement);
152     SVGPolyElement* ownerType = static_cast<SVGPolyElement*>(contextElement);
153     return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPolyElement, SVGAnimatedListPropertyTearOff<SVGPointList>, SVGPointList, true>
154            (ownerType, pointsPropertyInfo(), ownerType->m_points.value);
155 }
156
157 SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::points()
158 {
159     m_points.shouldSynchronize = true;
160     return static_cast<SVGListPropertyTearOff<SVGPointList>*>(static_pointer_cast<SVGAnimatedListPropertyTearOff<SVGPointList> >(lookupOrCreatePointsWrapper(this))->baseVal());
161 }
162
163 SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::animatedPoints()
164 {
165     m_points.shouldSynchronize = true;
166     return static_cast<SVGListPropertyTearOff<SVGPointList>*>(static_pointer_cast<SVGAnimatedListPropertyTearOff<SVGPointList> >(lookupOrCreatePointsWrapper(this))->animVal());
167 }
168
169 }
170
171 #endif // ENABLE(SVG)