2007-01-02 Eric Seidel <eric@webkit.org>
[WebKit-https.git] / WebCore / ksvg2 / svg / SVGPathElement.cpp
1 /*
2     Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
3                   2004, 2005, 2006 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., 59 Temple Place - Suite 330,
20     Boston, MA 02111-1307, USA.
21 */
22
23 #include "config.h"
24
25 #ifdef SVG_SUPPORT
26 #include "SVGPathElement.h"
27
28 #include "SVGNames.h"
29 #include "SVGPathSegArc.h"
30 #include "SVGPathSegClosePath.h"
31 #include "SVGPathSegCurvetoCubic.h"
32 #include "SVGPathSegCurvetoCubicSmooth.h"
33 #include "SVGPathSegCurvetoQuadratic.h"
34 #include "SVGPathSegCurvetoQuadraticSmooth.h"
35 #include "SVGPathSegLineto.h"
36 #include "SVGPathSegLinetoHorizontal.h"
37 #include "SVGPathSegLinetoVertical.h"
38 #include "SVGPathSegList.h"
39 #include "SVGPathSegMoveto.h"
40 #include "SVGSVGElement.h"
41
42 namespace WebCore {
43
44 SVGPathElement::SVGPathElement(const QualifiedName& tagName, Document* doc)
45     : SVGStyledTransformableElement(tagName, doc)
46     , SVGTests()
47     , SVGLangSpace()
48     , SVGExternalResourcesRequired()
49     , SVGPathParser()
50     , m_pathLength(0.0)
51 {
52 }
53
54 SVGPathElement::~SVGPathElement()
55 {
56 }
57
58 ANIMATED_PROPERTY_DEFINITIONS(SVGPathElement, double, Number, number, PathLength, pathLength, SVGNames::pathLengthAttr.localName(), m_pathLength)
59
60 double 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
66 FloatPoint SVGPathElement::getPointAtLength(double 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
73 unsigned long SVGPathElement::getPathSegAtLength(double length)
74 {
75     return pathSegList()->getPathSegAtLength(length);
76 }
77
78 SVGPathSegClosePath* SVGPathElement::createSVGPathSegClosePath()
79 {
80     return new SVGPathSegClosePath();
81 }
82
83 SVGPathSegMovetoAbs* SVGPathElement::createSVGPathSegMovetoAbs(double x, double y)
84 {
85     return new SVGPathSegMovetoAbs(x, y);
86 }
87
88 SVGPathSegMovetoRel* SVGPathElement::createSVGPathSegMovetoRel(double x, double y)
89 {
90     return new SVGPathSegMovetoRel(x, y);
91 }
92
93 SVGPathSegLinetoAbs* SVGPathElement::createSVGPathSegLinetoAbs(double x, double y)
94 {
95     return new SVGPathSegLinetoAbs(x, y);
96 }
97
98 SVGPathSegLinetoRel* SVGPathElement::createSVGPathSegLinetoRel(double x, double y)
99 {
100     return new SVGPathSegLinetoRel(x, y);
101 }
102
103 SVGPathSegCurvetoCubicAbs* SVGPathElement::createSVGPathSegCurvetoCubicAbs(double x, double y, double x1, double y1, double x2, double y2)
104 {
105     return new SVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2);
106 }
107
108 SVGPathSegCurvetoCubicRel* SVGPathElement::createSVGPathSegCurvetoCubicRel(double x, double y, double x1, double y1, double x2, double y2)
109 {
110     return new SVGPathSegCurvetoCubicRel(x, y, x1, y1, x2, y2);
111 }
112
113 SVGPathSegCurvetoQuadraticAbs* SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(double x, double y, double x1, double y1)
114 {
115     return new SVGPathSegCurvetoQuadraticAbs(x, y, x1, y1);
116 }
117
118 SVGPathSegCurvetoQuadraticRel* SVGPathElement::createSVGPathSegCurvetoQuadraticRel(double x, double y, double x1, double y1)
119 {
120     return new SVGPathSegCurvetoQuadraticRel(x, y, x1, y1);
121 }
122
123 SVGPathSegArcAbs* SVGPathElement::createSVGPathSegArcAbs(double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag)
124 {
125     return new SVGPathSegArcAbs(x, y, r1, r2, angle, largeArcFlag, sweepFlag);
126 }
127
128 SVGPathSegArcRel* SVGPathElement::createSVGPathSegArcRel(double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag)
129 {
130     return new SVGPathSegArcRel(x, y, r1, r2, angle, largeArcFlag, sweepFlag);
131 }
132
133 SVGPathSegLinetoHorizontalAbs* SVGPathElement::createSVGPathSegLinetoHorizontalAbs(double x)
134 {
135     return new SVGPathSegLinetoHorizontalAbs(x);
136 }
137
138 SVGPathSegLinetoHorizontalRel* SVGPathElement::createSVGPathSegLinetoHorizontalRel(double x)
139 {
140     return new SVGPathSegLinetoHorizontalRel(x);
141 }
142
143 SVGPathSegLinetoVerticalAbs* SVGPathElement::createSVGPathSegLinetoVerticalAbs(double y)
144 {
145     return new SVGPathSegLinetoVerticalAbs(y);
146 }
147
148 SVGPathSegLinetoVerticalRel* SVGPathElement::createSVGPathSegLinetoVerticalRel(double y)
149 {
150     return new SVGPathSegLinetoVerticalRel(y);
151 }
152
153 SVGPathSegCurvetoCubicSmoothAbs* SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(double x, double y, double x2, double y2)
154 {
155     return new SVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2);
156 }
157
158 SVGPathSegCurvetoCubicSmoothRel* SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(double x, double y, double x2, double y2)
159 {
160     return new SVGPathSegCurvetoCubicSmoothRel(x, y, x2, y2);
161 }
162
163 SVGPathSegCurvetoQuadraticSmoothAbs* SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(double x, double y)
164 {
165     return new SVGPathSegCurvetoQuadraticSmoothAbs(x, y);
166 }
167
168 SVGPathSegCurvetoQuadraticSmoothRel* SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(double x, double y)
169 {
170     return new SVGPathSegCurvetoQuadraticSmoothRel(x, y);
171 }
172
173 void SVGPathElement::svgMoveTo(double x1, double y1, bool, bool abs)
174 {
175     ExceptionCode ec = 0;
176
177     if (abs)
178         pathSegList()->appendItem(createSVGPathSegMovetoAbs(x1, y1), ec);
179     else
180         pathSegList()->appendItem(createSVGPathSegMovetoRel(x1, y1), ec);
181 }
182
183 void SVGPathElement::svgLineTo(double x1, double y1, bool abs)
184 {
185     ExceptionCode ec = 0;
186
187     if (abs)
188         pathSegList()->appendItem(createSVGPathSegLinetoAbs(x1, y1), ec);
189     else
190         pathSegList()->appendItem(createSVGPathSegLinetoRel(x1, y1), ec);
191 }
192
193 void SVGPathElement::svgLineToHorizontal(double x, bool abs)
194 {
195     ExceptionCode ec = 0;
196
197     if (abs)
198         pathSegList()->appendItem(createSVGPathSegLinetoHorizontalAbs(x), ec);
199     else
200         pathSegList()->appendItem(createSVGPathSegLinetoHorizontalRel(x), ec);
201 }
202
203 void SVGPathElement::svgLineToVertical(double y, bool abs)
204 {
205     ExceptionCode ec = 0;
206
207     if (abs)
208         pathSegList()->appendItem(createSVGPathSegLinetoVerticalAbs(y), ec);
209     else
210         pathSegList()->appendItem(createSVGPathSegLinetoVerticalRel(y), ec);
211 }
212
213 void SVGPathElement::svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs)
214 {
215     ExceptionCode ec = 0;
216
217     if (abs)
218         pathSegList()->appendItem(createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), ec);
219     else
220         pathSegList()->appendItem(createSVGPathSegCurvetoCubicRel(x, y, x1, y1, x2, y2), ec);
221 }
222
223 void SVGPathElement::svgCurveToCubicSmooth(double x, double y, double x2, double y2, bool abs)
224 {
225     ExceptionCode ec = 0;
226
227     if (abs)
228         pathSegList()->appendItem(createSVGPathSegCurvetoCubicSmoothAbs(x2, y2, x, y), ec);
229     else
230         pathSegList()->appendItem(createSVGPathSegCurvetoCubicSmoothRel(x2, y2, x, y), ec);
231 }
232
233 void SVGPathElement::svgCurveToQuadratic(double x, double y, double x1, double y1, bool abs)
234 {
235     ExceptionCode ec = 0;
236
237     if (abs)
238         pathSegList()->appendItem(createSVGPathSegCurvetoQuadraticAbs(x1, y1, x, y), ec);
239     else
240         pathSegList()->appendItem(createSVGPathSegCurvetoQuadraticRel(x1, y1, x, y), ec);
241 }
242
243 void SVGPathElement::svgCurveToQuadraticSmooth(double x, double y, bool abs)
244 {
245     ExceptionCode ec = 0;
246
247     if (abs)
248         pathSegList()->appendItem(createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), ec);
249     else
250         pathSegList()->appendItem(createSVGPathSegCurvetoQuadraticSmoothRel(x, y), ec);
251 }
252
253 void SVGPathElement::svgArcTo(double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag, bool abs)
254 {
255     ExceptionCode ec = 0;
256
257     if (abs)
258         pathSegList()->appendItem(createSVGPathSegArcAbs(x, y, r1, r2, angle, largeArcFlag, sweepFlag), ec);
259     else
260         pathSegList()->appendItem(createSVGPathSegArcRel(x, y, r1, r2, angle, largeArcFlag, sweepFlag), ec);
261 }
262
263 void SVGPathElement::svgClosePath()
264 {
265     ExceptionCode ec = 0;
266     pathSegList()->appendItem(createSVGPathSegClosePath(), ec);
267 }
268
269 void SVGPathElement::parseMappedAttribute(MappedAttribute* attr)
270 {
271     if (attr->name() == SVGNames::dAttr) {
272         ExceptionCode ec;
273         pathSegList()->clear(ec);
274         if (!parseSVG(attr->value(), true))
275             pathSegList()->clear(ec);
276     } else {
277         if (SVGTests::parseMappedAttribute(attr))
278             return;
279         if (SVGLangSpace::parseMappedAttribute(attr))
280             return;
281         if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
282             return;
283         SVGStyledTransformableElement::parseMappedAttribute(attr);
284     }
285 }
286
287 SVGPathSegList* SVGPathElement::pathSegList() const
288 {
289     if (!m_pathSegList)
290         m_pathSegList = new SVGPathSegList(this);
291
292     return m_pathSegList.get();
293 }
294
295 SVGPathSegList* SVGPathElement::normalizedPathSegList() const
296 {
297     // TODO
298     return 0;
299 }
300
301 SVGPathSegList* SVGPathElement::animatedPathSegList() const
302 {
303     // TODO
304     return 0;
305 }
306
307 SVGPathSegList* SVGPathElement::animatedNormalizedPathSegList() const
308 {
309     // TODO
310     return 0;
311 }
312
313 Path SVGPathElement::toPathData() const
314 {
315     return pathSegList()->toPathData();
316 }
317
318 }
319
320 #endif // SVG_SUPPORT
321
322 // vim:ts=4:noet