treat backwards quads as not convex
If a quad, cubic, or conic goes back on itself, assume it's not convex. In a future CL, we could check to see if the curve is linear so that linear curves are treated the same as lines. BUG=skia:3469 Review URL: https://codereview.chromium.org/971773002
This commit is contained in:
parent
341c808070
commit
5ccef57790
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user