Add isRect variant that returns path closure and direction.
Add path test to verify that when isRect() returns false, output parameters are unchanged. Review URL: https://codereview.appspot.com/6855074 git-svn-id: http://skia.googlecode.com/svn/trunk@6524 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
f276fa74f5
commit
f68154a3cf
@ -535,6 +535,17 @@ public:
|
||||
return this->cheapComputeDirection(&computedDir) && computedDir == dir;
|
||||
}
|
||||
|
||||
/** Returns true if the path specifies a rectangle. If so, and if isClosed is
|
||||
not null, set isClosed to true if the path is closed. Also, if returning true
|
||||
and direction is not null, return the rect direction. If the path does not
|
||||
specify a rectangle, return false and ignore isClosed and direction.
|
||||
|
||||
@param isClosed If not null, set to true if the path is closed
|
||||
@param direction If not null, set to the rectangle's direction
|
||||
@return true if the path specifies a rectangle
|
||||
*/
|
||||
bool isRect(bool* isClosed, Direction* direction) const;
|
||||
|
||||
/** Add a closed rectangle contour to the path
|
||||
@param rect The rectangle to add as a closed contour to the path
|
||||
@param dir The direction to wind the rectangle's contour
|
||||
@ -917,7 +928,8 @@ private:
|
||||
|
||||
Convexity internalGetConvexity() const;
|
||||
|
||||
bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts) const;
|
||||
bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
|
||||
bool* isClosed, Direction* direction) const;
|
||||
|
||||
friend class SkAutoPathBoundsUpdate;
|
||||
friend class SkAutoDisableOvalCheck;
|
||||
|
@ -459,9 +459,9 @@ bool SkPath::isLine(SkPoint line[2]) const {
|
||||
|
||||
The direction is computed such that:
|
||||
0: vertical up
|
||||
1: horizontal right
|
||||
1: horizontal left
|
||||
2: vertical down
|
||||
3: horizontal left
|
||||
3: horizontal right
|
||||
|
||||
A rectangle cycles up/right/down/left or up/left/down/right.
|
||||
|
||||
@ -488,7 +488,8 @@ FIXME: Allow colinear quads and cubics to be treated like lines.
|
||||
FIXME: If the API passes fill-only, return true if the filled stroke
|
||||
is a rectangle, though the caller failed to close the path.
|
||||
*/
|
||||
bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** ptsPtr) const {
|
||||
bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** ptsPtr,
|
||||
bool* isClosed, Direction* direction) const {
|
||||
int corners = 0;
|
||||
SkPoint first, last;
|
||||
const SkPoint* pts = *ptsPtr;
|
||||
@ -571,6 +572,12 @@ bool SkPath::isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts
|
||||
if (savePts) {
|
||||
*ptsPtr = savePts;
|
||||
}
|
||||
if (result && isClosed) {
|
||||
*isClosed = autoClose;
|
||||
}
|
||||
if (result && direction) {
|
||||
*direction = firstDirection == (lastDirection + 1 & 3) ? kCCW_Direction : kCW_Direction;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -578,24 +585,31 @@ bool SkPath::isRect(SkRect* rect) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
int currVerb = 0;
|
||||
const SkPoint* pts = fPathRef->points();
|
||||
bool result = isRectContour(false, &currVerb, &pts);
|
||||
bool result = isRectContour(false, &currVerb, &pts, NULL, NULL);
|
||||
if (result && rect) {
|
||||
*rect = getBounds();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SkPath::isRect(bool* isClosed, Direction* direction) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
int currVerb = 0;
|
||||
const SkPoint* pts = fPathRef->points();
|
||||
return isRectContour(false, &currVerb, &pts, isClosed, direction);
|
||||
}
|
||||
|
||||
bool SkPath::isNestedRects(SkRect rects[2]) const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
int currVerb = 0;
|
||||
const SkPoint* pts = fPathRef->points();
|
||||
const SkPoint* first = pts;
|
||||
if (!isRectContour(true, &currVerb, &pts)) {
|
||||
if (!isRectContour(true, &currVerb, &pts, NULL, NULL)) {
|
||||
return false;
|
||||
}
|
||||
const SkPoint* last = pts;
|
||||
SkRect testRects[2];
|
||||
if (isRectContour(false, &currVerb, &pts)) {
|
||||
if (isRectContour(false, &currVerb, &pts, NULL, NULL)) {
|
||||
testRects[0].set(first, last - first);
|
||||
testRects[1].set(last, pts - last);
|
||||
if (testRects[0].contains(testRects[1])) {
|
||||
|
@ -1052,12 +1052,34 @@ static void test_isRect(skiatest::Reporter* reporter) {
|
||||
path.close();
|
||||
}
|
||||
REPORTER_ASSERT(reporter, fail ^ path.isRect(0));
|
||||
REPORTER_ASSERT(reporter, fail ^ path.isRect(NULL, NULL));
|
||||
|
||||
if (!fail) {
|
||||
SkRect computed, expected;
|
||||
expected.set(tests[testIndex], testLen[testIndex] / sizeof(SkPoint));
|
||||
REPORTER_ASSERT(reporter, path.isRect(&computed));
|
||||
REPORTER_ASSERT(reporter, expected == computed);
|
||||
|
||||
bool isClosed;
|
||||
SkPath::Direction direction, cheapDirection;
|
||||
REPORTER_ASSERT(reporter, path.cheapComputeDirection(&cheapDirection));
|
||||
REPORTER_ASSERT(reporter, path.isRect(&isClosed, &direction));
|
||||
REPORTER_ASSERT(reporter, isClosed == close);
|
||||
REPORTER_ASSERT(reporter, direction == cheapDirection);
|
||||
} else {
|
||||
SkRect computed;
|
||||
computed.set(123, 456, 789, 1011);
|
||||
REPORTER_ASSERT(reporter, !path.isRect(&computed));
|
||||
REPORTER_ASSERT(reporter, computed.fLeft == 123 && computed.fTop == 456);
|
||||
REPORTER_ASSERT(reporter, computed.fRight == 789 && computed.fBottom == 1011);
|
||||
|
||||
bool isClosed = (bool) -1;
|
||||
SkPath::Direction direction = (SkPath::Direction) -1;
|
||||
REPORTER_ASSERT(reporter, !path.isRect(&isClosed, &direction));
|
||||
REPORTER_ASSERT(reporter, isClosed == (bool) -1);
|
||||
REPORTER_ASSERT(reporter, direction == (SkPath::Direction) -1);
|
||||
}
|
||||
|
||||
if (tests[testIndex] == lastPass) {
|
||||
fail = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user