Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Unified Diff: third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp

Issue 1623073003: [SVG] Paint unnormalized paths (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: missed review comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp
diff --git a/third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp b/third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp
index acbce1d157bfbfd9be74f0a519449046e57aff21..4810645af5cfd3c417cb612c7967caccf478c9d3 100644
--- a/third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp
@@ -23,29 +23,194 @@
#include "core/svg/SVGPathBuilder.h"
-#include "core/svg/SVGPathData.h"
#include "platform/graphics/Path.h"
namespace blink {
+FloatPoint SVGPathBuilder::smoothControl(bool isCompatibleSegment) const
+{
+ // The control point is assumed to be the reflection of the control point on
+ // the previous command relative to the current point. If there is no previous
+ // command or if the previous command was not a [quad/cubic], assume the control
+ // point is coincident with the current point.
+ // [https://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands]
+ // [https://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands]
+ FloatPoint controlPoint = m_currentPoint;
+ if (isCompatibleSegment)
+ controlPoint += m_currentPoint - m_lastControlPoint;
+
+ return controlPoint;
+}
+
+void SVGPathBuilder::emitClose()
+{
+ m_path.closeSubpath();
+
+ // At the end of the [closepath] command, the new current
+ // point is set to the initial point of the current subpath.
+ // [https://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand]
+ m_currentPoint = m_subpathPoint;
+}
+
+void SVGPathBuilder::emitMoveTo(const FloatPoint& p)
+{
+ m_path.moveTo(p);
+
+ // If a "closepath" is followed immediately by a "moveto", then
+ // the "moveto" identifies the start point of the next subpath.
+ // [https://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand]
+ if (m_lastCommand == PathSegClosePath)
+ m_subpathPoint = p;
+
+ m_currentPoint = p;
+}
+
+void SVGPathBuilder::emitLineTo(const FloatPoint& p)
+{
+ m_path.addLineTo(p);
+ m_currentPoint = p;
+}
+
+void SVGPathBuilder::emitQuadTo(const FloatPoint& c0, const FloatPoint& p)
+{
+ m_path.addQuadCurveTo(c0, p);
+ m_lastControlPoint = c0;
+ m_currentPoint = p;
+}
+
+void SVGPathBuilder::emitSmoothQuadTo(const FloatPoint& p)
+{
+ bool lastWasQuadratic = m_lastCommand == PathSegCurveToQuadraticAbs
+ || m_lastCommand == PathSegCurveToQuadraticRel
+ || m_lastCommand == PathSegCurveToQuadraticSmoothAbs
+ || m_lastCommand == PathSegCurveToQuadraticSmoothRel;
+
+ emitQuadTo(smoothControl(lastWasQuadratic), p);
+}
+
+void SVGPathBuilder::emitCubicTo(const FloatPoint& c0, const FloatPoint& c1, const FloatPoint& p)
+{
+ m_path.addBezierCurveTo(c0, c1, p);
+ m_lastControlPoint = c1;
+ m_currentPoint = p;
+}
+
+void SVGPathBuilder::emitSmoothCubicTo(const FloatPoint& c1, const FloatPoint& p)
+{
+ bool lastWasCubic = m_lastCommand == PathSegCurveToCubicAbs
+ || m_lastCommand == PathSegCurveToCubicRel
+ || m_lastCommand == PathSegCurveToCubicSmoothAbs
+ || m_lastCommand == PathSegCurveToCubicSmoothRel;
+
+ emitCubicTo(smoothControl(lastWasCubic), c1, p);
+}
+
+void SVGPathBuilder::emitArcTo(const FloatPoint& p, const FloatSize& r, float rotate,
+ bool largeArc, bool sweep)
+{
+ m_path.addArcTo(p, r, rotate, largeArc, sweep);
+ m_currentPoint = p;
+}
+
void SVGPathBuilder::emitSegment(const PathSegmentData& segment)
{
switch (segment.command) {
+ case PathSegClosePath:
+ emitClose();
+ break;
case PathSegMoveToAbs:
- m_path.moveTo(segment.targetPoint);
+ emitMoveTo(
+ segment.targetPoint);
+ break;
+ case PathSegMoveToRel:
+ emitMoveTo(
+ m_currentPoint + segment.targetPoint);
break;
case PathSegLineToAbs:
- m_path.addLineTo(segment.targetPoint);
+ emitLineTo(
+ segment.targetPoint);
break;
- case PathSegClosePath:
- m_path.closeSubpath();
+ case PathSegLineToRel:
+ emitLineTo(
+ m_currentPoint + segment.targetPoint);
+ break;
+ case PathSegLineToHorizontalAbs:
+ emitLineTo(
+ FloatPoint(segment.targetPoint.x(), m_currentPoint.y()));
+ break;
+ case PathSegLineToHorizontalRel:
+ emitLineTo(
+ m_currentPoint + FloatSize(segment.targetPoint.x(), 0));
+ break;
+ case PathSegLineToVerticalAbs:
+ emitLineTo(
+ FloatPoint(m_currentPoint.x(), segment.targetPoint.y()));
+ break;
+ case PathSegLineToVerticalRel:
+ emitLineTo(
+ m_currentPoint + FloatSize(0, segment.targetPoint.y()));
+ break;
+ case PathSegCurveToQuadraticAbs:
+ emitQuadTo(
+ segment.point1,
+ segment.targetPoint);
+ break;
+ case PathSegCurveToQuadraticRel:
+ emitQuadTo(
+ m_currentPoint + segment.point1,
+ m_currentPoint + segment.targetPoint);
+ break;
+ case PathSegCurveToQuadraticSmoothAbs:
+ emitSmoothQuadTo(
+ segment.targetPoint);
+ break;
+ case PathSegCurveToQuadraticSmoothRel:
+ emitSmoothQuadTo(
+ m_currentPoint + segment.targetPoint);
break;
case PathSegCurveToCubicAbs:
- m_path.addBezierCurveTo(segment.point1, segment.point2, segment.targetPoint);
+ emitCubicTo(
+ segment.point1,
+ segment.point2,
+ segment.targetPoint);
+ break;
+ case PathSegCurveToCubicRel:
+ emitCubicTo(
+ m_currentPoint + segment.point1,
+ m_currentPoint + segment.point2,
+ m_currentPoint + segment.targetPoint);
+ break;
+ case PathSegCurveToCubicSmoothAbs:
+ emitSmoothCubicTo(
+ segment.point2,
+ segment.targetPoint);
+ break;
+ case PathSegCurveToCubicSmoothRel:
+ emitSmoothCubicTo(
+ m_currentPoint + segment.point2,
+ m_currentPoint + segment.targetPoint);
+ break;
+ case PathSegArcAbs:
+ emitArcTo(
+ segment.targetPoint,
+ toFloatSize(segment.arcRadii()),
+ segment.arcAngle(),
+ segment.largeArcFlag(),
+ segment.sweepFlag());
+ break;
+ case PathSegArcRel:
+ emitArcTo(
+ m_currentPoint + segment.targetPoint,
+ toFloatSize(segment.arcRadii()),
+ segment.arcAngle(),
+ segment.largeArcFlag(),
+ segment.sweepFlag());
break;
default:
ASSERT_NOT_REACHED();
}
+
+ m_lastCommand = segment.command;
}
}
« no previous file with comments | « third_party/WebKit/Source/core/svg/SVGPathBuilder.h ('k') | third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698