test lineTo after addRect

Motivated by investigating
https://skia-review.googlesource.com/c/skia/+/330696

This CL does not fix anything, but is meant to better document
the current behavior.

Change-Id: I62b8cbfb39e05404f0f5303f024e1f56fc32b7e5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330937
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
Mike Reed 2020-10-31 10:31:55 -04:00 committed by Skia Commit-Bot
parent de48febf8b
commit b21c1f2d44
3 changed files with 95 additions and 38 deletions

View File

@ -1047,48 +1047,41 @@ public:
private:
#endif
/** Adds SkRect to SkPath, appending kMove_Verb, three kLine_Verb, and kClose_Verb,
starting with top-left corner of SkRect; followed by top-right, bottom-right,
and bottom-left if dir is kCW_Direction; or followed by bottom-left,
bottom-right, and top-right if dir is kCCW_Direction.
/** Adds a new contour to the path, defined by the rect, and wound in the
specified direction. The verbs added to the path will be:
@param rect SkRect to add as a closed contour
@param dir SkPath::Direction to wind added contour
@return reference to SkPath
kMove, kLine, kLine, kLine, kClose
example: https://fiddle.skia.org/c/@Path_addRect
*/
SkPath& addRect(const SkRect& rect, SkPathDirection dir = SkPathDirection::kCW);
start specifies which corner to begin the contour:
0: upper-left corner
1: upper-right corner
2: lower-right corner
3: lower-left corner
/** Adds SkRect to SkPath, appending kMove_Verb, three kLine_Verb, and kClose_Verb.
If dir is kCW_Direction, SkRect corners are added clockwise; if dir is
kCCW_Direction, SkRect corners are added counterclockwise.
start determines the first corner added.
This start point also acts as the implied beginning of the subsequent,
contour, if it does not have an explicit moveTo(). e.g.
path.addRect(...)
// if we don't say moveTo() here, we will use the rect's start point
path.lineTo(...)
@param rect SkRect to add as a closed contour
@param dir SkPath::Direction to wind added contour
@param dir SkPath::Direction to orient the new contour
@param start initial corner of SkRect to add
@return reference to SkPath
example: https://fiddle.skia.org/c/@Path_addRect_2
*/
*/
SkPath& addRect(const SkRect& rect, SkPathDirection dir, unsigned start);
/** Adds SkRect (left, top, right, bottom) to SkPath,
appending kMove_Verb, three kLine_Verb, and kClose_Verb,
starting with top-left corner of SkRect; followed by top-right, bottom-right,
and bottom-left if dir is kCW_Direction; or followed by bottom-left,
bottom-right, and top-right if dir is kCCW_Direction.
SkPath& addRect(const SkRect& rect, SkPathDirection dir = SkPathDirection::kCW) {
return this->addRect(rect, dir, 0);
}
@param left smaller x-axis value of SkRect
@param top smaller y-axis value of SkRect
@param right larger x-axis value of SkRect
@param bottom larger y-axis value of SkRect
@param dir SkPath::Direction to wind added contour
@return reference to SkPath
*/
SkPath& addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
SkPathDirection dir = SkPathDirection::kCW);
SkPathDirection dir = SkPathDirection::kCW) {
return this->addRect({left, top, right, bottom}, dir, 0);
}
/** Adds oval to path, appending kMove_Verb, four kConic_Verb, and kClose_Verb.
Oval is upright ellipse bounded by SkRect oval with radii equal to half oval width

View File

@ -766,15 +766,6 @@ static void assert_known_direction(SkPathDirection dir) {
SkASSERT(SkPathDirection::kCW == dir || SkPathDirection::kCCW == dir);
}
SkPath& SkPath::addRect(const SkRect& rect, SkPathDirection dir) {
return this->addRect(rect, dir, 0);
}
SkPath& SkPath::addRect(SkScalar left, SkScalar top, SkScalar right,
SkScalar bottom, SkPathDirection dir) {
return this->addRect(SkRect::MakeLTRB(left, top, right, bottom), dir, 0);
}
SkPath& SkPath::addRect(const SkRect &rect, SkPathDirection dir, unsigned startIndex) {
assert_known_direction(dir);
this->setFirstDirection(this->hasOnlyMoveTos() ? (SkPathFirstDirection)dir

View File

@ -5665,7 +5665,80 @@ static void test_edger(skiatest::Reporter* r,
REPORTER_ASSERT(r, !iter.next());
}
static void assert_points(skiatest::Reporter* reporter,
const SkPath& path, const std::initializer_list<SkPoint>& list) {
const SkPoint* expected = list.begin();
SkPath::RawIter iter(path);
for (size_t i = 0;;) {
SkPoint pts[4];
switch (iter.next(pts)) {
case SkPath::kDone_Verb:
REPORTER_ASSERT(reporter, i == list.size());
return;
case SkPath::kMove_Verb:
REPORTER_ASSERT(reporter, pts[0] == expected[i]);
i++;
break;
case SkPath::kLine_Verb:
REPORTER_ASSERT(reporter, pts[1] == expected[i]);
i++;
break;
case SkPath::kClose_Verb: break;
default: SkASSERT(false);
}
}
}
static void test_addRect_and_trailing_lineTo(skiatest::Reporter* reporter) {
SkPath path;
const SkRect r = {1, 2, 3, 4};
// build our default p-array clockwise
const SkPoint p[] = {
{r.fLeft, r.fTop}, {r.fRight, r.fTop},
{r.fRight, r.fBottom}, {r.fLeft, r.fBottom},
};
for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
int increment = dir == SkPathDirection::kCW ? 1 : 3;
for (int i = 0; i < 4; ++i) {
path.reset();
path.addRect(r, dir, i);
// check that we return the 4 ponts in the expected order
SkPoint e[4];
for (int j = 0; j < 4; ++j) {
int index = (i + j*increment) % 4;
e[j] = p[index];
}
assert_points(reporter, path, {
e[0], e[1], e[2], e[3]
});
// check that the new line begins where the rect began
path.lineTo(7,8);
assert_points(reporter, path, {
e[0], e[1], e[2], e[3],
e[0], {7,8},
});
}
}
// now add a moveTo before the rect, just to be sure we don't always look at
// the "first" point in the path when we handle the trailing lineTo
path.reset();
path.moveTo(7, 8);
path.addRect(r, SkPathDirection::kCW, 2);
path.lineTo(5, 6);
assert_points(reporter, path, {
{7,8}, // initial moveTo
p[2], p[3], p[0], p[1], // rect
p[2], {5, 6}, // trailing line
});
}
DEF_TEST(pathedger, r) {
test_addRect_and_trailing_lineTo(r); return;
auto M = SkPath::kMove_Verb;
auto L = SkPath::kLine_Verb;
auto C = SkPath::kClose_Verb;