summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit/Source
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/WebKit/Source')
-rw-r--r--third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h3
-rw-r--r--third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp177
-rw-r--r--third_party/WebKit/Source/core/svg/SVGPathBuilder.h25
-rw-r--r--third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp4
-rw-r--r--third_party/WebKit/Source/platform/graphics/Path.cpp10
-rw-r--r--third_party/WebKit/Source/platform/graphics/Path.h1
6 files changed, 210 insertions, 10 deletions
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h b/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h
index 878c45b..5dec45f 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h
+++ b/third_party/WebKit/Source/core/layout/svg/SVGMarkerData.h
@@ -137,7 +137,8 @@ private:
switch (element->type) {
case PathElementAddQuadCurveToPoint:
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=33115 (PathElementAddQuadCurveToPoint not handled for <marker>)
+ m_inslopePoints[0] = points[0];
+ m_inslopePoints[1] = points[1];
m_origin = points[1];
break;
case PathElementAddCurveToPoint:
diff --git a/third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp b/third_party/WebKit/Source/core/svg/SVGPathBuilder.cpp
index 32e47dd..0fcd338 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;
}
} // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGPathBuilder.h b/third_party/WebKit/Source/core/svg/SVGPathBuilder.h
index 6cbe279..522bee4 100644
--- a/third_party/WebKit/Source/core/svg/SVGPathBuilder.h
+++ b/third_party/WebKit/Source/core/svg/SVGPathBuilder.h
@@ -25,19 +25,42 @@
#define SVGPathBuilder_h
#include "core/svg/SVGPathConsumer.h"
+#include "core/svg/SVGPathData.h"
+#include "platform/geometry/FloatPoint.h"
namespace blink {
+class FloatSize;
class Path;
class SVGPathBuilder final : public SVGPathConsumer {
public:
- SVGPathBuilder(Path& path) : m_path(path) { }
+ SVGPathBuilder(Path& path)
+ : m_path(path)
+ // Starting in ClosePath state ensures correct handling of the first moveTo.
+ , m_lastCommand(PathSegClosePath)
+ { }
private:
void emitSegment(const PathSegmentData&) override;
+ void emitClose();
+ void emitMoveTo(const FloatPoint&);
+ void emitLineTo(const FloatPoint&);
+ void emitQuadTo(const FloatPoint&, const FloatPoint&);
+ void emitSmoothQuadTo(const FloatPoint&);
+ void emitCubicTo(const FloatPoint&, const FloatPoint&, const FloatPoint&);
+ void emitSmoothCubicTo(const FloatPoint&, const FloatPoint&);
+ void emitArcTo(const FloatPoint&, const FloatSize&, float, bool largeArc, bool sweep);
+
+ FloatPoint smoothControl(bool isSmooth) const;
+
Path& m_path;
+
+ SVGPathSegType m_lastCommand;
+ FloatPoint m_subpathPoint;
+ FloatPoint m_currentPoint;
+ FloatPoint m_lastControlPoint;
};
} // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp b/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp
index a4b9ddb..259bf0e 100644
--- a/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp
@@ -36,7 +36,7 @@ bool buildPathFromString(const String& d, Path& result)
SVGPathBuilder builder(result);
SVGPathStringSource source(d);
SVGPathParser parser(&source, &builder);
- return parser.parsePathDataFromSource(NormalizedParsing);
+ return parser.parsePathDataFromSource(UnalteredParsing);
}
bool buildPathFromByteStream(const SVGPathByteStream& stream, Path& result)
@@ -47,7 +47,7 @@ bool buildPathFromByteStream(const SVGPathByteStream& stream, Path& result)
SVGPathBuilder builder(result);
SVGPathByteStreamSource source(stream);
SVGPathParser parser(&source, &builder);
- return parser.parsePathDataFromSource(NormalizedParsing);
+ return parser.parsePathDataFromSource(UnalteredParsing);
}
String buildStringFromByteStream(const SVGPathByteStream& stream)
diff --git a/third_party/WebKit/Source/platform/graphics/Path.cpp b/third_party/WebKit/Source/platform/graphics/Path.cpp
index c54308e..f18b2f2 100644
--- a/third_party/WebKit/Source/platform/graphics/Path.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Path.cpp
@@ -331,6 +331,16 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
m_path.arcTo(p1.data(), p2.data(), WebCoreFloatToSkScalar(radius));
}
+void Path::addArcTo(const FloatPoint& p, const FloatSize& r, float xRotate, bool largeArc, bool sweep)
+{
+ m_path.arcTo(
+ WebCoreFloatToSkScalar(r.width()), WebCoreFloatToSkScalar(r.height()),
+ WebCoreFloatToSkScalar(xRotate),
+ largeArc ? SkPath::kLarge_ArcSize : SkPath::kSmall_ArcSize,
+ sweep ? SkPath::kCW_Direction : SkPath::kCCW_Direction,
+ WebCoreFloatToSkScalar(p.x()), WebCoreFloatToSkScalar(p.y()));
+}
+
void Path::closeSubpath()
{
m_path.close();
diff --git a/third_party/WebKit/Source/platform/graphics/Path.h b/third_party/WebKit/Source/platform/graphics/Path.h
index f2a4f72..c46b5ac 100644
--- a/third_party/WebKit/Source/platform/graphics/Path.h
+++ b/third_party/WebKit/Source/platform/graphics/Path.h
@@ -122,6 +122,7 @@ public:
void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint);
void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint);
void addArcTo(const FloatPoint&, const FloatPoint&, float radius);
+ void addArcTo(const FloatPoint&, const FloatSize& r, float xRotate, bool largeArc, bool sweep);
void closeSubpath();
void addArc(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);