Reset conicWeights in SkPath::consumeDegenerateSegments when rewinding to last Move op
Without this patch the iterator can end up running off the end of the conic weights if there is a mixture of degenerate and non-degenerate ops
Note: we might want to suppress the generation of degenerate conics and lines in SkPath::addRRect
BUG=459897
Review URL: https://codereview.chromium.org/954453003
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index de3d297..0b796fc 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -1660,6 +1660,7 @@
// forward before the next move is seen
const uint8_t* lastMoveVerb = 0;
const SkPoint* lastMovePt = 0;
+ const SkScalar* lastMoveWeight = NULL;
SkPoint lastPt = fLastPt;
while (fVerbs != fVerbStop) {
unsigned verb = *(fVerbs - 1); // fVerbs is one beyond the current verb
@@ -1668,6 +1669,7 @@
// Keep a record of this most recent move
lastMoveVerb = fVerbs;
lastMovePt = fPts;
+ lastMoveWeight = fConicWeights;
lastPt = fPts[0];
fVerbs--;
fPts++;
@@ -1688,6 +1690,7 @@
if (lastMoveVerb) {
fVerbs = lastMoveVerb;
fPts = lastMovePt;
+ fConicWeights = lastMoveWeight;
return;
}
return;
@@ -1703,6 +1706,7 @@
if (lastMoveVerb) {
fVerbs = lastMoveVerb;
fPts = lastMovePt;
+ fConicWeights = lastMoveWeight;
return;
}
return;
@@ -1718,6 +1722,7 @@
if (lastMoveVerb) {
fVerbs = lastMoveVerb;
fPts = lastMovePt;
+ fConicWeights = lastMoveWeight;
return;
}
return;
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 7db65a8..a868d93 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -2475,6 +2475,20 @@
REPORTER_ASSERT(reporter, SkPath::kDone_Verb == iter.next(pts, true));
// The GM degeneratesegments.cpp test is more extensive
+
+ // Test out mixed degenerate and non-degenerate geometry with Conics
+ const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } };
+ SkRect r = SkRect::MakeWH(100, 100);
+ SkRRect rr;
+ rr.setRectRadii(r, radii);
+ p.reset();
+ p.addRRect(rr);
+ iter.setPath(p, false);
+ REPORTER_ASSERT(reporter, SkPath::kMove_Verb == iter.next(pts));
+ REPORTER_ASSERT(reporter, SkPath::kLine_Verb == iter.next(pts));
+ REPORTER_ASSERT(reporter, SkPath::kLine_Verb == iter.next(pts));
+ REPORTER_ASSERT(reporter, SkPath::kConic_Verb == iter.next(pts));
+ REPORTER_ASSERT(reporter, SK_ScalarRoot2Over2 == iter.conicWeight());
}
static void test_raw_iter(skiatest::Reporter* reporter) {