2 Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
5 This file is part of the KDE project
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.
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.
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.
24 #include "wtf/Platform.h"
27 #include "SVGPathElement.h"
29 #include "RenderPath.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"
47 SVGPathElement::SVGPathElement(const QualifiedName
& tagName
, Document
* doc
)
48 : SVGStyledTransformableElement(tagName
, doc
)
51 , SVGExternalResourcesRequired()
56 SVGPathElement::~SVGPathElement()
60 ANIMATED_PROPERTY_DEFINITIONS(SVGPathElement
, float, Number
, number
, PathLength
, pathLength
, SVGNames::pathLengthAttr
, m_pathLength
)
62 float SVGPathElement::getTotalLength()
64 // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached)
65 return toPathData().length();
68 FloatPoint
SVGPathElement::getPointAtLength(float length
)
70 // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached)
72 return toPathData().pointAtLength(length
, ok
);
75 unsigned long SVGPathElement::getPathSegAtLength(float length
)
77 return pathSegList()->getPathSegAtLength(length
);
80 PassRefPtr
<SVGPathSegClosePath
> SVGPathElement::createSVGPathSegClosePath()
82 return SVGPathSegClosePath::create();
85 PassRefPtr
<SVGPathSegMovetoAbs
> SVGPathElement::createSVGPathSegMovetoAbs(float x
, float y
)
87 return SVGPathSegMovetoAbs::create(x
, y
);
90 PassRefPtr
<SVGPathSegMovetoRel
> SVGPathElement::createSVGPathSegMovetoRel(float x
, float y
)
92 return SVGPathSegMovetoRel::create(x
, y
);
95 PassRefPtr
<SVGPathSegLinetoAbs
> SVGPathElement::createSVGPathSegLinetoAbs(float x
, float y
)
97 return SVGPathSegLinetoAbs::create(x
, y
);
100 PassRefPtr
<SVGPathSegLinetoRel
> SVGPathElement::createSVGPathSegLinetoRel(float x
, float y
)
102 return SVGPathSegLinetoRel::create(x
, y
);
105 PassRefPtr
<SVGPathSegCurvetoCubicAbs
> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x
, float y
, float x1
, float y1
, float x2
, float y2
)
107 return SVGPathSegCurvetoCubicAbs::create(x
, y
, x1
, y1
, x2
, y2
);
110 PassRefPtr
<SVGPathSegCurvetoCubicRel
> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x
, float y
, float x1
, float y1
, float x2
, float y2
)
112 return SVGPathSegCurvetoCubicRel::create(x
, y
, x1
, y1
, x2
, y2
);
115 PassRefPtr
<SVGPathSegCurvetoQuadraticAbs
> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x
, float y
, float x1
, float y1
)
117 return SVGPathSegCurvetoQuadraticAbs::create(x
, y
, x1
, y1
);
120 PassRefPtr
<SVGPathSegCurvetoQuadraticRel
> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x
, float y
, float x1
, float y1
)
122 return SVGPathSegCurvetoQuadraticRel::create(x
, y
, x1
, y1
);
125 PassRefPtr
<SVGPathSegArcAbs
> SVGPathElement::createSVGPathSegArcAbs(float x
, float y
, float r1
, float r2
, float angle
, bool largeArcFlag
, bool sweepFlag
)
127 return SVGPathSegArcAbs::create(x
, y
, r1
, r2
, angle
, largeArcFlag
, sweepFlag
);
130 PassRefPtr
<SVGPathSegArcRel
> SVGPathElement::createSVGPathSegArcRel(float x
, float y
, float r1
, float r2
, float angle
, bool largeArcFlag
, bool sweepFlag
)
132 return SVGPathSegArcRel::create(x
, y
, r1
, r2
, angle
, largeArcFlag
, sweepFlag
);
135 PassRefPtr
<SVGPathSegLinetoHorizontalAbs
> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x
)
137 return SVGPathSegLinetoHorizontalAbs::create(x
);
140 PassRefPtr
<SVGPathSegLinetoHorizontalRel
> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x
)
142 return SVGPathSegLinetoHorizontalRel::create(x
);
145 PassRefPtr
<SVGPathSegLinetoVerticalAbs
> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y
)
147 return SVGPathSegLinetoVerticalAbs::create(y
);
150 PassRefPtr
<SVGPathSegLinetoVerticalRel
> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y
)
152 return SVGPathSegLinetoVerticalRel::create(y
);
155 PassRefPtr
<SVGPathSegCurvetoCubicSmoothAbs
> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x
, float y
, float x2
, float y2
)
157 return SVGPathSegCurvetoCubicSmoothAbs::create(x
, y
, x2
, y2
);
160 PassRefPtr
<SVGPathSegCurvetoCubicSmoothRel
> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x
, float y
, float x2
, float y2
)
162 return SVGPathSegCurvetoCubicSmoothRel::create(x
, y
, x2
, y2
);
165 PassRefPtr
<SVGPathSegCurvetoQuadraticSmoothAbs
> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x
, float y
)
167 return SVGPathSegCurvetoQuadraticSmoothAbs::create(x
, y
);
170 PassRefPtr
<SVGPathSegCurvetoQuadraticSmoothRel
> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x
, float y
)
172 return SVGPathSegCurvetoQuadraticSmoothRel::create(x
, y
);
175 void SVGPathElement::parseMappedAttribute(MappedAttribute
* attr
)
177 if (attr
->name() == SVGNames::dAttr
) {
179 pathSegList()->clear(ec
);
180 pathSegListFromSVGData(pathSegList(), attr
->value(), true);
181 /*FIXME khtml if (!pathSegListFromSVGData(pathSegList(), attr->value(), true))
182 document()->accessSVGExtensions()->reportError("Problem parsing d=\"" + attr->value() + "\"");*/
183 } else if (attr
->name() == SVGNames::pathLengthAttr
) {
184 m_pathLength
= attr
->value().toFloat();
185 if (m_pathLength
< 0.0f
)
186 document()->accessSVGExtensions()->reportError("A negative value for path attribute <pathLength> is not allowed");
188 if (SVGTests::parseMappedAttribute(attr
))
190 if (SVGLangSpace::parseMappedAttribute(attr
))
192 if (SVGExternalResourcesRequired::parseMappedAttribute(attr
))
194 SVGStyledTransformableElement::parseMappedAttribute(attr
);
198 void SVGPathElement::svgAttributeChanged(const QualifiedName
& attrName
)
200 SVGStyledTransformableElement::svgAttributeChanged(attrName
);
205 if (attrName
== SVGNames::dAttr
|| attrName
== SVGNames::pathLengthAttr
||
206 SVGTests::isKnownAttribute(attrName
) ||
207 SVGLangSpace::isKnownAttribute(attrName
) ||
208 SVGExternalResourcesRequired::isKnownAttribute(attrName
) ||
209 SVGStyledTransformableElement::isKnownAttribute(attrName
))
210 renderer()->setNeedsLayout(true);
213 SVGPathSegList
* SVGPathElement::pathSegList() const
216 m_pathSegList
= SVGPathSegList::create(SVGNames::dAttr
);
218 return m_pathSegList
.get();
221 SVGPathSegList
* SVGPathElement::normalizedPathSegList() const
227 SVGPathSegList
* SVGPathElement::animatedPathSegList() const
233 SVGPathSegList
* SVGPathElement::animatedNormalizedPathSegList() const
239 Path
SVGPathElement::toPathData() const
241 return pathSegList()->toPathData();
244 // KHTML ElementImpl pure virtual method
245 quint32
SVGPathElement::id() const
247 return SVGNames::pathTag
.id();
250 DOMString
SVGPathElement::tagName() const
252 return SVGNames::pathTag
.tagName();
257 #endif // ENABLE(SVG)