diff options
-rw-r--r-- | gm/pathfill.cpp | 10 | ||||
-rw-r--r-- | src/core/SkPath.cpp | 10 | ||||
-rw-r--r-- | tests/PathTest.cpp | 6 |
3 files changed, 22 insertions, 4 deletions
diff --git a/gm/pathfill.cpp b/gm/pathfill.cpp index 0fcffdc23f..db1f3f2557 100644 --- a/gm/pathfill.cpp +++ b/gm/pathfill.cpp @@ -558,4 +558,14 @@ DEF_SIMPLE_GM(bug7792, canvas, 600, 800) { path.moveTo(75, 75); path.close(); canvas->drawPath(path, p); + // from skbug.com/7792#c36 + canvas->translate(200, 0); + path.reset(); + path.moveTo(75, 75); + path.lineTo(150, 75); + path.lineTo(150, 150); + path.lineTo(10, 150); + path.moveTo(75, 75); + path.lineTo(75, 75); + canvas->drawPath(path, p); } diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 0ff5edf109..ff4208a346 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -450,6 +450,7 @@ static int rect_make_dir(SkScalar dx, SkScalar dy) { bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** ptsPtr, bool* isClosed, Direction* direction, SkRect* rect) const { int corners = 0; + SkPoint closeXY; // used to determine if final line falls on a diagonal SkPoint lineStart; // used to construct line from previous point const SkPoint* firstPt = nullptr; // first point in the rect (last of first moves) const SkPoint* lastPt = nullptr; // last point in the rect (last of lines or first if closed) @@ -538,6 +539,10 @@ bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts firstPt = pts; accumulatingRect = true; } else { + closeXY = *firstPt - *lastPt; + if (closeXY.fX && closeXY.fY) { + return false; // we're diagonal, abort + } accumulatingRect = false; } lineStart = *pts++; @@ -555,7 +560,7 @@ addMissingClose: if (corners < 3 || corners > 4) { return false; } - SkPoint closeXY = *firstPt - *lastPt; + closeXY = *firstPt - *lastPt; // If autoClose, check if close generates diagonal bool result = 4 == corners && (closeXY.isZero() || (autoClose && (!closeXY.fX || !closeXY.fY))); if (!result) { @@ -565,9 +570,6 @@ addMissingClose: // 3 sided rectangle // 4 sided but the last edge is not long enough to reach the start // - if (closeXY.fX && closeXY.fY) { - return false; // we're diagonal, abort (can we ever reach this?) - } int closeDirection = rect_make_dir(closeXY.fX, closeXY.fY); // make sure the close-segment doesn't double-back on itself if (3 == corners || (closeDirection ^ directions[1]) == 2) { diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index 817aa82b75..d7b38d87e1 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -5012,4 +5012,10 @@ DEF_TEST(Path_isRect, reporter) { REPORTER_ASSERT(reporter, path.isRect(&rect, nullptr, nullptr)); compare.set(&points31[0], 4); REPORTER_ASSERT(reporter, rect == compare); + // isolated from skbug.com/7792#c36 + SkPath::Verb verbs36[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, + SkPath::kLine_Verb, SkPath::kMove_Verb, SkPath::kLine_Verb }; + SkPoint points36[] = { {75, 75}, {150, 75}, {150, 150}, {10, 150}, {75, 75}, {75, 75} }; + path = makePath2(points36, verbs36, SK_ARRAY_COUNT(verbs36)); + REPORTER_ASSERT(reporter, !path.isRect(&rect, nullptr, nullptr)); } |