• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3                   2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 
5     This file is part of the KDE project
6 
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11 
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16 
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22 
23 #include "config.h"
24 
25 #if ENABLE(SVG)
26 #include "SVGPathElement.h"
27 
28 #include "MappedAttribute.h"
29 #include "RenderPath.h"
30 #include "SVGNames.h"
31 #include "SVGParserUtilities.h"
32 #include "SVGPathSegArc.h"
33 #include "SVGPathSegClosePath.h"
34 #include "SVGPathSegCurvetoCubic.h"
35 #include "SVGPathSegCurvetoCubicSmooth.h"
36 #include "SVGPathSegCurvetoQuadratic.h"
37 #include "SVGPathSegCurvetoQuadraticSmooth.h"
38 #include "SVGPathSegLineto.h"
39 #include "SVGPathSegLinetoHorizontal.h"
40 #include "SVGPathSegLinetoVertical.h"
41 #include "SVGPathSegList.h"
42 #include "SVGPathSegMoveto.h"
43 #include "SVGSVGElement.h"
44 
45 namespace WebCore {
46 
SVGPathElement(const QualifiedName & tagName,Document * doc)47 SVGPathElement::SVGPathElement(const QualifiedName& tagName, Document* doc)
48     : SVGStyledTransformableElement(tagName, doc)
49     , SVGTests()
50     , SVGLangSpace()
51     , SVGExternalResourcesRequired()
52     , m_pathLength(this, SVGNames::pathLengthAttr, 0.0f)
53 {
54 }
55 
~SVGPathElement()56 SVGPathElement::~SVGPathElement()
57 {
58 }
59 
getTotalLength()60 float SVGPathElement::getTotalLength()
61 {
62     // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached)
63     return toPathData().length();
64 }
65 
getPointAtLength(float length)66 FloatPoint SVGPathElement::getPointAtLength(float length)
67 {
68     // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached)
69     bool ok = false;
70     return toPathData().pointAtLength(length, ok);
71 }
72 
getPathSegAtLength(float length)73 unsigned long SVGPathElement::getPathSegAtLength(float length)
74 {
75     return pathSegList()->getPathSegAtLength(length);
76 }
77 
createSVGPathSegClosePath()78 PassRefPtr<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath()
79 {
80     return SVGPathSegClosePath::create();
81 }
82 
createSVGPathSegMovetoAbs(float x,float y)83 PassRefPtr<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y)
84 {
85     return SVGPathSegMovetoAbs::create(x, y);
86 }
87 
createSVGPathSegMovetoRel(float x,float y)88 PassRefPtr<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y)
89 {
90     return SVGPathSegMovetoRel::create(x, y);
91 }
92 
createSVGPathSegLinetoAbs(float x,float y)93 PassRefPtr<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y)
94 {
95     return SVGPathSegLinetoAbs::create(x, y);
96 }
97 
createSVGPathSegLinetoRel(float x,float y)98 PassRefPtr<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y)
99 {
100     return SVGPathSegLinetoRel::create(x, y);
101 }
102 
createSVGPathSegCurvetoCubicAbs(float x,float y,float x1,float y1,float x2,float y2)103 PassRefPtr<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2)
104 {
105     return SVGPathSegCurvetoCubicAbs::create(x, y, x1, y1, x2, y2);
106 }
107 
createSVGPathSegCurvetoCubicRel(float x,float y,float x1,float y1,float x2,float y2)108 PassRefPtr<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2)
109 {
110     return SVGPathSegCurvetoCubicRel::create(x, y, x1, y1, x2, y2);
111 }
112 
createSVGPathSegCurvetoQuadraticAbs(float x,float y,float x1,float y1)113 PassRefPtr<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1)
114 {
115     return SVGPathSegCurvetoQuadraticAbs::create(x, y, x1, y1);
116 }
117 
createSVGPathSegCurvetoQuadraticRel(float x,float y,float x1,float y1)118 PassRefPtr<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1)
119 {
120     return SVGPathSegCurvetoQuadraticRel::create(x, y, x1, y1);
121 }
122 
createSVGPathSegArcAbs(float x,float y,float r1,float r2,float angle,bool largeArcFlag,bool sweepFlag)123 PassRefPtr<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
124 {
125     return SVGPathSegArcAbs::create(x, y, r1, r2, angle, largeArcFlag, sweepFlag);
126 }
127 
createSVGPathSegArcRel(float x,float y,float r1,float r2,float angle,bool largeArcFlag,bool sweepFlag)128 PassRefPtr<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
129 {
130     return SVGPathSegArcRel::create(x, y, r1, r2, angle, largeArcFlag, sweepFlag);
131 }
132 
createSVGPathSegLinetoHorizontalAbs(float x)133 PassRefPtr<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x)
134 {
135     return SVGPathSegLinetoHorizontalAbs::create(x);
136 }
137 
createSVGPathSegLinetoHorizontalRel(float x)138 PassRefPtr<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x)
139 {
140     return SVGPathSegLinetoHorizontalRel::create(x);
141 }
142 
createSVGPathSegLinetoVerticalAbs(float y)143 PassRefPtr<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y)
144 {
145     return SVGPathSegLinetoVerticalAbs::create(y);
146 }
147 
createSVGPathSegLinetoVerticalRel(float y)148 PassRefPtr<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y)
149 {
150     return SVGPathSegLinetoVerticalRel::create(y);
151 }
152 
createSVGPathSegCurvetoCubicSmoothAbs(float x,float y,float x2,float y2)153 PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2)
154 {
155     return SVGPathSegCurvetoCubicSmoothAbs::create(x, y, x2, y2);
156 }
157 
createSVGPathSegCurvetoCubicSmoothRel(float x,float y,float x2,float y2)158 PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2)
159 {
160     return SVGPathSegCurvetoCubicSmoothRel::create(x, y, x2, y2);
161 }
162 
createSVGPathSegCurvetoQuadraticSmoothAbs(float x,float y)163 PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y)
164 {
165     return SVGPathSegCurvetoQuadraticSmoothAbs::create(x, y);
166 }
167 
createSVGPathSegCurvetoQuadraticSmoothRel(float x,float y)168 PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y)
169 {
170     return SVGPathSegCurvetoQuadraticSmoothRel::create(x, y);
171 }
172 
parseMappedAttribute(MappedAttribute * attr)173 void SVGPathElement::parseMappedAttribute(MappedAttribute* attr)
174 {
175     if (attr->name() == SVGNames::dAttr) {
176         ExceptionCode ec;
177         pathSegList()->clear(ec);
178         if (!pathSegListFromSVGData(pathSegList(), attr->value(), true))
179             document()->accessSVGExtensions()->reportError("Problem parsing d=\"" + attr->value() + "\"");
180     } else if (attr->name() == SVGNames::pathLengthAttr) {
181         setPathLengthBaseValue(attr->value().toFloat());
182         if (pathLengthBaseValue() < 0.0f)
183             document()->accessSVGExtensions()->reportError("A negative value for path attribute <pathLength> is not allowed");
184     } else {
185         if (SVGTests::parseMappedAttribute(attr))
186             return;
187         if (SVGLangSpace::parseMappedAttribute(attr))
188             return;
189         if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
190             return;
191         SVGStyledTransformableElement::parseMappedAttribute(attr);
192     }
193 }
194 
svgAttributeChanged(const QualifiedName & attrName)195 void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
196 {
197     SVGStyledTransformableElement::svgAttributeChanged(attrName);
198 
199     if (!renderer())
200         return;
201 
202     if (attrName == SVGNames::dAttr || attrName == SVGNames::pathLengthAttr ||
203         SVGTests::isKnownAttribute(attrName) ||
204         SVGLangSpace::isKnownAttribute(attrName) ||
205         SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
206         SVGStyledTransformableElement::isKnownAttribute(attrName))
207         renderer()->setNeedsLayout(true);
208 }
209 
pathSegList() const210 SVGPathSegList* SVGPathElement::pathSegList() const
211 {
212     if (!m_pathSegList)
213         m_pathSegList = SVGPathSegList::create(SVGNames::dAttr);
214 
215     return m_pathSegList.get();
216 }
217 
normalizedPathSegList() const218 SVGPathSegList* SVGPathElement::normalizedPathSegList() const
219 {
220     // TODO
221     return 0;
222 }
223 
animatedPathSegList() const224 SVGPathSegList* SVGPathElement::animatedPathSegList() const
225 {
226     // TODO
227     return 0;
228 }
229 
animatedNormalizedPathSegList() const230 SVGPathSegList* SVGPathElement::animatedNormalizedPathSegList() const
231 {
232     // TODO
233     return 0;
234 }
235 
toPathData() const236 Path SVGPathElement::toPathData() const
237 {
238     return pathSegList()->toPathData();
239 }
240 
241 }
242 
243 #endif // ENABLE(SVG)
244