tiny concave path point fix

The tiny path added to PathTest.cpp has
tinier cross products (e.g. 1e-12)
so appears to be a series of unbending
lines as far as getConvexity is concerned.

This point fix looks for paths that
do not bend left or right or go backwards,
but do have a bounds, and calls them
concave.

A better fix may be to consider empty
and degenerate paths to be concave
instead of convex; I don't know if
anyone relies on the existing behavior.

Another better fix may be to change
the math to compute the path turns
even though the numbers are very small;
on the surface, very difficult.

R=bsalomon@google.com,reed@google.com
Bug:755839
Change-Id: Ie2280f3f0b95fecab2899f5fc579fd39258e0647
Reviewed-on: https://skia-review.googlesource.com/38720
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Cary Clark <caryclark@google.com>
This commit is contained in:
Cary Clark 2017-08-25 08:04:43 -04:00 committed by Skia Commit-Bot
parent 5563d8da7d
commit c8323aa51a
2 changed files with 23 additions and 2 deletions

View File

@ -2301,7 +2301,8 @@ struct Convexicator {
, fConvexity(SkPath::kConvex_Convexity)
, fFirstDirection(SkPathPriv::kUnknown_FirstDirection)
, fIsFinite(true)
, fIsCurve(false) {
, fIsCurve(false)
, fBackwards(false) {
fExpectedDir = kInvalid_DirChange;
// warnings
fPriorPt.set(0,0);
@ -2400,6 +2401,9 @@ struct Convexicator {
return kStraight_DirChange;
}
bool hasBackwards() const {
return fBackwards;
}
bool isFinite() const {
return fIsFinite;
@ -2435,6 +2439,7 @@ private:
fExpectedDir = dir;
}
fLastVec = vec;
fBackwards = true;
break;
case kInvalid_DirChange:
SK_ABORT("Use of invalid direction change flag");
@ -2455,6 +2460,7 @@ private:
int fDx, fDy, fSx, fSy;
bool fIsFinite;
bool fIsCurve;
bool fBackwards;
};
SkPath::Convexity SkPath::internalGetConvexity() const {
@ -2518,8 +2524,13 @@ SkPath::Convexity SkPath::internalGetConvexity() const {
}
fConvexity = state.getConvexity();
if (kConvex_Convexity == fConvexity && SkPathPriv::kUnknown_FirstDirection == fFirstDirection) {
if (SkPathPriv::kUnknown_FirstDirection == state.getFirstDirection() &&
!this->getBounds().isEmpty() && !state.hasBackwards()) {
fConvexity = Convexity::kConcave_Convexity;
} else {
fFirstDirection = state.getFirstDirection();
}
}
return static_cast<Convexity>(fConvexity);
}

View File

@ -1681,6 +1681,16 @@ static void test_convexity(skiatest::Reporter* reporter) {
: SkPath::kUnknown_Convexity);
}
path.reset();
path.moveTo(SkBits2Float(0xbe9171db), SkBits2Float(0xbd7eeb5d)); // -0.284072f, -0.0622362f
path.lineTo(SkBits2Float(0xbe9171db), SkBits2Float(0xbd7eea38)); // -0.284072f, -0.0622351f
path.lineTo(SkBits2Float(0xbe9171a0), SkBits2Float(0xbd7ee5a7)); // -0.28407f, -0.0622307f
path.lineTo(SkBits2Float(0xbe917147), SkBits2Float(0xbd7ed886)); // -0.284067f, -0.0622182f
path.lineTo(SkBits2Float(0xbe917378), SkBits2Float(0xbd7ee1a9)); // -0.284084f, -0.0622269f
path.lineTo(SkBits2Float(0xbe9171db), SkBits2Float(0xbd7eeb5d)); // -0.284072f, -0.0622362f
path.close();
check_convexity(reporter, path, SkPath::kConcave_Convexity);
}
static void test_isLine(skiatest::Reporter* reporter) {