Index: Source/platform/graphics/Path.cpp |
diff --git a/Source/platform/graphics/Path.cpp b/Source/platform/graphics/Path.cpp |
index e04f4a8ea7b3752ec08b468f4ab578b7b9a46ae7..3671bcf6c71d020204d7b2eca7a2999f3dccd395 100644 |
--- a/Source/platform/graphics/Path.cpp |
+++ b/Source/platform/graphics/Path.cpp |
@@ -36,7 +36,6 @@ |
#include "platform/graphics/GraphicsContext.h" |
#include "platform/graphics/skia/SkiaUtils.h" |
#include "platform/transforms/AffineTransform.h" |
-#include "third_party/skia/include/core/SkPathMeasure.h" |
#include "third_party/skia/include/pathops/SkPathOps.h" |
#include "wtf/MathExtras.h" |
@@ -177,10 +176,8 @@ float Path::normalAngleAtLength(float length, bool& ok) const |
return normal; |
} |
-bool Path::pointAndNormalAtLength(float length, FloatPoint& point, float& normal) const |
+static bool calculatePointAndNormalOnPath(SkPathMeasure& measure, SkScalar length, FloatPoint& point, float& normalAngle, SkScalar* accumulatedLength = 0) |
{ |
- SkPathMeasure measure(m_path, false); |
- |
do { |
SkScalar contourLength = measure.getLength(); |
if (length <= contourLength) { |
@@ -188,19 +185,58 @@ bool Path::pointAndNormalAtLength(float length, FloatPoint& point, float& normal |
SkPoint position; |
if (measure.getPosTan(length, &position, &tangent)) { |
- normal = rad2deg(SkScalarToFloat(SkScalarATan2(tangent.fY, tangent.fX))); |
+ normalAngle = rad2deg(SkScalarToFloat(SkScalarATan2(tangent.fY, tangent.fX))); |
point = FloatPoint(SkScalarToFloat(position.fX), SkScalarToFloat(position.fY)); |
return true; |
} |
} |
length -= contourLength; |
+ if (accumulatedLength) |
+ *accumulatedLength += contourLength; |
} while (measure.nextContour()); |
+ return false; |
+} |
+ |
+bool Path::pointAndNormalAtLength(float length, FloatPoint& point, float& normal) const |
+{ |
+ SkPathMeasure measure(m_path, false); |
+ |
+ if (calculatePointAndNormalOnPath(measure, WebCoreFloatToSkScalar(length), point, normal)) |
+ return true; |
normal = 0; |
point = FloatPoint(0, 0); |
return false; |
} |
+Path::PositionCalculator::PositionCalculator(const Path& path) |
+ : m_path(path.skPath()) |
+ , m_pathMeasure(path.skPath(), false) |
+ , m_accumulatedLength(0) |
+{ |
+} |
+ |
+bool Path::PositionCalculator::pointAndNormalAtLength(float length, FloatPoint& point, float& normalAngle) |
+{ |
+ SkScalar skLength = WebCoreFloatToSkScalar(length); |
+ if (skLength >= 0) { |
+ if (skLength < m_accumulatedLength) { |
+ // Reset path measurer to rewind (and restart from 0). |
+ m_pathMeasure.setPath(&m_path, false); |
+ m_accumulatedLength = 0; |
+ } else { |
+ skLength -= m_accumulatedLength; |
+ } |
+ |
+ if (calculatePointAndNormalOnPath(m_pathMeasure, skLength, point, normalAngle, &m_accumulatedLength)) |
+ return true; |
+ } |
+ |
+ normalAngle = 0; |
+ point = FloatPoint(0, 0); |
+ return false; |
+} |
+ |
void Path::clear() |
{ |
m_path.reset(); |