| Index: Source/core/svg/SVGPathParser.cpp
|
| diff --git a/Source/core/svg/SVGPathParser.cpp b/Source/core/svg/SVGPathParser.cpp
|
| index 9e9cc88647c89c1240a38970840f1d0353e27ad9..52bb80920523598dd41f8df2663b1c064da9fe22 100644
|
| --- a/Source/core/svg/SVGPathParser.cpp
|
| +++ b/Source/core/svg/SVGPathParser.cpp
|
| @@ -167,27 +167,12 @@ void SVGPathParser::emitCurveToQuadraticSmoothSegment(PathSegmentData& segment)
|
|
|
| void SVGPathParser::emitArcToSegment(PathSegmentData& segment)
|
| {
|
| - // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a "lineto") joining the endpoints.
|
| - // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
|
| - // If the current point and target point for the arc are identical, it should be treated as a zero length
|
| - // path. This ensures continuity in animations.
|
| - float rx = fabsf(segment.arcRadii().x());
|
| - float ry = fabsf(segment.arcRadii().y());
|
| -
|
| if (m_mode == RelativeCoordinates)
|
| segment.targetPoint += m_currentPoint;
|
|
|
| - if (!rx || !ry || segment.targetPoint == m_currentPoint) {
|
| + if (!decomposeArcToCubic(m_currentPoint, segment))
|
| m_consumer->lineTo(segment.targetPoint, AbsoluteCoordinates);
|
| - m_currentPoint = segment.targetPoint;
|
| - return;
|
| - }
|
| -
|
| - float angle = segment.arcAngle();
|
| - FloatPoint point1 = m_currentPoint;
|
| m_currentPoint = segment.targetPoint;
|
| - if (!decomposeArcToCubic(angle, rx, ry, point1, segment.targetPoint, segment.arcLarge, segment.arcSweep))
|
| - m_consumer->lineTo(segment.targetPoint, AbsoluteCoordinates);
|
| }
|
|
|
| bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, bool checkForInitialMoveTo)
|
| @@ -346,9 +331,23 @@ bool SVGPathParser::parsePathDataFromSource(PathParsingMode pathParsingMode, boo
|
| // 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
|
| -bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, const FloatPoint& start, const FloatPoint& end, bool largeArcFlag, bool sweepFlag)
|
| +bool SVGPathParser::decomposeArcToCubic(const FloatPoint& currentPoint, const PathSegmentData& arcSegment)
|
| {
|
| - FloatSize midPointDistance = start - end;
|
| + // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a "lineto") joining the endpoints.
|
| + // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
|
| + float rx = fabsf(arcSegment.arcRadii().x());
|
| + float ry = fabsf(arcSegment.arcRadii().y());
|
| + if (!rx || !ry)
|
| + return false;
|
| +
|
| + // If the current point and target point for the arc are identical, it should be treated as a zero length
|
| + // path. This ensures continuity in animations.
|
| + if (arcSegment.targetPoint == currentPoint)
|
| + return false;
|
| +
|
| + float angle = arcSegment.arcAngle();
|
| +
|
| + FloatSize midPointDistance = currentPoint - arcSegment.targetPoint;
|
| midPointDistance.scale(0.5f);
|
|
|
| AffineTransform pointTransform;
|
| @@ -372,15 +371,15 @@ bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, const F
|
| pointTransform.scale(1 / rx, 1 / ry);
|
| pointTransform.rotate(-angle);
|
|
|
| - FloatPoint point1 = pointTransform.mapPoint(start);
|
| - FloatPoint point2 = pointTransform.mapPoint(end);
|
| + FloatPoint point1 = pointTransform.mapPoint(currentPoint);
|
| + FloatPoint point2 = pointTransform.mapPoint(arcSegment.targetPoint);
|
| FloatSize delta = point2 - point1;
|
|
|
| float d = delta.width() * delta.width() + delta.height() * delta.height();
|
| float scaleFactorSquared = std::max(1 / d - 0.25f, 0.f);
|
|
|
| float scaleFactor = sqrtf(scaleFactorSquared);
|
| - if (sweepFlag == largeArcFlag)
|
| + if (arcSegment.arcSweep == arcSegment.arcLarge)
|
| scaleFactor = -scaleFactor;
|
|
|
| delta.scale(scaleFactor);
|
| @@ -392,9 +391,9 @@ bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, const F
|
| float theta2 = FloatPoint(point2 - centerPoint).slopeAngleRadians();
|
|
|
| float thetaArc = theta2 - theta1;
|
| - if (thetaArc < 0 && sweepFlag)
|
| + if (thetaArc < 0 && arcSegment.arcSweep)
|
| thetaArc += twoPiFloat;
|
| - else if (thetaArc > 0 && !sweepFlag)
|
| + else if (thetaArc > 0 && !arcSegment.arcSweep)
|
| thetaArc -= twoPiFloat;
|
|
|
| pointTransform.makeIdentity();
|
|
|