diff options
-rw-r--r-- | src/core/SkPath.cpp | 30 | ||||
-rw-r--r-- | tests/PathTest.cpp | 9 |
2 files changed, 34 insertions, 5 deletions
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 2babe70185..738edd9d23 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -2129,7 +2129,8 @@ struct Convexicator { : fPtCount(0) , fConvexity(SkPath::kConvex_Convexity) , fDirection(SkPath::kUnknown_Direction) - , fIsFinite(true) { + , fIsFinite(true) + , fIsCurve(false) { fExpectedDir = kInvalid_DirChange; // warnings fLastPt.set(0, 0); @@ -2193,6 +2194,10 @@ struct Convexicator { return fIsFinite; } + void setCurve(bool isCurve) { + fIsCurve = isCurve; + } + private: void addVec(const SkVector& vec) { SkASSERT(vec.fX || vec.fY); @@ -2213,6 +2218,10 @@ private: case kStraight_DirChange: break; case kBackwards_DirChange: + if (fIsCurve) { + fConvexity = SkPath::kConcave_Convexity; + fDirection = SkPath::kUnknown_Direction; + } fLastVec = vec; break; case kInvalid_DirChange: @@ -2232,6 +2241,7 @@ private: SkPath::Direction fDirection; int fDx, fDy, fSx, fSy; bool fIsFinite; + bool fIsCurve; }; SkPath::Convexity SkPath::internalGetConvexity() const { @@ -2255,13 +2265,23 @@ SkPath::Convexity SkPath::internalGetConvexity() const { return kConcave_Convexity; } pts[1] = pts[0]; + // fall through + case kLine_Verb: count = 1; + state.setCurve(false); + break; + case kQuad_Verb: + // fall through + case kConic_Verb: + // fall through + case kCubic_Verb: + count = 2 + (kCubic_Verb == verb); + // As an additional enhancement, this could set curve true only + // if the curve is nonlinear + state.setCurve(true); break; - case kLine_Verb: count = 1; break; - case kQuad_Verb: count = 2; break; - case kConic_Verb: count = 2; break; - case kCubic_Verb: count = 3; break; case kClose_Verb: + state.setCurve(false); state.close(); count = 0; break; diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index a868d93d78..aeab7e6e25 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -38,6 +38,14 @@ static void test_add_rrect(skiatest::Reporter* reporter, const SkRect& bounds, REPORTER_ASSERT(reporter, bounds == path.getBounds()); } +static void test_skbug_3469(skiatest::Reporter* reporter) { + SkPath path; + path.moveTo(20, 20); + path.quadTo(20, 50, 80, 50); + path.quadTo(20, 50, 20, 80); + REPORTER_ASSERT(reporter, !path.isConvex()); +} + static void test_skbug_3239(skiatest::Reporter* reporter) { const float min = SkBits2Float(0xcb7f16c8); /* -16717512.000000 */ const float max = SkBits2Float(0x4b7f1c1d); /* 16718877.000000 */ @@ -3732,5 +3740,6 @@ DEF_TEST(Paths, reporter) { PathRefTest_Private::TestPathRef(reporter); test_dump(reporter); test_path_crbugskia2820(reporter); + test_skbug_3469(reporter); test_skbug_3239(reporter); } |