Cleanup and simplification of SVG path-related classes
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Oct 2015 03:34:08 +0000 (03:34 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Oct 2015 03:34:08 +0000 (03:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150011

Reviewed by Zalan Bujtas.

Many SVG path-related subclasses were stateful, but only because code in
SVGPathUtilities kept global copies around for no reason. A microbenchmark
showed that there was no benefit to keeping global singletons of SVGPathBuilder,
SVGPathSegListBuilder, SVGPathByteStreamBuilder, SVGPathStringBuilder,
SVGPathTraversalStateBuilder, SVGPathParser and SVGPathBlender.

Making these classes not be re-usable makes the code much simpler, allowing
their SVGPathSources, SVGPathConsumers, SVGPathByteStream etc. to be stored
by reference, and eliminating the cleanup() function which created annoying
ordering issues.

Code that uses SVGPathParser and SVGPathBlender is further simplified by having
these classes expose only static functions, hiding any internal statefulness.

* svg/SVGPathBlender.cpp: Remove the m_progress member variable and instead
pass progress to the various blend functions, as we do for other blend functions.
Expose two only static functions. Pointers to references.
(WebCore::SVGPathBlender::addAnimatedPath):
(WebCore::SVGPathBlender::blendAnimatedPath):
(WebCore::SVGPathBlender::SVGPathBlender):
(WebCore::SVGPathBlender::blendAnimatedDimensonalFloat):
(WebCore::SVGPathBlender::blendAnimatedFloatPoint):
(WebCore::SVGPathBlender::blendMoveToSegment):
(WebCore::SVGPathBlender::blendLineToSegment):
(WebCore::SVGPathBlender::blendLineToHorizontalSegment):
(WebCore::SVGPathBlender::blendLineToVerticalSegment):
(WebCore::SVGPathBlender::blendCurveToCubicSegment):
(WebCore::SVGPathBlender::blendCurveToCubicSmoothSegment):
(WebCore::SVGPathBlender::blendCurveToQuadraticSegment):
(WebCore::SVGPathBlender::blendCurveToQuadraticSmoothSegment):
(WebCore::SVGPathBlender::blendArcToSegment):
(WebCore::SVGPathBlender::cleanup): Deleted.
* svg/SVGPathBlender.h: Make the constructor take a ref to the destination Path,
which is stored by reference.
* svg/SVGPathBuilder.cpp:
(WebCore::SVGPathBuilder::SVGPathBuilder):
(WebCore::SVGPathBuilder::moveTo):
(WebCore::SVGPathBuilder::lineTo):
(WebCore::SVGPathBuilder::curveToCubic):
(WebCore::SVGPathBuilder::closePath):
* svg/SVGPathBuilder.h:
(WebCore::SVGPathBuilder::setCurrentPath): Deleted.
* svg/SVGPathByteStreamBuilder.cpp: References, assertions removed.
(WebCore::SVGPathByteStreamBuilder::SVGPathByteStreamBuilder):
* svg/SVGPathByteStreamBuilder.h:
(WebCore::SVGPathByteStreamBuilder::writeType):
(WebCore::SVGPathByteStreamBuilder::setCurrentByteStream): Deleted.
* svg/SVGPathConsumer.h:
* svg/SVGPathElement.cpp:
* svg/SVGPathParser.cpp: Expose some static helper functions for parsing
to byte streams and strings. References.
(WebCore::SVGPathParser::parse):
(WebCore::SVGPathParser::parseToByteStream):
(WebCore::SVGPathParser::parseToString):
(WebCore::SVGPathParser::SVGPathParser):
(WebCore::SVGPathParser::parseClosePathSegment):
(WebCore::SVGPathParser::parseMoveToSegment):
(WebCore::SVGPathParser::parseLineToSegment):
(WebCore::SVGPathParser::parseLineToHorizontalSegment):
(WebCore::SVGPathParser::parseLineToVerticalSegment):
(WebCore::SVGPathParser::parseCurveToCubicSegment):
(WebCore::SVGPathParser::parseCurveToCubicSmoothSegment):
(WebCore::SVGPathParser::parseCurveToQuadraticSegment):
(WebCore::SVGPathParser::parseCurveToQuadraticSmoothSegment):
(WebCore::SVGPathParser::parseArcToSegment):
(WebCore::SVGPathParser::parsePathData):
(WebCore::SVGPathParser::decomposeArcToCubic):
(WebCore::SVGPathParser::parsePathDataFromSource): Deleted.
(WebCore::SVGPathParser::cleanup): Deleted.
* svg/SVGPathParser.h:
(WebCore::SVGPathParser::setCurrentConsumer): Deleted.
(WebCore::SVGPathParser::setCurrentSource): Deleted.
* svg/SVGPathSegListBuilder.cpp:
(WebCore::SVGPathSegListBuilder::SVGPathSegListBuilder):
(WebCore::SVGPathSegListBuilder::moveTo):
(WebCore::SVGPathSegListBuilder::lineTo):
(WebCore::SVGPathSegListBuilder::lineToHorizontal):
(WebCore::SVGPathSegListBuilder::lineToVertical):
(WebCore::SVGPathSegListBuilder::curveToCubic):
(WebCore::SVGPathSegListBuilder::curveToCubicSmooth):
(WebCore::SVGPathSegListBuilder::curveToQuadratic):
(WebCore::SVGPathSegListBuilder::curveToQuadraticSmooth):
(WebCore::SVGPathSegListBuilder::arcTo):
(WebCore::SVGPathSegListBuilder::closePath):
* svg/SVGPathSegListBuilder.h:
(WebCore::SVGPathSegListBuilder::setCurrentSVGPathElement): Deleted.
(WebCore::SVGPathSegListBuilder::setCurrentSVGPathSegList): Deleted.
(WebCore::SVGPathSegListBuilder::setCurrentSVGPathSegRole): Deleted.
* svg/SVGPathStringBuilder.cpp:
(WebCore::SVGPathStringBuilder::cleanup): Deleted.
* svg/SVGPathStringBuilder.h:
* svg/SVGPathTraversalStateBuilder.cpp:
(WebCore::SVGPathTraversalStateBuilder::SVGPathTraversalStateBuilder):
(WebCore::SVGPathTraversalStateBuilder::moveTo):
(WebCore::SVGPathTraversalStateBuilder::lineTo):
(WebCore::SVGPathTraversalStateBuilder::curveToCubic):
(WebCore::SVGPathTraversalStateBuilder::closePath):
(WebCore::SVGPathTraversalStateBuilder::continueConsuming):
(WebCore::SVGPathTraversalStateBuilder::totalLength):
(WebCore::SVGPathTraversalStateBuilder::currentPoint):
(WebCore::SVGPathTraversalStateBuilder::setDesiredLength): Deleted.
* svg/SVGPathTraversalStateBuilder.h:
(WebCore::SVGPathTraversalStateBuilder::pathSegmentIndex):
(WebCore::SVGPathTraversalStateBuilder::setCurrentTraversalState): Deleted.
* svg/SVGPathUtilities.cpp: Remove globals accessors, making things on the stack
instead. Use SVGPathParser helper functions where possible.
(WebCore::buildPathFromString):
(WebCore::buildSVGPathByteStreamFromSVGPathSegList):
(WebCore::appendSVGPathByteStreamFromSVGPathSeg):
(WebCore::buildPathFromByteStream):
(WebCore::buildSVGPathSegListFromByteStream):
(WebCore::buildStringFromByteStream):
(WebCore::buildStringFromSVGPathSegList):
(WebCore::buildSVGPathByteStreamFromString):
(WebCore::buildAnimatedSVGPathByteStream):
(WebCore::addToSVGPathByteStream):
(WebCore::getSVGPathSegAtLengthFromSVGPathByteStream):
(WebCore::getTotalLengthOfSVGPathByteStream):
(WebCore::getPointAtLengthOfSVGPathByteStream):
(WebCore::buildStringFromPath):
(WebCore::globalSVGPathBuilder): Deleted.
(WebCore::globalSVGPathSegListBuilder): Deleted.
(WebCore::globalSVGPathByteStreamBuilder): Deleted.
(WebCore::globalSVGPathStringBuilder): Deleted.
(WebCore::globalSVGPathTraversalStateBuilder): Deleted.
(WebCore::globalSVGPathParser): Deleted.
(WebCore::globalSVGPathBlender): Deleted.
* svg/SVGPathUtilities.h:
* svg/SVGToOTFFontConversion.cpp: CFFBuilder no longer inherits from SVGPathBuilder.
It did nothing with the Path, re-implemented all the functions, and only made use of
the m_current member var, so just make it inherit from SVGPathConsumer, and have
its own m_current.
(WebCore::SVGToOTFFontConverter::transcodeGlyphPaths):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@190849 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
Source/WebCore/ChangeLog
Source/WebCore/svg/SVGPathBlender.cpp
Source/WebCore/svg/SVGPathBlender.h
Source/WebCore/svg/SVGPathBuilder.cpp
Source/WebCore/svg/SVGPathBuilder.h
Source/WebCore/svg/SVGPathByteStreamBuilder.cpp
Source/WebCore/svg/SVGPathByteStreamBuilder.h
Source/WebCore/svg/SVGPathConsumer.h
Source/WebCore/svg/SVGPathElement.cpp
Source/WebCore/svg/SVGPathParser.cpp
Source/WebCore/svg/SVGPathParser.h
Source/WebCore/svg/SVGPathSegListBuilder.cpp
Source/WebCore/svg/SVGPathSegListBuilder.h
Source/WebCore/svg/SVGPathStringBuilder.cpp
Source/WebCore/svg/SVGPathStringBuilder.h
Source/WebCore/svg/SVGPathTraversalStateBuilder.cpp
Source/WebCore/svg/SVGPathTraversalStateBuilder.h
Source/WebCore/svg/SVGPathUtilities.cpp
Source/WebCore/svg/SVGPathUtilities.h
Source/WebCore/svg/SVGToOTFFontConversion.cpp

index 2a46791..8ea0747 100644 (file)
@@ -1,3 +1,144 @@
+2015-10-11  Simon Fraser  <simon.fraser@apple.com>
+
+        Cleanup and simplification of SVG path-related classes
+        https://bugs.webkit.org/show_bug.cgi?id=150011
+
+        Reviewed by Zalan Bujtas.
+
+        Many SVG path-related subclasses were stateful, but only because code in
+        SVGPathUtilities kept global copies around for no reason. A microbenchmark
+        showed that there was no benefit to keeping global singletons of SVGPathBuilder,
+        SVGPathSegListBuilder, SVGPathByteStreamBuilder, SVGPathStringBuilder,
+        SVGPathTraversalStateBuilder, SVGPathParser and SVGPathBlender.
+        
+        Making these classes not be re-usable makes the code much simpler, allowing
+        their SVGPathSources, SVGPathConsumers, SVGPathByteStream etc. to be stored
+        by reference, and eliminating the cleanup() function which created annoying
+        ordering issues.
+        
+        Code that uses SVGPathParser and SVGPathBlender is further simplified by having
+        these classes expose only static functions, hiding any internal statefulness.
+
+        * svg/SVGPathBlender.cpp: Remove the m_progress member variable and instead
+        pass progress to the various blend functions, as we do for other blend functions.
+        Expose two only static functions. Pointers to references.
+        (WebCore::SVGPathBlender::addAnimatedPath):
+        (WebCore::SVGPathBlender::blendAnimatedPath):
+        (WebCore::SVGPathBlender::SVGPathBlender):
+        (WebCore::SVGPathBlender::blendAnimatedDimensonalFloat):
+        (WebCore::SVGPathBlender::blendAnimatedFloatPoint):
+        (WebCore::SVGPathBlender::blendMoveToSegment):
+        (WebCore::SVGPathBlender::blendLineToSegment):
+        (WebCore::SVGPathBlender::blendLineToHorizontalSegment):
+        (WebCore::SVGPathBlender::blendLineToVerticalSegment):
+        (WebCore::SVGPathBlender::blendCurveToCubicSegment):
+        (WebCore::SVGPathBlender::blendCurveToCubicSmoothSegment):
+        (WebCore::SVGPathBlender::blendCurveToQuadraticSegment):
+        (WebCore::SVGPathBlender::blendCurveToQuadraticSmoothSegment):
+        (WebCore::SVGPathBlender::blendArcToSegment):
+        (WebCore::SVGPathBlender::cleanup): Deleted.
+        * svg/SVGPathBlender.h: Make the constructor take a ref to the destination Path,
+        which is stored by reference.
+        * svg/SVGPathBuilder.cpp:
+        (WebCore::SVGPathBuilder::SVGPathBuilder):
+        (WebCore::SVGPathBuilder::moveTo):
+        (WebCore::SVGPathBuilder::lineTo):
+        (WebCore::SVGPathBuilder::curveToCubic):
+        (WebCore::SVGPathBuilder::closePath):
+        * svg/SVGPathBuilder.h:
+        (WebCore::SVGPathBuilder::setCurrentPath): Deleted.
+        * svg/SVGPathByteStreamBuilder.cpp: References, assertions removed.
+        (WebCore::SVGPathByteStreamBuilder::SVGPathByteStreamBuilder):
+        * svg/SVGPathByteStreamBuilder.h:
+        (WebCore::SVGPathByteStreamBuilder::writeType):
+        (WebCore::SVGPathByteStreamBuilder::setCurrentByteStream): Deleted.
+        * svg/SVGPathConsumer.h:
+        * svg/SVGPathElement.cpp:
+        * svg/SVGPathParser.cpp: Expose some static helper functions for parsing
+        to byte streams and strings. References.
+        (WebCore::SVGPathParser::parse):
+        (WebCore::SVGPathParser::parseToByteStream):
+        (WebCore::SVGPathParser::parseToString):
+        (WebCore::SVGPathParser::SVGPathParser):
+        (WebCore::SVGPathParser::parseClosePathSegment):
+        (WebCore::SVGPathParser::parseMoveToSegment):
+        (WebCore::SVGPathParser::parseLineToSegment):
+        (WebCore::SVGPathParser::parseLineToHorizontalSegment):
+        (WebCore::SVGPathParser::parseLineToVerticalSegment):
+        (WebCore::SVGPathParser::parseCurveToCubicSegment):
+        (WebCore::SVGPathParser::parseCurveToCubicSmoothSegment):
+        (WebCore::SVGPathParser::parseCurveToQuadraticSegment):
+        (WebCore::SVGPathParser::parseCurveToQuadraticSmoothSegment):
+        (WebCore::SVGPathParser::parseArcToSegment):
+        (WebCore::SVGPathParser::parsePathData):
+        (WebCore::SVGPathParser::decomposeArcToCubic):
+        (WebCore::SVGPathParser::parsePathDataFromSource): Deleted.
+        (WebCore::SVGPathParser::cleanup): Deleted.
+        * svg/SVGPathParser.h:
+        (WebCore::SVGPathParser::setCurrentConsumer): Deleted.
+        (WebCore::SVGPathParser::setCurrentSource): Deleted.
+        * svg/SVGPathSegListBuilder.cpp:
+        (WebCore::SVGPathSegListBuilder::SVGPathSegListBuilder):
+        (WebCore::SVGPathSegListBuilder::moveTo):
+        (WebCore::SVGPathSegListBuilder::lineTo):
+        (WebCore::SVGPathSegListBuilder::lineToHorizontal):
+        (WebCore::SVGPathSegListBuilder::lineToVertical):
+        (WebCore::SVGPathSegListBuilder::curveToCubic):
+        (WebCore::SVGPathSegListBuilder::curveToCubicSmooth):
+        (WebCore::SVGPathSegListBuilder::curveToQuadratic):
+        (WebCore::SVGPathSegListBuilder::curveToQuadraticSmooth):
+        (WebCore::SVGPathSegListBuilder::arcTo):
+        (WebCore::SVGPathSegListBuilder::closePath):
+        * svg/SVGPathSegListBuilder.h:
+        (WebCore::SVGPathSegListBuilder::setCurrentSVGPathElement): Deleted.
+        (WebCore::SVGPathSegListBuilder::setCurrentSVGPathSegList): Deleted.
+        (WebCore::SVGPathSegListBuilder::setCurrentSVGPathSegRole): Deleted.
+        * svg/SVGPathStringBuilder.cpp:
+        (WebCore::SVGPathStringBuilder::cleanup): Deleted.
+        * svg/SVGPathStringBuilder.h:
+        * svg/SVGPathTraversalStateBuilder.cpp:
+        (WebCore::SVGPathTraversalStateBuilder::SVGPathTraversalStateBuilder):
+        (WebCore::SVGPathTraversalStateBuilder::moveTo):
+        (WebCore::SVGPathTraversalStateBuilder::lineTo):
+        (WebCore::SVGPathTraversalStateBuilder::curveToCubic):
+        (WebCore::SVGPathTraversalStateBuilder::closePath):
+        (WebCore::SVGPathTraversalStateBuilder::continueConsuming):
+        (WebCore::SVGPathTraversalStateBuilder::totalLength):
+        (WebCore::SVGPathTraversalStateBuilder::currentPoint):
+        (WebCore::SVGPathTraversalStateBuilder::setDesiredLength): Deleted.
+        * svg/SVGPathTraversalStateBuilder.h:
+        (WebCore::SVGPathTraversalStateBuilder::pathSegmentIndex):
+        (WebCore::SVGPathTraversalStateBuilder::setCurrentTraversalState): Deleted.
+        * svg/SVGPathUtilities.cpp: Remove globals accessors, making things on the stack
+        instead. Use SVGPathParser helper functions where possible.
+        (WebCore::buildPathFromString):
+        (WebCore::buildSVGPathByteStreamFromSVGPathSegList):
+        (WebCore::appendSVGPathByteStreamFromSVGPathSeg):
+        (WebCore::buildPathFromByteStream):
+        (WebCore::buildSVGPathSegListFromByteStream):
+        (WebCore::buildStringFromByteStream):
+        (WebCore::buildStringFromSVGPathSegList):
+        (WebCore::buildSVGPathByteStreamFromString):
+        (WebCore::buildAnimatedSVGPathByteStream):
+        (WebCore::addToSVGPathByteStream):
+        (WebCore::getSVGPathSegAtLengthFromSVGPathByteStream):
+        (WebCore::getTotalLengthOfSVGPathByteStream):
+        (WebCore::getPointAtLengthOfSVGPathByteStream):
+        (WebCore::buildStringFromPath):
+        (WebCore::globalSVGPathBuilder): Deleted.
+        (WebCore::globalSVGPathSegListBuilder): Deleted.
+        (WebCore::globalSVGPathByteStreamBuilder): Deleted.
+        (WebCore::globalSVGPathStringBuilder): Deleted.
+        (WebCore::globalSVGPathTraversalStateBuilder): Deleted.
+        (WebCore::globalSVGPathParser): Deleted.
+        (WebCore::globalSVGPathBlender): Deleted.
+        * svg/SVGPathUtilities.h:
+        * svg/SVGToOTFFontConversion.cpp: CFFBuilder no longer inherits from SVGPathBuilder.
+        It did nothing with the Path, re-implemented all the functions, and only made use of
+        the m_current member var, so just make it inherit from SVGPathConsumer, and have
+        its own m_current.
+        (WebCore::SVGToOTFFontConverter::transcodeGlyphPaths):
+
 2015-10-10  Antti Koivisto  <antti@apple.com>
 
         Remove InsertionPoint and ContentDistributor
index c21d57f..7aa84e8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 
 namespace WebCore {
 
-SVGPathBlender::SVGPathBlender()
-    : m_fromSource(nullptr)
-    , m_toSource(nullptr)
-    , m_consumer(nullptr)
-    , m_progress(0)
-    , m_addTypesCount(0)
-    , m_isInFirstHalfOfAnimation(false)
+bool SVGPathBlender::addAnimatedPath(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer& consumer, unsigned repeatCount)
+{
+    SVGPathBlender blender(fromSource, toSource, consumer);
+    return blender.addAnimatedPath(repeatCount);
+}
+
+bool SVGPathBlender::blendAnimatedPath(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer& consumer, float progress)
+{
+    SVGPathBlender blender(fromSource, toSource, consumer);
+    return blender.blendAnimatedPath(progress);
+}
+
+SVGPathBlender::SVGPathBlender(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer& consumer)
+    : m_fromSource(fromSource)
+    , m_toSource(toSource)
+    , m_consumer(consumer)
 {
 }
 
@@ -43,7 +53,7 @@ static inline FloatPoint blendFloatPoint(const FloatPoint& a, const FloatPoint&
     return FloatPoint(blend(a.x(), b.x(), progress), blend(a.y(), b.y(), progress));
 }
 
-float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode blendMode)
+float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode blendMode, float progress)
 {
     if (m_addTypesCount) {
         ASSERT(m_fromMode == m_toMode);
@@ -51,23 +61,23 @@ float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBl
     }
 
     if (m_fromMode == m_toMode)
-        return blend(from, to, m_progress);
+        return blend(from, to, progress);
     
     float fromValue = blendMode == BlendHorizontal ? m_fromCurrentPoint.x() : m_fromCurrentPoint.y();
     float toValue = blendMode == BlendHorizontal ? m_toCurrentPoint.x() : m_toCurrentPoint.y();
 
     // Transform toY to the coordinate mode of fromY
-    float animValue = blend(from, m_fromMode == AbsoluteCoordinates ? to + toValue : to - toValue, m_progress);
+    float animValue = blend(from, m_fromMode == AbsoluteCoordinates ? to + toValue : to - toValue, progress);
     
     if (m_isInFirstHalfOfAnimation)
         return animValue;
     
     // Transform the animated point to the coordinate mode, needed for the current progress.
-    float currentValue = blend(fromValue, toValue, m_progress);
+    float currentValue = blend(fromValue, toValue, progress);
     return m_toMode == AbsoluteCoordinates ? animValue + currentValue : animValue - currentValue;
 }
 
-FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint)
+FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint, float progress)
 {
     if (m_addTypesCount) {
         ASSERT(m_fromMode == m_toMode);
@@ -77,7 +87,7 @@ FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint,
     }
 
     if (m_fromMode == m_toMode)
-        return blendFloatPoint(fromPoint, toPoint, m_progress);
+        return blendFloatPoint(fromPoint, toPoint, progress);
 
     // Transform toPoint to the coordinate mode of fromPoint
     FloatPoint animatedPoint = toPoint;
@@ -86,13 +96,13 @@ FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint,
     else
         animatedPoint.move(-m_toCurrentPoint.x(), -m_toCurrentPoint.y());
 
-    animatedPoint = blendFloatPoint(fromPoint, animatedPoint, m_progress);
+    animatedPoint = blendFloatPoint(fromPoint, animatedPoint, progress);
 
     if (m_isInFirstHalfOfAnimation)
         return animatedPoint;
 
     // Transform the animated point to the coordinate mode, needed for the current progress.
-    FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoint, m_progress);
+    FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoint, progress);
     if (m_toMode == AbsoluteCoordinates)
         return animatedPoint + currentPoint;
 
@@ -100,63 +110,63 @@ FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint,
     return animatedPoint;
 }
 
-bool SVGPathBlender::blendMoveToSegment()
+bool SVGPathBlender::blendMoveToSegment(float progress)
 {
     FloatPoint fromTargetPoint;
     FloatPoint toTargetPoint;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseMoveToSegment(fromTargetPoint))
-        || !m_toSource->parseMoveToSegment(toTargetPoint))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseMoveToSegment(fromTargetPoint))
+        || !m_toSource.parseMoveToSegment(toTargetPoint))
         return false;
 
-    m_consumer->moveTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), false, m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.moveTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), false, m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint;
     m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint;
     return true;
 }
 
-bool SVGPathBlender::blendLineToSegment()
+bool SVGPathBlender::blendLineToSegment(float progress)
 {
     FloatPoint fromTargetPoint;
     FloatPoint toTargetPoint;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseLineToSegment(fromTargetPoint))
-        || !m_toSource->parseLineToSegment(toTargetPoint))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseLineToSegment(fromTargetPoint))
+        || !m_toSource.parseLineToSegment(toTargetPoint))
         return false;
 
-    m_consumer->lineTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.lineTo(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint;
     m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint;
     return true;
 }
 
-bool SVGPathBlender::blendLineToHorizontalSegment()
+bool SVGPathBlender::blendLineToHorizontalSegment(float progress)
 {
     float fromX = 0;
     float toX = 0;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseLineToHorizontalSegment(fromX))
-        || !m_toSource->parseLineToHorizontalSegment(toX))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseLineToHorizontalSegment(fromX))
+        || !m_toSource.parseLineToHorizontalSegment(toX))
         return false;
 
-    m_consumer->lineToHorizontal(blendAnimatedDimensonalFloat(fromX, toX, BlendHorizontal), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.lineToHorizontal(blendAnimatedDimensonalFloat(fromX, toX, BlendHorizontal, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint.setX(m_fromMode == AbsoluteCoordinates ? fromX : m_fromCurrentPoint.x() + fromX);
     m_toCurrentPoint.setX(m_toMode == AbsoluteCoordinates ? toX : m_toCurrentPoint.x() + toX);
     return true;
 }
 
-bool SVGPathBlender::blendLineToVerticalSegment()
+bool SVGPathBlender::blendLineToVerticalSegment(float progress)
 {
     float fromY = 0;
     float toY = 0;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseLineToVerticalSegment(fromY))
-        || !m_toSource->parseLineToVerticalSegment(toY))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseLineToVerticalSegment(fromY))
+        || !m_toSource.parseLineToVerticalSegment(toY))
         return false;
 
-    m_consumer->lineToVertical(blendAnimatedDimensonalFloat(fromY, toY, BlendVertical), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.lineToVertical(blendAnimatedDimensonalFloat(fromY, toY, BlendVertical, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint.setY(m_fromMode == AbsoluteCoordinates ? fromY : m_fromCurrentPoint.y() + fromY);
     m_toCurrentPoint.setY(m_toMode == AbsoluteCoordinates ? toY : m_toCurrentPoint.y() + toY);
     return true;
 }
 
-bool SVGPathBlender::blendCurveToCubicSegment()
+bool SVGPathBlender::blendCurveToCubicSegment(float progress)
 {
     FloatPoint fromTargetPoint;
     FloatPoint fromPoint1;
@@ -164,70 +174,70 @@ bool SVGPathBlender::blendCurveToCubicSegment()
     FloatPoint toTargetPoint;
     FloatPoint toPoint1;
     FloatPoint toPoint2;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToCubicSegment(fromPoint1, fromPoint2, fromTargetPoint))
-        || !m_toSource->parseCurveToCubicSegment(toPoint1, toPoint2, toTargetPoint))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToCubicSegment(fromPoint1, fromPoint2, fromTargetPoint))
+        || !m_toSource.parseCurveToCubicSegment(toPoint1, toPoint2, toTargetPoint))
         return false;
 
-    m_consumer->curveToCubic(blendAnimatedFloatPoint(fromPoint1, toPoint1),
-                             blendAnimatedFloatPoint(fromPoint2, toPoint2),
-                             blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint),
-                             m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.curveToCubic(blendAnimatedFloatPoint(fromPoint1, toPoint1, progress),
+        blendAnimatedFloatPoint(fromPoint2, toPoint2, progress),
+        blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress),
+        m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint;
     m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint;
     return true;
 }
 
-bool SVGPathBlender::blendCurveToCubicSmoothSegment()
+bool SVGPathBlender::blendCurveToCubicSmoothSegment(float progress)
 {
     FloatPoint fromTargetPoint;
     FloatPoint fromPoint2;
     FloatPoint toTargetPoint;
     FloatPoint toPoint2;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToCubicSmoothSegment(fromPoint2, fromTargetPoint))
-        || !m_toSource->parseCurveToCubicSmoothSegment(toPoint2, toTargetPoint))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToCubicSmoothSegment(fromPoint2, fromTargetPoint))
+        || !m_toSource.parseCurveToCubicSmoothSegment(toPoint2, toTargetPoint))
         return false;
 
-    m_consumer->curveToCubicSmooth(blendAnimatedFloatPoint(fromPoint2, toPoint2),
-                                   blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint),
-                                   m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.curveToCubicSmooth(blendAnimatedFloatPoint(fromPoint2, toPoint2, progress),
+        blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress),
+        m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint;
     m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint;
     return true;
 }
 
-bool SVGPathBlender::blendCurveToQuadraticSegment()
+bool SVGPathBlender::blendCurveToQuadraticSegment(float progress)
 {
     FloatPoint fromTargetPoint;
     FloatPoint fromPoint1;
     FloatPoint toTargetPoint;
     FloatPoint toPoint1;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToQuadraticSegment(fromPoint1, fromTargetPoint))
-        || !m_toSource->parseCurveToQuadraticSegment(toPoint1, toTargetPoint))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToQuadraticSegment(fromPoint1, fromTargetPoint))
+        || !m_toSource.parseCurveToQuadraticSegment(toPoint1, toTargetPoint))
         return false;
 
-    m_consumer->curveToQuadratic(blendAnimatedFloatPoint(fromPoint1, toPoint1),
-                                 blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint),
-                                 m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.curveToQuadratic(blendAnimatedFloatPoint(fromPoint1, toPoint1, progress),
+        blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress),
+        m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint;
     m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint;
     return true;
 }
 
-bool SVGPathBlender::blendCurveToQuadraticSmoothSegment()
+bool SVGPathBlender::blendCurveToQuadraticSmoothSegment(float progress)
 {
     FloatPoint fromTargetPoint;
     FloatPoint toTargetPoint;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseCurveToQuadraticSmoothSegment(fromTargetPoint))
-        || !m_toSource->parseCurveToQuadraticSmoothSegment(toTargetPoint))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseCurveToQuadraticSmoothSegment(fromTargetPoint))
+        || !m_toSource.parseCurveToQuadraticSmoothSegment(toTargetPoint))
         return false;
 
-    m_consumer->curveToQuadraticSmooth(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+    m_consumer.curveToQuadraticSmooth(blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint;
     m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint;
     return true;
 }
 
-bool SVGPathBlender::blendArcToSegment()
+bool SVGPathBlender::blendArcToSegment(float progress)
 {
     float fromRx = 0;
     float fromRy = 0;
@@ -241,29 +251,29 @@ bool SVGPathBlender::blendArcToSegment()
     bool toLargeArc = false;
     bool toSweep = false;
     FloatPoint toTargetPoint;
-    if ((m_fromSource->hasMoreData() && !m_fromSource->parseArcToSegment(fromRx, fromRy, fromAngle, fromLargeArc, fromSweep, fromTargetPoint))
-        || !m_toSource->parseArcToSegment(toRx, toRy, toAngle, toLargeArc, toSweep, toTargetPoint))
+    if ((m_fromSource.hasMoreData() && !m_fromSource.parseArcToSegment(fromRx, fromRy, fromAngle, fromLargeArc, fromSweep, fromTargetPoint))
+        || !m_toSource.parseArcToSegment(toRx, toRy, toAngle, toLargeArc, toSweep, toTargetPoint))
         return false;
 
     if (m_addTypesCount) {
         ASSERT(m_fromMode == m_toMode);
         FloatPoint scaledToTargetPoint = toTargetPoint;
         scaledToTargetPoint.scale(m_addTypesCount, m_addTypesCount);
-        m_consumer->arcTo(fromRx + toRx * m_addTypesCount,
-                          fromRy + toRy * m_addTypesCount,
-                          fromAngle + toAngle * m_addTypesCount,
-                          fromLargeArc || toLargeArc,
-                          fromSweep || toSweep,
-                          fromTargetPoint + scaledToTargetPoint,
-                          m_fromMode);
+        m_consumer.arcTo(fromRx + toRx * m_addTypesCount,
+            fromRy + toRy * m_addTypesCount,
+            fromAngle + toAngle * m_addTypesCount,
+            fromLargeArc || toLargeArc,
+            fromSweep || toSweep,
+            fromTargetPoint + scaledToTargetPoint,
+            m_fromMode);
     } else {
-        m_consumer->arcTo(blend(fromRx, toRx, m_progress),
-                          blend(fromRy, toRy, m_progress),
-                          blend(fromAngle, toAngle, m_progress),
-                          m_isInFirstHalfOfAnimation ? fromLargeArc : toLargeArc,
-                          m_isInFirstHalfOfAnimation ? fromSweep : toSweep,
-                          blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint),
-                          m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
+        m_consumer.arcTo(blend(fromRx, toRx, progress),
+            blend(fromRy, toRy, progress),
+            blend(fromAngle, toAngle, progress),
+            m_isInFirstHalfOfAnimation ? fromLargeArc : toLargeArc,
+            m_isInFirstHalfOfAnimation ? fromSweep : toSweep,
+            blendAnimatedFloatPoint(fromTargetPoint, toTargetPoint, progress),
+            m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
     }
     m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? fromTargetPoint : m_fromCurrentPoint + fromTargetPoint;
     m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? toTargetPoint : m_toCurrentPoint + toTargetPoint;
@@ -296,28 +306,21 @@ static inline bool isSegmentEqual(const SVGPathSegType& fromType, const SVGPathS
     return to == from - 1;
 }
 
-bool SVGPathBlender::addAnimatedPath(SVGPathSource* fromSource, SVGPathSource* toSource, SVGPathConsumer* consumer, unsigned repeatCount)
+bool SVGPathBlender::addAnimatedPath(unsigned repeatCount)
 {
     TemporaryChange<unsigned> change(m_addTypesCount, repeatCount);
-    return blendAnimatedPath(0, fromSource, toSource, consumer);
+    return blendAnimatedPath(0);
 }
 
-bool SVGPathBlender::blendAnimatedPath(float progress, SVGPathSource* fromSource, SVGPathSource* toSource, SVGPathConsumer* consumer)
+bool SVGPathBlender::blendAnimatedPath(float progress)
 {
-    ASSERT(fromSource);
-    ASSERT(toSource);
-    ASSERT(consumer);
-    m_fromSource = fromSource;
-    m_toSource = toSource;
-    m_consumer = consumer;
     m_isInFirstHalfOfAnimation = progress < 0.5f;
-    m_progress = progress;
 
-    bool fromSourceHadData = m_fromSource->hasMoreData();
-    while (m_toSource->hasMoreData()) {
+    bool fromSourceHadData = m_fromSource.hasMoreData();
+    while (m_toSource.hasMoreData()) {
         SVGPathSegType fromCommand;
         SVGPathSegType toCommand;
-        if ((fromSourceHadData && !m_fromSource->parseSVGSegmentType(fromCommand)) || !m_toSource->parseSVGSegmentType(toCommand))
+        if ((fromSourceHadData && !m_fromSource.parseSVGSegmentType(fromCommand)) || !m_toSource.parseSVGSegmentType(toCommand))
             return false;
 
         m_toMode = coordinateModeOfCommand(toCommand);
@@ -331,50 +334,50 @@ bool SVGPathBlender::blendAnimatedPath(float progress, SVGPathSource* fromSource
         switch (toCommand) {
         case PathSegMoveToRel:
         case PathSegMoveToAbs:
-            if (!blendMoveToSegment())
+            if (!blendMoveToSegment(progress))
                 return false;
             break;
         case PathSegLineToRel:
         case PathSegLineToAbs:
-            if (!blendLineToSegment())
+            if (!blendLineToSegment(progress))
                 return false;
             break;
         case PathSegLineToHorizontalRel:
         case PathSegLineToHorizontalAbs:
-            if (!blendLineToHorizontalSegment())
+            if (!blendLineToHorizontalSegment(progress))
                 return false;
             break;
         case PathSegLineToVerticalRel:
         case PathSegLineToVerticalAbs:
-            if (!blendLineToVerticalSegment())
+            if (!blendLineToVerticalSegment(progress))
                 return false;
             break;
         case PathSegClosePath:
-            m_consumer->closePath();
+            m_consumer.closePath();
             break;
         case PathSegCurveToCubicRel:
         case PathSegCurveToCubicAbs:
-            if (!blendCurveToCubicSegment())
+            if (!blendCurveToCubicSegment(progress))
                 return false;
             break;
         case PathSegCurveToCubicSmoothRel:
         case PathSegCurveToCubicSmoothAbs:
-            if (!blendCurveToCubicSmoothSegment())
+            if (!blendCurveToCubicSmoothSegment(progress))
                 return false;
             break;
         case PathSegCurveToQuadraticRel:
         case PathSegCurveToQuadraticAbs:
-            if (!blendCurveToQuadraticSegment())
+            if (!blendCurveToQuadraticSegment(progress))
                 return false;
             break;
         case PathSegCurveToQuadraticSmoothRel:
         case PathSegCurveToQuadraticSmoothAbs:
-            if (!blendCurveToQuadraticSmoothSegment())
+            if (!blendCurveToQuadraticSmoothSegment(progress))
                 return false;
             break;
         case PathSegArcRel:
         case PathSegArcAbs:
-            if (!blendArcToSegment())
+            if (!blendArcToSegment(progress))
                 return false;
             break;
         case PathSegUnknown:
@@ -383,27 +386,13 @@ bool SVGPathBlender::blendAnimatedPath(float progress, SVGPathSource* fromSource
 
         if (!fromSourceHadData)
             continue;
-        if (m_fromSource->hasMoreData() != m_toSource->hasMoreData())
+        if (m_fromSource.hasMoreData() != m_toSource.hasMoreData())
             return false;
-        if (!m_fromSource->hasMoreData() || !m_toSource->hasMoreData())
+        if (!m_fromSource.hasMoreData() || !m_toSource.hasMoreData())
             return true;
     }
 
     return true;
 }
 
-void SVGPathBlender::cleanup()
-{
-    ASSERT(m_toSource);
-    ASSERT(m_fromSource);
-    ASSERT(m_consumer);
-
-    m_consumer->cleanup();
-    m_toSource = nullptr;
-    m_fromSource = nullptr;
-    m_consumer = nullptr;
-    m_fromCurrentPoint = FloatPoint();
-    m_toCurrentPoint = FloatPoint();
-}
-
 }
index 06baad1..505d108 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -34,38 +35,40 @@ class SVGPathSource;
 class SVGPathBlender {
     WTF_MAKE_NONCOPYABLE(SVGPathBlender); WTF_MAKE_FAST_ALLOCATED;
 public:
-    SVGPathBlender();
 
-    bool addAnimatedPath(SVGPathSource*, SVGPathSource*, SVGPathConsumer*, unsigned repeatCount);
-    bool blendAnimatedPath(float, SVGPathSource*, SVGPathSource*, SVGPathConsumer*);
-    void cleanup();
+    static bool addAnimatedPath(SVGPathSource& from, SVGPathSource& to, SVGPathConsumer&, unsigned repeatCount);
+    static bool blendAnimatedPath(SVGPathSource& from, SVGPathSource& to, SVGPathConsumer&, float);
 
 private:
-    bool blendMoveToSegment();
-    bool blendLineToSegment();
-    bool blendLineToHorizontalSegment();
-    bool blendLineToVerticalSegment();
-    bool blendCurveToCubicSegment();
-    bool blendCurveToCubicSmoothSegment();
-    bool blendCurveToQuadraticSegment();
-    bool blendCurveToQuadraticSmoothSegment();
-    bool blendArcToSegment();
+    SVGPathBlender(SVGPathSource&, SVGPathSource&, SVGPathConsumer&);
 
-    float blendAnimatedDimensonalFloat(float, float, FloatBlendMode);
-    FloatPoint blendAnimatedFloatPoint(const FloatPoint& from, const FloatPoint& to);
+    bool addAnimatedPath(unsigned repeatCount);
+    bool blendAnimatedPath(float progress);
 
-    SVGPathSource* m_fromSource;
-    SVGPathSource* m_toSource;
-    SVGPathConsumer* m_consumer;
+    bool blendMoveToSegment(float progress);
+    bool blendLineToSegment(float progress);
+    bool blendLineToHorizontalSegment(float progress);
+    bool blendLineToVerticalSegment(float progress);
+    bool blendCurveToCubicSegment(float progress);
+    bool blendCurveToCubicSmoothSegment(float progress);
+    bool blendCurveToQuadraticSegment(float progress);
+    bool blendCurveToQuadraticSmoothSegment(float progress);
+    bool blendArcToSegment(float progress);
+
+    float blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode, float progress);
+    FloatPoint blendAnimatedFloatPoint(const FloatPoint& from, const FloatPoint& to, float progress);
+
+    SVGPathSource& m_fromSource;
+    SVGPathSource& m_toSource;
+    SVGPathConsumer& m_consumer;
 
     FloatPoint m_fromCurrentPoint;
     FloatPoint m_toCurrentPoint;
     
-    PathCoordinateMode m_fromMode;
-    PathCoordinateMode m_toMode;
-    float m_progress;
-    unsigned m_addTypesCount;
-    bool m_isInFirstHalfOfAnimation;
+    PathCoordinateMode m_fromMode { AbsoluteCoordinates };
+    PathCoordinateMode m_toMode { AbsoluteCoordinates };
+    unsigned m_addTypesCount { 0 };
+    bool m_isInFirstHalfOfAnimation { false };
 };
 
 } // namespace WebCore
index cb8e794..d9e141c 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2002, 2003 The Karbon Developers
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
 
 namespace WebCore {
 
-SVGPathBuilder::SVGPathBuilder()
-    : m_path(nullptr)
+SVGPathBuilder::SVGPathBuilder(Path& path)
+    : m_path(path)
 {
 }
 
 void SVGPathBuilder::moveTo(const FloatPoint& targetPoint, bool closed, PathCoordinateMode mode)
 {
-    ASSERT(m_path);
     m_current = mode == AbsoluteCoordinates ? targetPoint : m_current + targetPoint;
-    if (closed && !m_path->isEmpty())
-        m_path->closeSubpath();
-    m_path->moveTo(m_current);
+    if (closed && !m_path.isEmpty())
+        m_path.closeSubpath();
+    m_path.moveTo(m_current);
 }
 
 void SVGPathBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_path);
     m_current = mode == AbsoluteCoordinates ? targetPoint : m_current + targetPoint;
-    m_path->addLineTo(m_current);
+    m_path.addLineTo(m_current);
 }
 
 void SVGPathBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_path);
     if (mode == RelativeCoordinates) {
-        m_path->addBezierCurveTo(m_current + point1, m_current + point2, m_current + targetPoint);
+        m_path.addBezierCurveTo(m_current + point1, m_current + point2, m_current + targetPoint);
         m_current += targetPoint;
     } else {
         m_current = targetPoint;
-        m_path->addBezierCurveTo(point1, point2, m_current);
+        m_path.addBezierCurveTo(point1, point2, m_current);
     }    
 }
 
 void SVGPathBuilder::closePath()
 {
-    ASSERT(m_path);
-    m_path->closeSubpath();
+    m_path.closeSubpath();
 }
 
 }
index 7efbb4d..94f332d 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2002, 2003 The Karbon Developers
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -33,17 +33,11 @@ class Path;
 
 class SVGPathBuilder : public SVGPathConsumer {
 public:
-    SVGPathBuilder();
-
-    void setCurrentPath(Path* path) { m_path = path; }
-
-protected:
-    FloatPoint m_current;
+    SVGPathBuilder(Path&);
 
 private:
     virtual void incrementPathSegmentCount() override { }
     virtual bool continueConsuming() override { return true; }
-    virtual void cleanup() override { m_path = nullptr; }
 
     // Used in UnalteredParsing/NormalizedParsing modes.
     virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override;
@@ -59,7 +53,8 @@ private:
     virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
     virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
 
-    Path* m_path;
+    Path& m_path;
+    FloatPoint m_current;
 };
 
 } // namespace WebCore
index 2f4d85c..d195c28 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #include "config.h"
 #include "SVGPathByteStreamBuilder.h"
 
-#include "SVGPathParser.h"
 #include "SVGPathSeg.h"
 #include "SVGPathStringSource.h"
 
 namespace WebCore {
 
-SVGPathByteStreamBuilder::SVGPathByteStreamBuilder()
-    : m_byteStream(nullptr)
+SVGPathByteStreamBuilder::SVGPathByteStreamBuilder(SVGPathByteStream& byteStream)
+    : m_byteStream(byteStream)
 {
 }
 
 void SVGPathByteStreamBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ?  PathSegMoveToRel : PathSegMoveToAbs);
     writeFloatPoint(targetPoint);
 }
 
 void SVGPathByteStreamBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegLineToRel : PathSegLineToAbs);
     writeFloatPoint(targetPoint);
 }
 
 void SVGPathByteStreamBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegLineToHorizontalRel : PathSegLineToHorizontalAbs);
     writeFloat(x);
 }
 
 void SVGPathByteStreamBuilder::lineToVertical(float y, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegLineToVerticalRel : PathSegLineToVerticalAbs);
     writeFloat(y);
 }
 
 void SVGPathByteStreamBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicRel : PathSegCurveToCubicAbs);
     writeFloatPoint(point1);
     writeFloatPoint(point2);
@@ -70,7 +65,6 @@ void SVGPathByteStreamBuilder::curveToCubic(const FloatPoint& point1, const Floa
 
 void SVGPathByteStreamBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicSmoothRel : PathSegCurveToCubicSmoothAbs);
     writeFloatPoint(point2);
     writeFloatPoint(targetPoint);
@@ -78,7 +72,6 @@ void SVGPathByteStreamBuilder::curveToCubicSmooth(const FloatPoint& point2, cons
 
 void SVGPathByteStreamBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticRel : PathSegCurveToQuadraticAbs);
     writeFloatPoint(point1);
     writeFloatPoint(targetPoint);
@@ -86,14 +79,12 @@ void SVGPathByteStreamBuilder::curveToQuadratic(const FloatPoint& point1, const
 
 void SVGPathByteStreamBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticSmoothRel : PathSegCurveToQuadraticSmoothAbs);
     writeFloatPoint(targetPoint);
 }
 
 void SVGPathByteStreamBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_byteStream);
     writeSegmentType(mode == RelativeCoordinates ? PathSegArcRel : PathSegArcAbs);
     writeFloat(r1);
     writeFloat(r2);
@@ -105,7 +96,6 @@ void SVGPathByteStreamBuilder::arcTo(float r1, float r2, float angle, bool large
 
 void SVGPathByteStreamBuilder::closePath()
 {
-    ASSERT(m_byteStream);
     writeSegmentType(PathSegClosePath);
 }
 
index 2a19701..c296b47 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -29,14 +30,11 @@ namespace WebCore {
 
 class SVGPathByteStreamBuilder : public SVGPathConsumer {
 public:
-    SVGPathByteStreamBuilder();
-
-    void setCurrentByteStream(SVGPathByteStream* byteStream) { m_byteStream = byteStream; }
+    SVGPathByteStreamBuilder(SVGPathByteStream&);
 
 private:
     virtual void incrementPathSegmentCount() override { }
     virtual bool continueConsuming() override { return true; }
-    virtual void cleanup() override { m_byteStream = nullptr; }
 
     // Used in UnalteredParsing/NormalizedParsing modes.
     virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override;
@@ -57,7 +55,7 @@ private:
     {
         size_t typeSize = sizeof(ByteType);
         for (size_t i = 0; i < typeSize; ++i)
-            m_byteStream->append(type.bytes[i]);
+            m_byteStream.append(type.bytes[i]);
     }
 
     void writeFlag(bool value)
@@ -87,7 +85,7 @@ private:
         writeType(data);
     }
 
-    SVGPathByteStream* m_byteStream;
+    SVGPathByteStream& m_byteStream;
 };
 
 } // namespace WebCore
index e8eaae8..821ee61 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2002, 2003 The Karbon Developers
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -46,7 +46,6 @@ public:
     SVGPathConsumer() { }
     virtual void incrementPathSegmentCount() = 0;
     virtual bool continueConsuming() = 0;
-    virtual void cleanup() = 0;
 
     // Used in UnalteredParsing/NormalizedParsing modes.
     virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) = 0;
index 991b775..33e9a1f 100644 (file)
@@ -43,7 +43,6 @@
 #include "SVGPathSegLinetoVerticalAbs.h"
 #include "SVGPathSegLinetoVerticalRel.h"
 #include "SVGPathSegList.h"
-#include "SVGPathSegListBuilder.h"
 #include "SVGPathSegListPropertyTearOff.h"
 #include "SVGPathSegMovetoAbs.h"
 #include "SVGPathSegMovetoRel.h"
index 20afc95..172a8b2 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2002, 2003 The Karbon Developers
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
 #include "SVGPathParser.h"
 
 #include "AffineTransform.h"
+#include "SVGPathByteStreamBuilder.h"
 #include "SVGPathSource.h"
+#include "SVGPathStringBuilder.h"
 #include <wtf/MathExtras.h>
 
 static const float gOneOverThree = 1 / 3.f;
 
 namespace WebCore {
 
-SVGPathParser::SVGPathParser()
-    : m_consumer(nullptr)
+bool SVGPathParser::parse(SVGPathSource& source, SVGPathConsumer& consumer, PathParsingMode mode, bool checkForInitialMoveTo)
+{
+    SVGPathParser parser(consumer, source, mode);
+    return parser.parsePathData(checkForInitialMoveTo);
+}
+
+bool SVGPathParser::parseToByteStream(SVGPathSource& source, SVGPathByteStream& byteStream, PathParsingMode mode, bool checkForInitialMoveTo)
+{
+    SVGPathByteStreamBuilder builder(byteStream);
+    return parse(source, builder, mode, checkForInitialMoveTo);
+}
+
+bool SVGPathParser::parseToString(SVGPathSource& source, String& result, PathParsingMode mode, bool checkForInitialMoveTo)
+{
+    SVGPathStringBuilder builder;
+    SVGPathParser parser(builder, source, mode);
+    bool ok = parser.parsePathData(checkForInitialMoveTo);
+    result = builder.result();
+    return ok;
+}
+
+SVGPathParser::SVGPathParser(SVGPathConsumer& consumer, SVGPathSource& source, PathParsingMode parsingMode)
+    : m_source(source)
+    , m_consumer(consumer)
+    , m_pathParsingMode(parsingMode)
 {
 }
 
@@ -43,13 +68,13 @@ void SVGPathParser::parseClosePathSegment()
     if (m_pathParsingMode == NormalizedParsing)
         m_currentPoint = m_subPathPoint;
     m_closePath = true;
-    m_consumer->closePath();
+    m_consumer.closePath();
 }
 
 bool SVGPathParser::parseMoveToSegment()
 {
     FloatPoint targetPoint;
-    if (!m_source->parseMoveToSegment(targetPoint))
+    if (!m_source.parseMoveToSegment(targetPoint))
         return false;
 
     if (m_pathParsingMode == NormalizedParsing) {
@@ -58,9 +83,9 @@ bool SVGPathParser::parseMoveToSegment()
         else
             m_currentPoint = targetPoint;
         m_subPathPoint = m_currentPoint;
-        m_consumer->moveTo(m_currentPoint, m_closePath, AbsoluteCoordinates);
+        m_consumer.moveTo(m_currentPoint, m_closePath, AbsoluteCoordinates);
     } else
-        m_consumer->moveTo(targetPoint, m_closePath, m_mode);
+        m_consumer.moveTo(targetPoint, m_closePath, m_mode);
     m_closePath = false;
     return true;
 }
@@ -68,7 +93,7 @@ bool SVGPathParser::parseMoveToSegment()
 bool SVGPathParser::parseLineToSegment()
 {
     FloatPoint targetPoint;
-    if (!m_source->parseLineToSegment(targetPoint))
+    if (!m_source.parseLineToSegment(targetPoint))
         return false;
 
     if (m_pathParsingMode == NormalizedParsing) {
@@ -76,16 +101,16 @@ bool SVGPathParser::parseLineToSegment()
             m_currentPoint += targetPoint;
         else
             m_currentPoint = targetPoint;
-        m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+        m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates);
     } else
-        m_consumer->lineTo(targetPoint, m_mode);
+        m_consumer.lineTo(targetPoint, m_mode);
     return true;
 }
 
 bool SVGPathParser::parseLineToHorizontalSegment()
 {
     float toX;
-    if (!m_source->parseLineToHorizontalSegment(toX))
+    if (!m_source.parseLineToHorizontalSegment(toX))
         return false;
 
     if (m_pathParsingMode == NormalizedParsing) {
@@ -93,16 +118,16 @@ bool SVGPathParser::parseLineToHorizontalSegment()
             m_currentPoint.move(toX, 0);
         else
             m_currentPoint.setX(toX);
-        m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+        m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates);
     } else
-        m_consumer->lineToHorizontal(toX, m_mode);
+        m_consumer.lineToHorizontal(toX, m_mode);
     return true;
 }
 
 bool SVGPathParser::parseLineToVerticalSegment()
 {
     float toY;
-    if (!m_source->parseLineToVerticalSegment(toY))
+    if (!m_source.parseLineToVerticalSegment(toY))
         return false;
 
     if (m_pathParsingMode == NormalizedParsing) {
@@ -110,9 +135,9 @@ bool SVGPathParser::parseLineToVerticalSegment()
             m_currentPoint.move(0, toY);
         else
             m_currentPoint.setY(toY);
-        m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+        m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates);
     } else
-        m_consumer->lineToVertical(toY, m_mode);
+        m_consumer.lineToVertical(toY, m_mode);
     return true;
 }
 
@@ -121,7 +146,7 @@ bool SVGPathParser::parseCurveToCubicSegment()
     FloatPoint point1;
     FloatPoint point2;
     FloatPoint targetPoint;
-    if (!m_source->parseCurveToCubicSegment(point1, point2, targetPoint))
+    if (!m_source.parseCurveToCubicSegment(point1, point2, targetPoint))
         return false;
 
     if (m_pathParsingMode == NormalizedParsing) {
@@ -130,12 +155,12 @@ bool SVGPathParser::parseCurveToCubicSegment()
             point2 += m_currentPoint;
             targetPoint += m_currentPoint;
         }
-        m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
+        m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
 
         m_controlPoint = point2;
         m_currentPoint = targetPoint;
     } else
-        m_consumer->curveToCubic(point1, point2, targetPoint, m_mode);
+        m_consumer.curveToCubic(point1, point2, targetPoint, m_mode);
     return true;
 }
 
@@ -143,7 +168,7 @@ bool SVGPathParser::parseCurveToCubicSmoothSegment()
 {
     FloatPoint point2;
     FloatPoint targetPoint;
-    if (!m_source->parseCurveToCubicSmoothSegment(point2, targetPoint))
+    if (!m_source.parseCurveToCubicSmoothSegment(point2, targetPoint))
         return false;
 
     if (m_lastCommand != PathSegCurveToCubicAbs
@@ -161,12 +186,12 @@ bool SVGPathParser::parseCurveToCubicSmoothSegment()
             targetPoint += m_currentPoint;
         }
 
-        m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
+        m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
 
         m_controlPoint = point2;
         m_currentPoint = targetPoint;
     } else
-        m_consumer->curveToCubicSmooth(point2, targetPoint, m_mode);
+        m_consumer.curveToCubicSmooth(point2, targetPoint, m_mode);
     return true;
 }
 
@@ -174,7 +199,7 @@ bool SVGPathParser::parseCurveToQuadraticSegment()
 {
     FloatPoint point1;
     FloatPoint targetPoint;
-    if (!m_source->parseCurveToQuadraticSegment(point1, targetPoint))
+    if (!m_source.parseCurveToQuadraticSegment(point1, targetPoint))
         return false;
 
     if (m_pathParsingMode == NormalizedParsing) {
@@ -190,20 +215,20 @@ bool SVGPathParser::parseCurveToQuadraticSegment()
         point1.scale(gOneOverThree, gOneOverThree);
         point2.scale(gOneOverThree, gOneOverThree);
 
-        m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
+        m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
 
         if (m_mode == RelativeCoordinates)
             m_controlPoint += m_currentPoint;
         m_currentPoint = targetPoint;
     } else
-        m_consumer->curveToQuadratic(point1, targetPoint, m_mode);
+        m_consumer.curveToQuadratic(point1, targetPoint, m_mode);
     return true;
 }
 
 bool SVGPathParser::parseCurveToQuadraticSmoothSegment()
 {
     FloatPoint targetPoint;
-    if (!m_source->parseCurveToQuadraticSmoothSegment(targetPoint))
+    if (!m_source.parseCurveToQuadraticSmoothSegment(targetPoint))
         return false;
 
     if (m_lastCommand != PathSegCurveToQuadraticAbs
@@ -225,12 +250,12 @@ bool SVGPathParser::parseCurveToQuadraticSmoothSegment()
         point1.scale(gOneOverThree, gOneOverThree);
         point2.scale(gOneOverThree, gOneOverThree);
 
-        m_consumer->curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
+        m_consumer.curveToCubic(point1, point2, targetPoint, AbsoluteCoordinates);
 
         m_controlPoint = cubicPoint;
         m_currentPoint = targetPoint;
     } else
-        m_consumer->curveToQuadraticSmooth(targetPoint, m_mode);
+        m_consumer.curveToQuadraticSmooth(targetPoint, m_mode);
     return true;
 }
 
@@ -242,7 +267,7 @@ bool SVGPathParser::parseArcToSegment()
     bool largeArc;
     bool sweep;
     FloatPoint targetPoint;
-    if (!m_source->parseArcToSegment(rx, ry, angle, largeArc, sweep, targetPoint))
+    if (!m_source.parseArcToSegment(rx, ry, angle, largeArc, sweep, targetPoint))
         return false;
 
     // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a "lineto") joining the endpoints.
@@ -264,9 +289,9 @@ bool SVGPathParser::parseArcToSegment()
                 m_currentPoint += targetPoint;
             else
                 m_currentPoint = targetPoint;
-            m_consumer->lineTo(m_currentPoint, AbsoluteCoordinates);
+            m_consumer.lineTo(m_currentPoint, AbsoluteCoordinates);
         } else
-            m_consumer->lineTo(targetPoint, m_mode);
+            m_consumer.lineTo(targetPoint, m_mode);
         return true;
     }
 
@@ -277,29 +302,18 @@ bool SVGPathParser::parseArcToSegment()
         m_currentPoint = targetPoint;
         return decomposeArcToCubic(angle, rx, ry, point1, targetPoint, largeArc, sweep);
     }
-    m_consumer->arcTo(rx, ry, angle, largeArc, sweep, targetPoint, m_mode);
+    m_consumer.arcTo(rx, ry, angle, largeArc, sweep, targetPoint, m_mode);
     return true;
 }
 
-bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, bool checkForInitialMoveTo)
+bool SVGPathParser::parsePathData(bool checkForInitialMoveTo)
 {
-    ASSERT(m_source);
-    ASSERT(m_consumer);
-
-    m_pathParsingMode = pathParsingMode;
-
-    m_controlPoint = FloatPoint();
-    m_currentPoint = FloatPoint();
-    m_subPathPoint = FloatPoint();
-    m_closePath = true;
-
     // Skip any leading spaces.
-    if (!m_source->moveToNextToken())
+    if (!m_source.moveToNextToken())
         return true;
 
     SVGPathSegType command;
-    m_source->parseSVGSegmentType(command);
-    m_lastCommand = PathSegUnknown;
+    m_source.parseSVGSegmentType(command);
 
     // Path must start with moveto.
     if (checkForInitialMoveTo && command != PathSegMoveToAbs && command != PathSegMoveToRel)
@@ -307,7 +321,7 @@ bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo
 
     while (true) {
         // Skip spaces between command and first coordinate.
-        m_source->moveToNextToken();
+        m_source.moveToNextToken();
         m_mode = AbsoluteCoordinates;
         switch (command) {
         case PathSegMoveToRel:
@@ -379,15 +393,15 @@ bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo
         default:
             return false;
         }
-        if (!m_consumer->continueConsuming())
+        if (!m_consumer.continueConsuming())
             return true;
 
         m_lastCommand = command;
 
-        if (!m_source->hasMoreData())
+        if (!m_source.hasMoreData())
             return true;
 
-        command = m_source->nextCommand(command);
+        command = m_source.nextCommand(command);
 
         if (m_lastCommand != PathSegCurveToCubicAbs
             && m_lastCommand != PathSegCurveToCubicRel
@@ -399,22 +413,12 @@ bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo
             && m_lastCommand != PathSegCurveToQuadraticSmoothRel)
             m_controlPoint = m_currentPoint;
 
-        m_consumer->incrementPathSegmentCount();
+        m_consumer.incrementPathSegmentCount();
     }
 
     return false;
 }
 
-void SVGPathParser::cleanup()
-{
-    ASSERT(m_source);
-    ASSERT(m_consumer);
-
-    m_consumer->cleanup();
-    m_source = nullptr;
-    m_consumer = nullptr;
-}
-
 // This works by converting the SVG arc to "simple" beziers.
 // Partly adapted from Niko's code in kdelibs/kdecore/svgicons.
 // See also SVG implementation notes: http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
@@ -495,7 +499,7 @@ bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, FloatPo
         point2 = targetPoint;
         point2.move(t * sinEndTheta, -t * cosEndTheta);
 
-        m_consumer->curveToCubic(pointTransform.mapPoint(point1), pointTransform.mapPoint(point2),
+        m_consumer.curveToCubic(pointTransform.mapPoint(point1), pointTransform.mapPoint(point2),
                                  pointTransform.mapPoint(targetPoint), AbsoluteCoordinates);
     }
     return true;
index 81fa091..534c6a5 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2002, 2003 The Karbon Developers
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
 
 namespace WebCore {
 
+class SVGPathByteStream;
 class SVGPathSource;
 
 class SVGPathParser {
-    WTF_MAKE_NONCOPYABLE(SVGPathParser); WTF_MAKE_FAST_ALLOCATED;
 public:
-    SVGPathParser();
+    static bool parse(SVGPathSource&, SVGPathConsumer&, PathParsingMode = NormalizedParsing, bool checkForInitialMoveTo = true);
 
-    bool parsePathDataFromSource(PathParsingMode, bool checkForInitialMoveTo = true);
-    void setCurrentConsumer(SVGPathConsumer* consumer) { m_consumer = consumer; }
-    void setCurrentSource(SVGPathSource* source) { m_source = source; }
-    void cleanup();
+    static bool parseToByteStream(SVGPathSource&, SVGPathByteStream&, PathParsingMode = NormalizedParsing, bool checkForInitialMoveTo = true);
+    static bool parseToString(SVGPathSource&, String& result, PathParsingMode = NormalizedParsing, bool checkForInitialMoveTo = true);
 
 private:
-    bool decomposeArcToCubic(float, float, float, FloatPoint&, FloatPoint&, bool largeArcFlag, bool sweepFlag);
+    SVGPathParser(SVGPathConsumer&, SVGPathSource&, PathParsingMode);
+    bool parsePathData(bool checkForInitialMoveTo);
+
+    bool decomposeArcToCubic(float angle, float rx, float ry, FloatPoint&, FloatPoint&, bool largeArcFlag, bool sweepFlag);
     void parseClosePathSegment();
     bool parseMoveToSegment();
     bool parseLineToSegment();
@@ -55,15 +56,15 @@ private:
     bool parseCurveToQuadraticSmoothSegment();
     bool parseArcToSegment();
 
-    SVGPathSource* m_source;
-    SVGPathConsumer* m_consumer;
-    PathCoordinateMode m_mode;
-    PathParsingMode m_pathParsingMode;
-    SVGPathSegType m_lastCommand;
-    bool m_closePath;
+    SVGPathSource& m_source;
+    SVGPathConsumer& m_consumer;
     FloatPoint m_controlPoint;
     FloatPoint m_currentPoint;
     FloatPoint m_subPathPoint;
+    PathCoordinateMode m_mode { AbsoluteCoordinates };
+    const PathParsingMode m_pathParsingMode { NormalizedParsing };
+    SVGPathSegType m_lastCommand { PathSegUnknown };
+    bool m_closePath { true };
 };
 
 } // namespace WebCore
index ce65721..db53f8c 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2002, 2003 The Karbon Developers
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
 #include "config.h"
 #include "SVGPathSegListBuilder.h"
 
-#include "ExceptionCode.h"
 #include "SVGPathElement.h"
 #include "SVGPathSegArcAbs.h"
 #include "SVGPathSegArcRel.h"
 
 namespace WebCore {
 
-SVGPathSegListBuilder::SVGPathSegListBuilder()
-    : m_pathElement(nullptr)
-    , m_pathSegList(nullptr)
-    , m_pathSegRole(PathSegUndefinedRole)
+SVGPathSegListBuilder::SVGPathSegListBuilder(SVGPathElement& pathElement, SVGPathSegList& pathSegList, SVGPathSegRole role)
+    : m_pathElement(pathElement)
+    , m_pathSegList(pathSegList)
+    , m_pathSegRole(role)
 {
 }
 
 void SVGPathSegListBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegMovetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegMovetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegMovetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegMovetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegLinetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegLinetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalAbs(x, m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegLinetoHorizontalAbs(x, m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalRel(x, m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegLinetoHorizontalRel(x, m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::lineToVertical(float y, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalAbs(y, m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegLinetoVerticalAbs(y, m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalRel(y, m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegLinetoVerticalRel(y, m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothAbs(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicSmoothAbs(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothRel(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoCubicSmoothRel(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticSmoothAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegCurvetoQuadraticSmoothRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegArcAbs(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegArcAbs(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegArcRel(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
+        m_pathSegList.append(m_pathElement.createSVGPathSegArcRel(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
 }
 
 void SVGPathSegListBuilder::closePath()
 {
-    ASSERT(m_pathElement);
-    ASSERT(m_pathSegList);
-    m_pathSegList->append(m_pathElement->createSVGPathSegClosePath(m_pathSegRole));
+    m_pathSegList.append(m_pathElement.createSVGPathSegClosePath(m_pathSegRole));
 }
 
 }
index 67ff267..f83986f 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2002, 2003 The Karbon Developers
  * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
  * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -34,21 +34,11 @@ class SVGPathElement;
 
 class SVGPathSegListBuilder : public SVGPathConsumer {
 public:
-    SVGPathSegListBuilder();
-
-    void setCurrentSVGPathElement(SVGPathElement* pathElement) { m_pathElement = pathElement; }
-    void setCurrentSVGPathSegList(SVGPathSegList& pathSegList) { m_pathSegList = &pathSegList; }
-    void setCurrentSVGPathSegRole(SVGPathSegRole pathSegRole) { m_pathSegRole = pathSegRole; }
+    SVGPathSegListBuilder(SVGPathElement&, SVGPathSegList&, SVGPathSegRole);
 
 private:
     virtual void incrementPathSegmentCount() override { }
     virtual bool continueConsuming() override { return true; }
-    virtual void cleanup() override
-    {
-        m_pathElement = nullptr;
-        m_pathSegList = nullptr;
-        m_pathSegRole = PathSegUndefinedRole;
-    }
 
     // Used in UnalteredParsing/NormalizedParsing modes.
     virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) override;
@@ -64,9 +54,9 @@ private:
     virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override;
     virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) override;
 
-    SVGPathElement* m_pathElement;
-    SVGPathSegList* m_pathSegList;
-    SVGPathSegRole m_pathSegRole;
+    SVGPathElement& m_pathElement;
+    SVGPathSegList& m_pathSegList;
+    SVGPathSegRole m_pathSegRole { PathSegUndefinedRole };
 };
 
 } // namespace WebCore
index f30ce00..e2a245b 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -43,11 +44,6 @@ String SVGPathStringBuilder::result()
     return m_stringBuilder.toString();
 }
 
-void SVGPathStringBuilder::cleanup()
-{
-    m_stringBuilder.clear();
-}
-
 void SVGPathStringBuilder::incrementPathSegmentCount()
 {
 }
index 0800d08..9230acc 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -33,7 +34,6 @@ public:
     String result();
 
 private:
-    virtual void cleanup() override;
     virtual void incrementPathSegmentCount() override;
     virtual bool continueConsuming() override;
 
index 1c27bcf..5da7e88 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
  * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
 
 namespace WebCore {
 
-SVGPathTraversalStateBuilder::SVGPathTraversalStateBuilder()
-    : m_traversalState(nullptr)
-    , m_segmentIndex(0)
+SVGPathTraversalStateBuilder::SVGPathTraversalStateBuilder(PathTraversalState& state, float desiredLength)
+    : m_traversalState(state)
 {
+    m_traversalState.setDesiredLength(desiredLength);
 }
 
 void SVGPathTraversalStateBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode)
 {
-    ASSERT(m_traversalState);
-    m_traversalState->processPathElement(PathElementMoveToPoint, &targetPoint);
+    m_traversalState.processPathElement(PathElementMoveToPoint, &targetPoint);
 }
 
 void SVGPathTraversalStateBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode)
 {
-    ASSERT(m_traversalState);
-    m_traversalState->processPathElement(PathElementAddLineToPoint, &targetPoint);
+    m_traversalState.processPathElement(PathElementAddLineToPoint, &targetPoint);
 }
 
 void SVGPathTraversalStateBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode)
 {
     FloatPoint points[] = { point1, point2, targetPoint };
-    ASSERT(m_traversalState);
-    m_traversalState->processPathElement(PathElementAddCurveToPoint, points);
-}
 
-void SVGPathTraversalStateBuilder::closePath()
-{
-    ASSERT(m_traversalState);
-    m_traversalState->processPathElement(PathElementCloseSubpath, nullptr);
+    m_traversalState.processPathElement(PathElementAddCurveToPoint, points);
 }
 
-void SVGPathTraversalStateBuilder::setDesiredLength(float desiredLength)
+void SVGPathTraversalStateBuilder::closePath()
 {
-    ASSERT(m_traversalState);
-    m_traversalState->setDesiredLength(desiredLength);
+    m_traversalState.processPathElement(PathElementCloseSubpath, nullptr);
 }
 
 bool SVGPathTraversalStateBuilder::continueConsuming()
 {
-    ASSERT(m_traversalState);    
-    return !m_traversalState->success();
+    return !m_traversalState.success();
 }
 
-float SVGPathTraversalStateBuilder::totalLength()
+float SVGPathTraversalStateBuilder::totalLength() const
 {
-    ASSERT(m_traversalState);
-    return m_traversalState->totalLength();
+    return m_traversalState.totalLength();
 }
 
-SVGPoint SVGPathTraversalStateBuilder::currentPoint()
+SVGPoint SVGPathTraversalStateBuilder::currentPoint() const
 {
-    ASSERT(m_traversalState);
-    return m_traversalState->current();
+    return m_traversalState.current();
 }
 
 }
index f2cfcd7..ea930f8 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -30,17 +31,14 @@ class PathTraversalState;
 
 class SVGPathTraversalStateBuilder : public SVGPathConsumer {
 public:
-    SVGPathTraversalStateBuilder();
+    SVGPathTraversalStateBuilder(PathTraversalState&, float desiredLength = 0);
 
-    unsigned pathSegmentIndex() { return m_segmentIndex; }
-    float totalLength();
-    SVGPoint currentPoint();
+    unsigned pathSegmentIndex() const { return m_segmentIndex; }
+    float totalLength() const;
+    SVGPoint currentPoint() const;
 
-    void setCurrentTraversalState(PathTraversalState* traversalState) { m_traversalState = traversalState; }
-    void setDesiredLength(float);
     virtual void incrementPathSegmentCount() override { ++m_segmentIndex; }
     virtual bool continueConsuming() override;
-    virtual void cleanup() override { m_traversalState = nullptr, m_segmentIndex = 0; }
 
 private:
     // Used in UnalteredParsing/NormalizedParsing modes.
@@ -58,8 +56,8 @@ private:
     virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
     virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
 
-    PathTraversalState* m_traversalState;
-    unsigned m_segmentIndex;
+    PathTraversalState& m_traversalState;
+    unsigned m_segmentIndex { 0 };
 };
 
 } // namespace WebCore
index b3cc049..bab498f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 
 namespace WebCore {
 
-// FIXME: are all these globals warranted? Why not just make them on the stack?
-static SVGPathBuilder& globalSVGPathBuilder(Path& result)
-{
-    static NeverDestroyed<SVGPathBuilder> s_builder;
-    s_builder.get().setCurrentPath(&result);
-    return s_builder.get();
-}
-
-static SVGPathSegListBuilder& globalSVGPathSegListBuilder(SVGPathElement& element, SVGPathSegRole role, SVGPathSegList& result)
-{
-    static NeverDestroyed<SVGPathSegListBuilder> s_builder;
-
-    s_builder.get().setCurrentSVGPathElement(&element);
-    s_builder.get().setCurrentSVGPathSegList(result);
-    s_builder.get().setCurrentSVGPathSegRole(role);
-    return s_builder.get();
-}
-
-static SVGPathByteStreamBuilder& globalSVGPathByteStreamBuilder(SVGPathByteStream& result)
-{
-    static NeverDestroyed<SVGPathByteStreamBuilder> s_builder;
-    s_builder.get().setCurrentByteStream(&result);
-    return s_builder.get();
-}
-
-static SVGPathStringBuilder& globalSVGPathStringBuilder()
-{
-    static NeverDestroyed<SVGPathStringBuilder> s_builder;
-    return s_builder.get();
-}
-
-static SVGPathTraversalStateBuilder& globalSVGPathTraversalStateBuilder(PathTraversalState& traversalState, float length)
-{
-    static NeverDestroyed<SVGPathTraversalStateBuilder> s_parser;
-
-    s_parser.get().setCurrentTraversalState(&traversalState);
-    s_parser.get().setDesiredLength(length);
-    return s_parser.get();
-}
-
-// FIXME: why bother keeping a singleton around? Is it slow to allocate?
-static SVGPathParser& globalSVGPathParser(SVGPathSource& source, SVGPathConsumer& consumer)
-{
-    static NeverDestroyed<SVGPathParser> s_parser;
-
-    s_parser.get().setCurrentSource(&source);
-    s_parser.get().setCurrentConsumer(&consumer);
-    return s_parser.get();
-}
-
-static SVGPathBlender& globalSVGPathBlender()
-{
-    static NeverDestroyed<SVGPathBlender> s_blender;
-    return s_blender.get();
-}
-
 bool buildPathFromString(const String& d, Path& result)
 {
     if (d.isEmpty())
         return true;
 
-    SVGPathBuilder& builder = globalSVGPathBuilder(result);
-
+    SVGPathBuilder builder(result);
     SVGPathStringSource source(d);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(NormalizedParsing);
-    parser.cleanup();
-    return ok;
+    return SVGPathParser::parse(source, builder);
 }
 
 bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream& result, PathParsingMode parsingMode)
@@ -113,13 +54,8 @@ bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPat
     if (list.isEmpty())
         return true;
 
-    SVGPathByteStreamBuilder& builder = globalSVGPathByteStreamBuilder(result);
-
     SVGPathSegListSource source(list);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(parsingMode);
-    parser.cleanup();
-    return ok;
+    return SVGPathParser::parseToByteStream(source, result, parsingMode);
 }
 
 bool appendSVGPathByteStreamFromSVGPathSeg(RefPtr<SVGPathSeg>&& pathSeg, SVGPathByteStream& result, PathParsingMode parsingMode)
@@ -131,11 +67,8 @@ bool appendSVGPathByteStreamFromSVGPathSeg(RefPtr<SVGPathSeg>&& pathSeg, SVGPath
     appendedItemList.append(WTF::move(pathSeg));
 
     SVGPathByteStream appendedByteStream;
-    SVGPathByteStreamBuilder& builder = globalSVGPathByteStreamBuilder(appendedByteStream);
     SVGPathSegListSource source(appendedItemList);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(parsingMode, false);
-    parser.cleanup();
+    bool ok = SVGPathParser::parseToByteStream(source, result, parsingMode, false);
 
     if (ok)
         result.append(appendedByteStream);
@@ -148,13 +81,9 @@ bool buildPathFromByteStream(const SVGPathByteStream& stream, Path& result)
     if (stream.isEmpty())
         return true;
 
-    SVGPathBuilder& builder = globalSVGPathBuilder(result);
-
+    SVGPathBuilder builder(result);
     SVGPathByteStreamSource source(stream);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(NormalizedParsing);
-    parser.cleanup();
-    return ok;
+    return SVGPathParser::parse(source, builder);
 }
 
 bool buildSVGPathSegListFromByteStream(const SVGPathByteStream& stream, SVGPathElement& element, SVGPathSegList& result, PathParsingMode parsingMode)
@@ -162,13 +91,9 @@ bool buildSVGPathSegListFromByteStream(const SVGPathByteStream& stream, SVGPathE
     if (stream.isEmpty())
         return true;
 
-    SVGPathSegListBuilder& builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result);
-
+    SVGPathSegListBuilder builder(element, result, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole);
     SVGPathByteStreamSource source(stream);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(parsingMode);
-    parser.cleanup();
-    return ok;
+    return SVGPathParser::parse(source, builder, parsingMode);
 }
 
 bool buildStringFromByteStream(const SVGPathByteStream& stream, String& result, PathParsingMode parsingMode)
@@ -176,14 +101,8 @@ bool buildStringFromByteStream(const SVGPathByteStream& stream, String& result,
     if (stream.isEmpty())
         return true;
 
-    SVGPathStringBuilder& builder = globalSVGPathStringBuilder();
-
     SVGPathByteStreamSource source(stream);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(parsingMode);
-    result = builder.result();
-    parser.cleanup();
-    return ok;
+    return SVGPathParser::parseToString(source, result, parsingMode);
 }
 
 bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode)
@@ -192,14 +111,8 @@ bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, P
     if (list.isEmpty())
         return true;
 
-    SVGPathStringBuilder& builder = globalSVGPathStringBuilder();
-
     SVGPathSegListSource source(list);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(parsingMode);
-    result = builder.result();
-    parser.cleanup();
-    return ok;
+    return SVGPathParser::parseToString(source, result, parsingMode);
 }
 
 bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream& result, PathParsingMode parsingMode)
@@ -208,13 +121,8 @@ bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream& result
     if (d.isEmpty())
         return true;
 
-    SVGPathByteStreamBuilder& builder = globalSVGPathByteStreamBuilder(result);
-
     SVGPathStringSource source(d);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(parsingMode);
-    parser.cleanup();
-    return ok;
+    return SVGPathParser::parseToByteStream(source, result, parsingMode);
 }
 
 bool buildAnimatedSVGPathByteStream(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream, SVGPathByteStream& result, float progress)
@@ -224,14 +132,11 @@ bool buildAnimatedSVGPathByteStream(const SVGPathByteStream& fromStream, const S
     if (toStream.isEmpty())
         return true;
 
-    SVGPathByteStreamBuilder& builder = globalSVGPathByteStreamBuilder(result);
+    SVGPathByteStreamBuilder builder(result);
 
     SVGPathByteStreamSource fromSource(fromStream);
     SVGPathByteStreamSource toSource(toStream);
-    SVGPathBlender& blender = globalSVGPathBlender();
-    bool ok = blender.blendAnimatedPath(progress, &fromSource, &toSource, &builder);
-    blender.cleanup();
-    return ok;
+    return SVGPathBlender::blendAnimatedPath(fromSource, toSource, builder, progress);
 }
 
 bool addToSVGPathByteStream(SVGPathByteStream& streamToAppendTo, const SVGPathByteStream& byStream, unsigned repeatCount)
@@ -241,17 +146,14 @@ bool addToSVGPathByteStream(SVGPathByteStream& streamToAppendTo, const SVGPathBy
         return true;
 
     // Is it OK to make the SVGPathByteStreamBuilder from a stream, and then clear that stream?
-    SVGPathByteStreamBuilder& builder = globalSVGPathByteStreamBuilder(streamToAppendTo);
+    SVGPathByteStreamBuilder builder(streamToAppendTo);
 
     SVGPathByteStream fromStreamCopy = streamToAppendTo;
     streamToAppendTo.clear();
 
     SVGPathByteStreamSource fromSource(fromStreamCopy);
     SVGPathByteStreamSource bySource(byStream);
-    SVGPathBlender& blender = globalSVGPathBlender();
-    bool ok = blender.addAnimatedPath(&fromSource, &bySource, &builder, repeatCount);
-    blender.cleanup();
-    return ok;
+    return SVGPathBlender::addAnimatedPath(fromSource, bySource, builder, repeatCount);
 }
 
 bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream, float length, unsigned& pathSeg)
@@ -260,13 +162,11 @@ bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream& stream,
         return false;
 
     PathTraversalState traversalState(PathTraversalState::Action::SegmentAtLength);
-    SVGPathTraversalStateBuilder& builder = globalSVGPathTraversalStateBuilder(traversalState, length);
+    SVGPathTraversalStateBuilder builder(traversalState, length);
 
     SVGPathByteStreamSource source(stream);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(NormalizedParsing);
+    bool ok = SVGPathParser::parse(source, builder);
     pathSeg = builder.pathSegmentIndex();
-    parser.cleanup();
     return ok;
 }
 
@@ -276,13 +176,12 @@ bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float& t
         return false;
 
     PathTraversalState traversalState(PathTraversalState::Action::TotalLength);
-    SVGPathTraversalStateBuilder& builder = globalSVGPathTraversalStateBuilder(traversalState, 0);
+
+    SVGPathTraversalStateBuilder builder(traversalState);
 
     SVGPathByteStreamSource source(stream);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(NormalizedParsing);
+    bool ok = SVGPathParser::parse(source, builder);
     totalLength = builder.totalLength();
-    parser.cleanup();
     return ok;
 }
 
@@ -292,13 +191,12 @@ bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream& stream, float
         return false;
 
     PathTraversalState traversalState(PathTraversalState::Action::VectorAtLength);
-    SVGPathTraversalStateBuilder& builder = globalSVGPathTraversalStateBuilder(traversalState, length);
+
+    SVGPathTraversalStateBuilder builder(traversalState, length);
 
     SVGPathByteStreamSource source(stream);
-    SVGPathParser& parser = globalSVGPathParser(source, builder);
-    bool ok = parser.parsePathDataFromSource(NormalizedParsing);
+    bool ok = SVGPathParser::parse(source, builder);
     point = builder.currentPoint();
-    parser.cleanup();
     return ok;
 }
 
@@ -332,12 +230,11 @@ bool buildStringFromPath(const Path& path, String& string)
     // Ideally we would have a SVGPathPlatformPathSource, but it's not possible to manually iterate
     // a path, only apply a function to all path elements at once.
 
-    SVGPathStringBuilder& builder = globalSVGPathStringBuilder();
+    SVGPathStringBuilder builder;
     path.apply([&builder](const PathElement& pathElement) {
         pathIteratorForBuildingString(builder, pathElement);
     });
     string = builder.result();
-    static_cast<SVGPathConsumer&>(builder).cleanup(); // Wat?
 
     return true;
 }
index f7aabdd..f64a124 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
index b8d2e99..bbfa20e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,7 +33,6 @@
 #include "SVGGlyphElement.h"
 #include "SVGHKernElement.h"
 #include "SVGMissingGlyphElement.h"
-#include "SVGPathBuilder.h"
 #include "SVGPathParser.h"
 #include "SVGPathStringSource.h"
 #include "SVGVKernElement.h"
@@ -1126,11 +1125,10 @@ static const char rrCurveTo = 0x08;
 static const char endChar = 0x0e;
 static const char rMoveTo = 0x15;
 
-class CFFBuilder : public SVGPathBuilder {
+class CFFBuilder : public SVGPathConsumer {
 public:
     CFFBuilder(Vector<char>& cffData, float width, FloatPoint origin)
         : m_cffData(cffData)
-        , m_hasBoundingBox(false)
     {
         writeCFFEncodedNumber(m_cffData, width);
         writeCFFEncodedNumber(m_cffData, origin.x());
@@ -1209,10 +1207,21 @@ private:
             lineTo(m_startingPoint, AbsoluteCoordinates);
     }
 
+    virtual void incrementPathSegmentCount() override { }
+    virtual bool continueConsuming() override { return true; }
+
+    virtual void lineToHorizontal(float, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
+    virtual void lineToVertical(float, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
+    virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
+    virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
+    virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
+    virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) override { ASSERT_NOT_REACHED(); }
+
     Vector<char>& m_cffData;
     FloatPoint m_startingPoint;
+    FloatPoint m_current;
     FloatRect m_boundingBox;
-    bool m_hasBoundingBox;
+    bool m_hasBoundingBox { false };
 };
 
 Vector<char> SVGToOTFFontConverter::transcodeGlyphPaths(float width, const SVGElement& glyphOrMissingGlyphElement, FloatRect& boundingBox) const
@@ -1241,13 +1250,7 @@ Vector<char> SVGToOTFFontConverter::transcodeGlyphPaths(float width, const SVGEl
     CFFBuilder builder(result, width, FloatPoint(horizontalOriginX, horizontalOriginY));
     SVGPathStringSource source(dAttribute);
 
-    SVGPathParser parser;
-    parser.setCurrentSource(&source);
-    parser.setCurrentConsumer(&builder);
-
-    ok = parser.parsePathDataFromSource(NormalizedParsing);
-    parser.cleanup();
-
+    ok = SVGPathParser::parse(source, builder);
     if (!ok)
         result.clear();