Changeset 86973 in webkit
- Timestamp:
- May 20, 2011 12:04:52 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r86970 r86973 1 2011-05-20 Dirk Schulze <krit@webkit.org> 2 3 Reviewed by Darin Adler. 4 5 SVGPathSegList needs better getTotalLength, getSegmentAtLength path traversal code 6 https://bugs.webkit.org/show_bug.cgi?id=12047 7 8 Right now SVGPathElement::getTotalLength and SVGPathElement::getPointAtLength use toPathData() 9 to transform a SVGPathByteStream to a Path. This Path gets traversed to find the searched value. 10 With this patch both functions use the SVGPathByteStream directly together with the existing 11 traversing code in SVG. This avoids the intermediate transforming to a platform path and gives 12 platform independent results. 13 The traversal code in SVG needed to be extended to support all PathTraversalActions. 14 15 No new tests added. The existing tests cover the changes. 16 17 * svg/SVGPathElement.cpp: 18 (WebCore::SVGPathElement::getTotalLength): 19 (WebCore::SVGPathElement::getPointAtLength): 20 * svg/SVGPathParserFactory.cpp: 21 (WebCore::SVGPathParserFactory::getTotalLengthOfSVGPathByteStream): 22 (WebCore::SVGPathParserFactory::getPointAtLengthOfSVGPathByteStream): 23 * svg/SVGPathParserFactory.h: 24 * svg/SVGPathTraversalStateBuilder.cpp: 25 (WebCore::SVGPathTraversalStateBuilder::continueConsuming): 26 (WebCore::SVGPathTraversalStateBuilder::totalLength): 27 (WebCore::SVGPathTraversalStateBuilder::currentPoint): 28 * svg/SVGPathTraversalStateBuilder.h: 29 1 30 2011-05-20 Mark Pilgrim <pilgrim@chromium.org> 2 31 -
trunk/Source/WebCore/svg/SVGPathElement.cpp
r86050 r86973 65 65 float SVGPathElement::getTotalLength() 66 66 { 67 // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached) 68 Path path; 69 toPathData(path); 70 return path.length(); 67 float totalLength = 0; 68 SVGPathParserFactory::self()->getTotalLengthOfSVGPathByteStream(m_pathByteStream.get(), totalLength); 69 return totalLength; 71 70 } 72 71 73 72 FloatPoint SVGPathElement::getPointAtLength(float length) 74 73 { 75 // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached) 76 bool ok = false; 77 Path path; 78 toPathData(path); 79 return path.pointAtLength(length, ok); 74 FloatPoint point; 75 SVGPathParserFactory::self()->getPointAtLengthOfSVGPathByteStream(m_pathByteStream.get(), length, point); 76 return point; 80 77 } 81 78 82 79 unsigned long SVGPathElement::getPathSegAtLength(float length) 83 80 { 84 SVGPathParserFactory* factory = SVGPathParserFactory::self();85 81 unsigned long pathSeg = 0; 86 factory->getSVGPathSegAtLengthFromSVGPathByteStream(m_pathByteStream.get(), length, pathSeg);82 SVGPathParserFactory::self()->getSVGPathSegAtLengthFromSVGPathByteStream(m_pathByteStream.get(), length, pathSeg); 87 83 return pathSeg; 88 84 } -
trunk/Source/WebCore/svg/SVGPathParserFactory.cpp
r72381 r86973 268 268 } 269 269 270 bool SVGPathParserFactory::getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength) 271 { 272 ASSERT(stream); 273 if (stream->isEmpty()) 274 return false; 275 276 PathTraversalState traversalState(PathTraversalState::TraversalTotalLength); 277 SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0); 278 279 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); 280 SVGPathParser* parser = globalSVGPathParser(source.get(), builder); 281 bool ok = parser->parsePathDataFromSource(NormalizedParsing); 282 totalLength = builder->totalLength(); 283 parser->cleanup(); 284 return ok; 285 } 286 287 bool SVGPathParserFactory::getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, FloatPoint& point) 288 { 289 ASSERT(stream); 290 if (stream->isEmpty()) 291 return false; 292 293 PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength); 294 SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length); 295 296 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); 297 SVGPathParser* parser = globalSVGPathParser(source.get(), builder); 298 bool ok = parser->parsePathDataFromSource(NormalizedParsing); 299 point = builder->currentPoint(); 300 parser->cleanup(); 301 return ok; 302 } 303 270 304 } 271 305 -
trunk/Source/WebCore/svg/SVGPathParserFactory.h
r74493 r86973 55 55 bool buildAnimatedSVGPathByteStream(SVGPathByteStream*, SVGPathByteStream*, OwnPtr<SVGPathByteStream>&, float); 56 56 bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream*, float length, unsigned long& pathSeg); 57 bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream*, float& totalLength); 58 bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream*, float length, FloatPoint&); 57 59 58 60 private: -
trunk/Source/WebCore/svg/SVGPathTraversalStateBuilder.cpp
r65605 r86973 66 66 bool SVGPathTraversalStateBuilder::continueConsuming() 67 67 { 68 ASSERT(m_traversalState); 69 ASSERT(m_traversalState->m_action == PathTraversalState::TraversalSegmentAtLength); 70 return m_traversalState->m_totalLength < m_traversalState->m_desiredLength; 68 ASSERT(m_traversalState); 69 if (m_traversalState->m_action == PathTraversalState::TraversalSegmentAtLength 70 && m_traversalState->m_totalLength >= m_traversalState->m_desiredLength) 71 m_traversalState->m_success = true; 72 73 if ((m_traversalState->m_action == PathTraversalState::TraversalPointAtLength 74 || m_traversalState->m_action == PathTraversalState::TraversalNormalAngleAtLength) 75 && m_traversalState->m_totalLength >= m_traversalState->m_desiredLength) { 76 FloatSize change = m_traversalState->m_current - m_traversalState->m_previous; 77 float slope = atan2f(change.height(), change.width()); 78 if (m_traversalState->m_action == PathTraversalState::TraversalPointAtLength) { 79 float offset = m_traversalState->m_desiredLength - m_traversalState->m_totalLength; 80 m_traversalState->m_current.move(offset * cosf(slope), offset * sinf(slope)); 81 } else 82 m_traversalState->m_normalAngle = rad2deg(slope); 83 m_traversalState->m_success = true; 84 } 85 m_traversalState->m_previous = m_traversalState->m_current; 86 87 return !m_traversalState->m_success; 71 88 } 72 89 … … 83 100 } 84 101 102 float SVGPathTraversalStateBuilder::totalLength() 103 { 104 ASSERT(m_traversalState); 105 return m_traversalState->m_totalLength; 106 } 107 108 FloatPoint SVGPathTraversalStateBuilder::currentPoint() 109 { 110 ASSERT(m_traversalState); 111 return m_traversalState->m_current; 112 } 113 85 114 } 86 115 -
trunk/Source/WebCore/svg/SVGPathTraversalStateBuilder.h
r65605 r86973 34 34 35 35 unsigned long pathSegmentIndex(); 36 float totalLength(); 37 FloatPoint currentPoint(); 38 36 39 void setCurrentTraversalState(PathTraversalState* traversalState) { m_traversalState = traversalState; } 37 40 void setDesiredLength(float);
Note: See TracChangeset
for help on using the changeset viewer.