add SkPath::isLine(), similar to isRect()

git-svn-id: http://skia.googlecode.com/svn/trunk@3892 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2012-05-10 14:05:43 +00:00
parent 963a8fa542
commit 7e6c4d1601
3 changed files with 74 additions and 1 deletions

View File

@ -221,6 +221,14 @@ public:
p3.equalsWithinTolerance(p4);
}
/**
* Returns true if the path specifies a single line (i.e. it contains just
* a moveTo and a lineTo). If so, and line[] is not null, it sets the 2
* points in line[] to the end-points of the line. If the path is not a
* line, returns false and ignores line[].
*/
bool isLine(SkPoint line[2]) const;
/** Returns true if the path specifies a rectangle. If so, and if rect is
not null, set rect to the bounds of the path. If the path does not
specify a rectangle, return false and ignore rect.

View File

@ -249,6 +249,24 @@ bool SkPath::isEmpty() const {
return 0 == fVerbs.count();
}
bool SkPath::isLine(SkPoint line[2]) const {
int verbCount = fVerbs.count();
int ptCount = fPts.count();
if (2 == verbCount && 2 == ptCount) {
const uint8_t* verbs = fVerbs.begin();
if (kMove_Verb == verbs[0] && kLine_Verb == verbs[1]) {
if (line) {
const SkPoint* pts = fPts.begin();
line[0] = pts[0];
line[1] = pts[1];
}
return true;
}
}
return false;
}
/*
Determines if path is a rect by keeping track of changes in direction
and looking for a loop either clockwise or counterclockwise.

View File

@ -425,6 +425,52 @@ static void test_convexity(skiatest::Reporter* reporter) {
}
}
static void test_isLine(skiatest::Reporter* reporter) {
SkPath path;
SkPoint pts[2];
const SkScalar value = SkIntToScalar(5);
REPORTER_ASSERT(reporter, !path.isLine(NULL));
// set some non-zero values
pts[0].set(value, value);
pts[1].set(value, value);
REPORTER_ASSERT(reporter, !path.isLine(pts));
// check that pts was untouched
REPORTER_ASSERT(reporter, pts[0].equals(value, value));
REPORTER_ASSERT(reporter, pts[1].equals(value, value));
const SkScalar moveX = SkIntToScalar(1);
const SkScalar moveY = SkIntToScalar(2);
SkASSERT(value != moveX && value != moveY);
path.moveTo(moveX, moveY);
REPORTER_ASSERT(reporter, !path.isLine(NULL));
REPORTER_ASSERT(reporter, !path.isLine(pts));
// check that pts was untouched
REPORTER_ASSERT(reporter, pts[0].equals(value, value));
REPORTER_ASSERT(reporter, pts[1].equals(value, value));
const SkScalar lineX = SkIntToScalar(2);
const SkScalar lineY = SkIntToScalar(2);
SkASSERT(value != lineX && value != lineY);
path.lineTo(lineX, lineY);
REPORTER_ASSERT(reporter, path.isLine(NULL));
REPORTER_ASSERT(reporter, !pts[0].equals(moveX, moveY));
REPORTER_ASSERT(reporter, !pts[1].equals(lineX, lineY));
REPORTER_ASSERT(reporter, path.isLine(pts));
REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
path.lineTo(0, 0); // too many points/verbs
REPORTER_ASSERT(reporter, !path.isLine(NULL));
REPORTER_ASSERT(reporter, !path.isLine(pts));
REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
}
// Simple isRect test is inline TestPath, below.
// test_isRect provides more extensive testing.
static void test_isRect(skiatest::Reporter* reporter) {
@ -1315,8 +1361,9 @@ void TestPath(skiatest::Reporter* reporter) {
bounds.set(0, 0, SK_Scalar1/2, SK_Scalar1/2);
p.addRect(bounds);
REPORTER_ASSERT(reporter, !p.isRect(NULL));
test_isRect(reporter);
test_isLine(reporter);
test_isRect(reporter);
test_zero_length_paths(reporter);
test_direction(reporter);
test_convexity(reporter);