Use double precision when iterating in SkDashPathEffect::filterPath()
Extremely large path_length/dash_length ratios may cause us to loop
indefinitely otherwise.
R=reed@google.com
BUG=
Review URL: https://codereview.appspot.com/6926051
git-svn-id: http://skia.googlecode.com/svn/trunk@6773 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp
index e2d3648..f2e36cc 100644
--- a/src/effects/SkDashPathEffect.cpp
+++ b/src/effects/SkDashPathEffect.cpp
@@ -186,8 +186,10 @@
}
}
- SkScalar distance = 0;
- SkScalar dlen = SkScalarMul(fInitialDashLength, scale);
+ // Using double precision to avoid looping indefinitely due to single precision rounding
+ // (for extreme path_length/dash_length ratios). See test_infinite_dash() unittest.
+ double distance = 0;
+ double dlen = SkScalarMul(fInitialDashLength, scale);
while (distance < length) {
SkASSERT(dlen >= 0);
diff --git a/tests/DrawPathTest.cpp b/tests/DrawPathTest.cpp
index 171a63c..fdabd01 100644
--- a/tests/DrawPathTest.cpp
+++ b/tests/DrawPathTest.cpp
@@ -219,6 +219,28 @@
canvas.get()->drawPath(path, paint);
}
+// Extremely large path_length/dash_length ratios may cause infinite looping
+// in SkDashPathEffect::filterPath() due to single precision rounding.
+// The test is quite expensive, but it should get much faster after the fix
+// for http://crbug.com/165432 goes in.
+static void test_infinite_dash(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(5000000, 0);
+
+ SkScalar intervals[] = { 0.2f, 0.2f };
+ SkDashPathEffect dash(intervals, 2, 0);
+
+ SkPath filteredPath;
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setPathEffect(&dash);
+
+ paint.getFillPath(path, &filteredPath);
+ // If we reach this, we passed.
+ REPORTER_ASSERT(reporter, true);
+}
+
static void TestDrawPath(skiatest::Reporter* reporter) {
test_giantaa(reporter);
test_bug533(reporter);
@@ -228,6 +250,7 @@
test_crbug_140803(reporter);
test_inversepathwithclip(reporter);
// test_crbug131181(reporter);
+ test_infinite_dash(reporter);
}
#include "TestClassDef.h"