Change getConvexity() to now compute it if the value is set to kUnkown.
Change behavior for degenerate paths: now those return kConvex instead of kUnknown git-svn-id: http://skia.googlecode.com/svn/trunk@1330 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
27a4dc4c36
commit
b54455e440
@ -88,9 +88,10 @@ public:
|
||||
/** Returns true if the filltype is one of the Inverse variants */
|
||||
bool isInverseFillType() const { return (fFillType & 2) != 0; }
|
||||
|
||||
/** Toggle between inverse and normal filltypes. This reverse the return
|
||||
value of isInverseFillType()
|
||||
*/
|
||||
/**
|
||||
* Toggle between inverse and normal filltypes. This reverse the return
|
||||
* value of isInverseFillType()
|
||||
*/
|
||||
void toggleInverseFillType() {
|
||||
fFillType ^= 2;
|
||||
GEN_ID_INC;
|
||||
@ -103,14 +104,33 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the path's convexity, as stored in the path.
|
||||
* Return the path's convexity, as stored in the path. If it is currently
|
||||
* unknown, and the computeIfUnknown bool is true, then this will first
|
||||
* call ComputeConvexity() and then return that (cached) value.
|
||||
*/
|
||||
Convexity getConvexity() const { return (Convexity)fConvexity; }
|
||||
Convexity getConvexity() const {
|
||||
if (kUnknown_Convexity == fConvexity) {
|
||||
fConvexity = (uint8_t)ComputeConvexity(*this);
|
||||
}
|
||||
return (Convexity)fConvexity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently cached value for convexity, even if that is set to
|
||||
* kUnknown_Convexity. Note: getConvexity() will automatically call
|
||||
* ComputeConvexity and cache its return value if the current setting is
|
||||
* kUnknown.
|
||||
*/
|
||||
Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; }
|
||||
|
||||
/**
|
||||
* Store a convexity setting in the path. There is no automatic check to
|
||||
* see if this value actually agress with the return value from
|
||||
* ComputeConvexity().
|
||||
*
|
||||
* Note: even if this is set to a "known" value, if the path is later
|
||||
* changed (e.g. lineTo(), addRect(), etc.) then the cached value will be
|
||||
* reset to kUnknown_Convexity.
|
||||
*/
|
||||
void setConvexity(Convexity);
|
||||
|
||||
@ -118,9 +138,11 @@ public:
|
||||
* Compute the convexity of the specified path. This does not look at the
|
||||
* value stored in the path, but computes it directly from the path's data.
|
||||
*
|
||||
* This never returns kUnknown_Convexity.
|
||||
*
|
||||
* If there is more than one contour, this returns kConcave_Convexity.
|
||||
* If the contour is degenerate (i.e. all segements are colinear,
|
||||
* then this returns kUnknown_Convexity.
|
||||
* If the contour is degenerate (e.g. there are fewer than 3 non-degenerate
|
||||
* segments), then this returns kConvex_Convexity.
|
||||
* The contour is treated as if it were closed, even if there is no kClose
|
||||
* verb.
|
||||
*/
|
||||
@ -635,7 +657,7 @@ private:
|
||||
mutable SkRect fBounds;
|
||||
mutable uint8_t fBoundsIsDirty;
|
||||
uint8_t fFillType;
|
||||
uint8_t fConvexity;
|
||||
mutable uint8_t fConvexity;
|
||||
#ifdef ANDROID
|
||||
uint32_t fGenerationID;
|
||||
#endif
|
||||
|
@ -254,6 +254,12 @@ void SkPath::setConvexity(Convexity c) {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Construction methods
|
||||
|
||||
#define DIRTY_AFTER_EDIT \
|
||||
do { \
|
||||
fBoundsIsDirty = true; \
|
||||
fConvexity = kUnknown_Convexity;\
|
||||
} while (0)
|
||||
|
||||
void SkPath::incReserve(U16CPU inc) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
@ -278,7 +284,7 @@ void SkPath::moveTo(SkScalar x, SkScalar y) {
|
||||
pt->set(x, y);
|
||||
|
||||
GEN_ID_INC;
|
||||
fBoundsIsDirty = true;
|
||||
DIRTY_AFTER_EDIT;
|
||||
}
|
||||
|
||||
void SkPath::rMoveTo(SkScalar x, SkScalar y) {
|
||||
@ -298,7 +304,7 @@ void SkPath::lineTo(SkScalar x, SkScalar y) {
|
||||
*fVerbs.append() = kLine_Verb;
|
||||
|
||||
GEN_ID_INC;
|
||||
fBoundsIsDirty = true;
|
||||
DIRTY_AFTER_EDIT;
|
||||
}
|
||||
|
||||
void SkPath::rLineTo(SkScalar x, SkScalar y) {
|
||||
@ -321,7 +327,7 @@ void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
|
||||
*fVerbs.append() = kQuad_Verb;
|
||||
|
||||
GEN_ID_INC;
|
||||
fBoundsIsDirty = true;
|
||||
DIRTY_AFTER_EDIT;
|
||||
}
|
||||
|
||||
void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
|
||||
@ -345,7 +351,7 @@ void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
*fVerbs.append() = kCubic_Verb;
|
||||
|
||||
GEN_ID_INC;
|
||||
fBoundsIsDirty = true;
|
||||
DIRTY_AFTER_EDIT;
|
||||
}
|
||||
|
||||
void SkPath::rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
@ -1293,7 +1299,7 @@ void SkPath::unflatten(SkReader32& buffer) {
|
||||
buffer.read(fVerbs.begin(), fVerbs.count());
|
||||
|
||||
GEN_ID_INC;
|
||||
fBoundsIsDirty = true;
|
||||
DIRTY_AFTER_EDIT;
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
@ -1410,7 +1416,7 @@ static int CrossProductSign(const SkVector& a, const SkVector& b) {
|
||||
|
||||
// only valid for a single contour
|
||||
struct Convexicator {
|
||||
Convexicator() : fPtCount(0), fConvexity(SkPath::kUnknown_Convexity) {
|
||||
Convexicator() : fPtCount(0), fConvexity(SkPath::kConvex_Convexity) {
|
||||
fSign = 0;
|
||||
// warnings
|
||||
fCurrPt.set(0, 0);
|
||||
@ -1472,9 +1478,7 @@ private:
|
||||
if (0 == fSign) {
|
||||
fSign = sign;
|
||||
} else if (sign) {
|
||||
if (fSign == sign) {
|
||||
fConvexity = SkPath::kConvex_Convexity;
|
||||
} else {
|
||||
if (fSign != sign) {
|
||||
fConvexity = SkPath::kConcave_Convexity;
|
||||
}
|
||||
}
|
||||
|
@ -13,15 +13,13 @@ static void test_convexity2(skiatest::Reporter* reporter) {
|
||||
SkPath pt;
|
||||
pt.moveTo(0, 0);
|
||||
pt.close();
|
||||
// check_convexity(reporter, pt, SkPath::kConvex_Convexity);
|
||||
check_convexity(reporter, pt, SkPath::kUnknown_Convexity);
|
||||
check_convexity(reporter, pt, SkPath::kConvex_Convexity);
|
||||
|
||||
SkPath line;
|
||||
line.moveTo(12, 20);
|
||||
line.lineTo(-12, -20);
|
||||
line.close();
|
||||
// check_convexity(reporter, pt, SkPath::kConvex_Convexity);
|
||||
check_convexity(reporter, pt, SkPath::kUnknown_Convexity);
|
||||
check_convexity(reporter, pt, SkPath::kConvex_Convexity);
|
||||
|
||||
SkPath triLeft;
|
||||
triLeft.moveTo(0, 0);
|
||||
@ -133,13 +131,12 @@ static void setFromString(SkPath* path, const char str[]) {
|
||||
}
|
||||
|
||||
static void test_convexity(skiatest::Reporter* reporter) {
|
||||
static const SkPath::Convexity U = SkPath::kUnknown_Convexity;
|
||||
static const SkPath::Convexity C = SkPath::kConcave_Convexity;
|
||||
static const SkPath::Convexity V = SkPath::kConvex_Convexity;
|
||||
|
||||
SkPath path;
|
||||
|
||||
REPORTER_ASSERT(reporter, U == SkPath::ComputeConvexity(path));
|
||||
REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
|
||||
path.addCircle(0, 0, 10);
|
||||
REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
|
||||
path.addCircle(0, 0, 10); // 2nd circle
|
||||
@ -155,8 +152,9 @@ static void test_convexity(skiatest::Reporter* reporter) {
|
||||
const char* fPathStr;
|
||||
SkPath::Convexity fExpectedConvexity;
|
||||
} gRec[] = {
|
||||
{ "0 0", SkPath::kUnknown_Convexity },
|
||||
{ "0 0 10 10", SkPath::kUnknown_Convexity },
|
||||
{ "", SkPath::kConvex_Convexity },
|
||||
{ "0 0", SkPath::kConvex_Convexity },
|
||||
{ "0 0 10 10", SkPath::kConvex_Convexity },
|
||||
{ "0 0 10 10 20 20 0 0 10 10", SkPath::kConcave_Convexity },
|
||||
{ "0 0 10 10 10 20", SkPath::kConvex_Convexity },
|
||||
{ "0 0 10 10 10 0", SkPath::kConvex_Convexity },
|
||||
@ -188,7 +186,7 @@ void TestPath(skiatest::Reporter* reporter) {
|
||||
SkRect bounds, bounds2;
|
||||
|
||||
REPORTER_ASSERT(reporter, p.isEmpty());
|
||||
REPORTER_ASSERT(reporter, !p.isConvex());
|
||||
REPORTER_ASSERT(reporter, p.isConvex());
|
||||
REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType);
|
||||
REPORTER_ASSERT(reporter, !p.isInverseFillType());
|
||||
REPORTER_ASSERT(reporter, p == p2);
|
||||
@ -198,17 +196,14 @@ void TestPath(skiatest::Reporter* reporter) {
|
||||
|
||||
bounds.set(0, 0, SK_Scalar1, SK_Scalar1);
|
||||
|
||||
p.setIsConvex(false);
|
||||
p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1);
|
||||
check_convex_bounds(reporter, p, bounds);
|
||||
|
||||
p.reset();
|
||||
p.setIsConvex(false);
|
||||
p.addOval(bounds);
|
||||
check_convex_bounds(reporter, p, bounds);
|
||||
|
||||
p.reset();
|
||||
p.setIsConvex(false);
|
||||
p.addRect(bounds);
|
||||
check_convex_bounds(reporter, p, bounds);
|
||||
|
||||
@ -245,18 +240,6 @@ void TestPath(skiatest::Reporter* reporter) {
|
||||
p.getLastPt(&pt);
|
||||
REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1);
|
||||
|
||||
// check that reset and rewind clear the convex hint back to false
|
||||
p.setIsConvex(false);
|
||||
REPORTER_ASSERT(reporter, !p.isConvex());
|
||||
p.setIsConvex(true);
|
||||
REPORTER_ASSERT(reporter, p.isConvex());
|
||||
p.reset();
|
||||
REPORTER_ASSERT(reporter, !p.isConvex());
|
||||
p.setIsConvex(true);
|
||||
REPORTER_ASSERT(reporter, p.isConvex());
|
||||
p.rewind();
|
||||
REPORTER_ASSERT(reporter, !p.isConvex());
|
||||
|
||||
test_convexity(reporter);
|
||||
test_convexity2(reporter);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user