File indexing completed on 2024-04-28 15:24:39
0001 /* 0002 Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 0003 2004, 2005 Rob Buis <buis@kde.org> 0004 Copyright (C) 2007 Eric Seidel <eric@webkit.org> 0005 0006 This file is part of the WebKit project 0007 0008 This library is free software; you can redistribute it and/or 0009 modify it under the terms of the GNU Library General Public 0010 License as published by the Free Software Foundation; either 0011 version 2 of the License, or (at your option) any later version. 0012 0013 This library is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 Library General Public License for more details. 0017 0018 You should have received a copy of the GNU Library General Public License 0019 along with this library; see the file COPYING.LIB. If not, write to 0020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0021 Boston, MA 02110-1301, USA. 0022 */ 0023 0024 #include "wtf/Platform.h" 0025 0026 #if ENABLE(SVG) 0027 #include "SVGPathSegList.h" 0028 0029 #include "FloatPoint.h" 0030 #include "Path.h" 0031 #include "PathTraversalState.h" 0032 #include "SVGPathSegMoveto.h" 0033 #include "SVGPathSegLineto.h" 0034 #include "SVGPathSegCurvetoCubic.h" 0035 0036 namespace WebCore 0037 { 0038 0039 SVGPathSegList::SVGPathSegList(const QualifiedName &attributeName) 0040 : SVGList<RefPtr<SVGPathSeg> >(attributeName) 0041 { 0042 } 0043 0044 SVGPathSegList::~SVGPathSegList() 0045 { 0046 } 0047 0048 unsigned SVGPathSegList::getPathSegAtLength(double) 0049 { 0050 // FIXME : to be useful this will need to support non-normalized SVGPathSegLists 0051 ExceptionCode ec = 0; 0052 int len = numberOfItems(); 0053 // FIXME: Eventually this will likely move to a "path applier"-like model, until then PathTraversalState is less useful as we could just use locals 0054 PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength); 0055 for (int i = 0; i < len; ++i) { 0056 SVGPathSeg *segment = getItem(i, ec).get(); 0057 float segmentLength = 0; 0058 switch (segment->pathSegType()) { 0059 case SVGPathSeg::PATHSEG_MOVETO_ABS: { 0060 SVGPathSegMovetoAbs *moveTo = static_cast<SVGPathSegMovetoAbs *>(segment); 0061 segmentLength = traversalState.moveTo(FloatPoint(moveTo->x(), moveTo->y())); 0062 break; 0063 } 0064 case SVGPathSeg::PATHSEG_LINETO_ABS: { 0065 SVGPathSegLinetoAbs *lineTo = static_cast<SVGPathSegLinetoAbs *>(segment); 0066 segmentLength = traversalState.lineTo(FloatPoint(lineTo->x(), lineTo->y())); 0067 break; 0068 } 0069 case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: { 0070 SVGPathSegCurvetoCubicAbs *curveTo = static_cast<SVGPathSegCurvetoCubicAbs *>(segment); 0071 segmentLength = traversalState.cubicBezierTo(FloatPoint(curveTo->x1(), curveTo->y1()), 0072 FloatPoint(curveTo->x2(), curveTo->y2()), 0073 FloatPoint(curveTo->x(), curveTo->y())); 0074 break; 0075 } 0076 case SVGPathSeg::PATHSEG_CLOSEPATH: 0077 segmentLength = traversalState.closeSubpath(); 0078 break; 0079 default: 0080 ASSERT(false); // FIXME: This only works with normalized/processed path data. 0081 break; 0082 } 0083 traversalState.m_totalLength += segmentLength; 0084 if ((traversalState.m_action == PathTraversalState::TraversalSegmentAtLength) 0085 && (traversalState.m_totalLength > traversalState.m_desiredLength)) { 0086 return traversalState.m_segmentIndex; 0087 } 0088 traversalState.m_segmentIndex++; 0089 } 0090 0091 return 0; // The SVG spec is unclear as to what to return when the distance is not on the path 0092 } 0093 0094 khtml::Path SVGPathSegList::toPathData() 0095 { 0096 // FIXME : This should also support non-normalized PathSegLists 0097 Path pathData; 0098 ExceptionCode ec = 0; 0099 int len = numberOfItems(); 0100 for (int i = 0; i < len; ++i) { 0101 SVGPathSeg *segment = getItem(i, ec).get(); 0102 switch (segment->pathSegType()) { 0103 case SVGPathSeg::PATHSEG_MOVETO_ABS: { 0104 SVGPathSegMovetoAbs *moveTo = static_cast<SVGPathSegMovetoAbs *>(segment); 0105 pathData.moveTo(FloatPoint(moveTo->x(), moveTo->y())); 0106 break; 0107 } 0108 case SVGPathSeg::PATHSEG_LINETO_ABS: { 0109 SVGPathSegLinetoAbs *lineTo = static_cast<SVGPathSegLinetoAbs *>(segment); 0110 pathData.addLineTo(FloatPoint(lineTo->x(), lineTo->y())); 0111 break; 0112 } 0113 case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: { 0114 SVGPathSegCurvetoCubicAbs *curveTo = static_cast<SVGPathSegCurvetoCubicAbs *>(segment); 0115 pathData.addBezierCurveTo(FloatPoint(curveTo->x1(), curveTo->y1()), 0116 FloatPoint(curveTo->x2(), curveTo->y2()), 0117 FloatPoint(curveTo->x(), curveTo->y())); 0118 break; 0119 } 0120 case SVGPathSeg::PATHSEG_CLOSEPATH: 0121 pathData.closeSubpath(); 0122 break; 0123 default: 0124 ASSERT(false); // FIXME: This only works with normalized/processed path data. 0125 break; 0126 } 0127 } 0128 0129 return pathData; 0130 } 0131 0132 } 0133 0134 #endif // ENABLE(SVG)