fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / khtml / svg / SVGPathSegList.cpp
blobec73fa0b18a0f0df6875aba79d3bda127e68b38c
1 /*
2 Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005 Rob Buis <buis@kde.org>
4 Copyright (C) 2007 Eric Seidel <eric@webkit.org>
6 This file is part of the WebKit project
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.
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.
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.
24 #include "config.h"
25 #include "wtf/Platform.h"
27 #if ENABLE(SVG)
28 #include "SVGPathSegList.h"
30 #include "FloatPoint.h"
31 #include "Path.h"
32 #include "PathTraversalState.h"
33 #include "SVGPathSegMoveto.h"
34 #include "SVGPathSegLineto.h"
35 #include "SVGPathSegCurvetoCubic.h"
37 namespace WebCore {
39 SVGPathSegList::SVGPathSegList(const QualifiedName& attributeName)
40 : SVGList<RefPtr<SVGPathSeg> >(attributeName)
44 SVGPathSegList::~SVGPathSegList()
48 unsigned SVGPathSegList::getPathSegAtLength(double)
50 // FIXME : to be useful this will need to support non-normalized SVGPathSegLists
51 ExceptionCode ec = 0;
52 int len = numberOfItems();
53 // FIXME: Eventually this will likely move to a "path applier"-like model, until then PathTraversalState is less useful as we could just use locals
54 PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
55 for (int i = 0; i < len; ++i) {
56 SVGPathSeg* segment = getItem(i, ec).get();
57 float segmentLength = 0;
58 switch (segment->pathSegType()) {
59 case SVGPathSeg::PATHSEG_MOVETO_ABS:
61 SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment);
62 segmentLength = traversalState.moveTo(FloatPoint(moveTo->x(), moveTo->y()));
63 break;
65 case SVGPathSeg::PATHSEG_LINETO_ABS:
67 SVGPathSegLinetoAbs* lineTo = static_cast<SVGPathSegLinetoAbs*>(segment);
68 segmentLength = traversalState.lineTo(FloatPoint(lineTo->x(), lineTo->y()));
69 break;
71 case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:
73 SVGPathSegCurvetoCubicAbs* curveTo = static_cast<SVGPathSegCurvetoCubicAbs*>(segment);
74 segmentLength = traversalState.cubicBezierTo(FloatPoint(curveTo->x1(), curveTo->y1()),
75 FloatPoint(curveTo->x2(), curveTo->y2()),
76 FloatPoint(curveTo->x(), curveTo->y()));
77 break;
79 case SVGPathSeg::PATHSEG_CLOSEPATH:
80 segmentLength = traversalState.closeSubpath();
81 break;
82 default:
83 ASSERT(false); // FIXME: This only works with normalized/processed path data.
84 break;
86 traversalState.m_totalLength += segmentLength;
87 if ((traversalState.m_action == PathTraversalState::TraversalSegmentAtLength)
88 && (traversalState.m_totalLength > traversalState.m_desiredLength)) {
89 return traversalState.m_segmentIndex;
91 traversalState.m_segmentIndex++;
94 return 0; // The SVG spec is unclear as to what to return when the distance is not on the path
97 Path SVGPathSegList::toPathData()
99 // FIXME : This should also support non-normalized PathSegLists
100 Path pathData;
101 ExceptionCode ec = 0;
102 int len = numberOfItems();
103 for (int i = 0; i < len; ++i) {
104 SVGPathSeg* segment = getItem(i, ec).get();;
105 switch (segment->pathSegType())
107 case SVGPathSeg::PATHSEG_MOVETO_ABS:
109 SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment);
110 pathData.moveTo(FloatPoint(moveTo->x(), moveTo->y()));
111 break;
113 case SVGPathSeg::PATHSEG_LINETO_ABS:
115 SVGPathSegLinetoAbs* lineTo = static_cast<SVGPathSegLinetoAbs*>(segment);
116 pathData.addLineTo(FloatPoint(lineTo->x(), lineTo->y()));
117 break;
119 case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:
121 SVGPathSegCurvetoCubicAbs* curveTo = static_cast<SVGPathSegCurvetoCubicAbs*>(segment);
122 pathData.addBezierCurveTo(FloatPoint(curveTo->x1(), curveTo->y1()),
123 FloatPoint(curveTo->x2(), curveTo->y2()),
124 FloatPoint(curveTo->x(), curveTo->y()));
125 break;
127 case SVGPathSeg::PATHSEG_CLOSEPATH:
128 pathData.closeSubpath();
129 break;
130 default:
131 ASSERT(false); // FIXME: This only works with normalized/processed path data.
132 break;
136 return pathData;
141 #endif // ENABLE(SVG)