Adding new 'extend' mode to SkPath::addPath
BUG=261727 R=reed@google.com, caryclark@google.com, schenney@chromium.org, robertphillips@google.com Author: junov@chromium.org Review URL: https://codereview.chromium.org/151353006 git-svn-id: http://skia.googlecode.com/svn/trunk@13415 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
e07dfe54c4
commit
14747e58f8
@ -702,25 +702,41 @@ public:
|
||||
*/
|
||||
void addPoly(const SkPoint pts[], int count, bool close);
|
||||
|
||||
enum AddPathMode {
|
||||
/** Source path contours are added as new contours.
|
||||
*/
|
||||
kAppend_AddPathMode,
|
||||
/** Path is added by extending the last contour of the destination path
|
||||
with the first contour of the source path. If the last contour of
|
||||
the destination path is closed, then it will not be extended.
|
||||
Instead, the start of source path will be extended by a straight
|
||||
line to the end point of the destination path.
|
||||
*/
|
||||
kExtend_AddPathMode
|
||||
};
|
||||
|
||||
/** Add a copy of src to the path, offset by (dx,dy)
|
||||
@param src The path to add as a new contour
|
||||
@param dx The amount to translate the path in X as it is added
|
||||
@param dx The amount to translate the path in Y as it is added
|
||||
*/
|
||||
void addPath(const SkPath& src, SkScalar dx, SkScalar dy);
|
||||
void addPath(const SkPath& src, SkScalar dx, SkScalar dy,
|
||||
AddPathMode mode = kAppend_AddPathMode);
|
||||
|
||||
/** Add a copy of src to the path
|
||||
*/
|
||||
void addPath(const SkPath& src) {
|
||||
void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
|
||||
SkMatrix m;
|
||||
m.reset();
|
||||
this->addPath(src, m);
|
||||
this->addPath(src, m, mode);
|
||||
}
|
||||
|
||||
/** Add a copy of src to the path, transformed by matrix
|
||||
@param src The path to add as a new contour
|
||||
@param matrix Transform applied to src
|
||||
@param mode Determines how path is added
|
||||
*/
|
||||
void addPath(const SkPath& src, const SkMatrix& matrix);
|
||||
void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode);
|
||||
|
||||
/**
|
||||
* Same as addPath(), but reverses the src input
|
||||
|
@ -1403,14 +1403,14 @@ void SkPath::arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy) {
|
||||
void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy, AddPathMode mode) {
|
||||
SkMatrix matrix;
|
||||
|
||||
matrix.setTranslate(dx, dy);
|
||||
this->addPath(path, matrix);
|
||||
this->addPath(path, matrix, mode);
|
||||
}
|
||||
|
||||
void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) {
|
||||
void SkPath::addPath(const SkPath& path, const SkMatrix& matrix, AddPathMode mode) {
|
||||
SkPathRef::Editor(&fPathRef, path.countVerbs(), path.countPoints());
|
||||
|
||||
RawIter iter(path);
|
||||
@ -1418,12 +1418,17 @@ void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) {
|
||||
Verb verb;
|
||||
|
||||
SkMatrix::MapPtsProc proc = matrix.getMapPtsProc();
|
||||
|
||||
bool firstVerb = true;
|
||||
while ((verb = iter.next(pts)) != kDone_Verb) {
|
||||
switch (verb) {
|
||||
case kMove_Verb:
|
||||
proc(matrix, &pts[0], &pts[0], 1);
|
||||
this->moveTo(pts[0]);
|
||||
if (firstVerb && mode == kExtend_AddPathMode && !isEmpty()) {
|
||||
injectMoveToIfNeeded(); // In case last contour is closed
|
||||
this->lineTo(pts[0]);
|
||||
} else {
|
||||
this->moveTo(pts[0]);
|
||||
}
|
||||
break;
|
||||
case kLine_Verb:
|
||||
proc(matrix, &pts[1], &pts[1], 1);
|
||||
@ -1447,6 +1452,7 @@ void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) {
|
||||
default:
|
||||
SkDEBUGFAIL("unknown verb");
|
||||
}
|
||||
firstVerb = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3060,6 +3060,68 @@ static void test_addPath(skiatest::Reporter* reporter) {
|
||||
REPORTER_ASSERT(reporter, p.getBounds() == reverseExpected);
|
||||
}
|
||||
|
||||
static void test_addPathMode(skiatest::Reporter* reporter, bool explicitMoveTo, bool extend) {
|
||||
SkPath p, q;
|
||||
if (explicitMoveTo) {
|
||||
p.moveTo(1, 1);
|
||||
}
|
||||
p.lineTo(1, 2);
|
||||
if (explicitMoveTo) {
|
||||
q.moveTo(2, 1);
|
||||
}
|
||||
q.lineTo(2, 2);
|
||||
p.addPath(q, extend ? SkPath::kExtend_AddPathMode : SkPath::kAppend_AddPathMode);
|
||||
uint8_t verbs[4];
|
||||
int verbcount = p.getVerbs(verbs, 4);
|
||||
REPORTER_ASSERT(reporter, verbcount == 4);
|
||||
REPORTER_ASSERT(reporter, verbs[0] == SkPath::kMove_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[1] == SkPath::kLine_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[2] == (extend ? SkPath::kLine_Verb : SkPath::kMove_Verb));
|
||||
REPORTER_ASSERT(reporter, verbs[3] == SkPath::kLine_Verb);
|
||||
}
|
||||
|
||||
static void test_extendClosedPath(skiatest::Reporter* reporter) {
|
||||
SkPath p, q;
|
||||
p.moveTo(1, 1);
|
||||
p.lineTo(1, 2);
|
||||
p.lineTo(2, 2);
|
||||
p.close();
|
||||
q.moveTo(2, 1);
|
||||
q.lineTo(2, 3);
|
||||
p.addPath(q, SkPath::kExtend_AddPathMode);
|
||||
uint8_t verbs[7];
|
||||
int verbcount = p.getVerbs(verbs, 7);
|
||||
REPORTER_ASSERT(reporter, verbcount == 7);
|
||||
REPORTER_ASSERT(reporter, verbs[0] == SkPath::kMove_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[1] == SkPath::kLine_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[2] == SkPath::kLine_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[3] == SkPath::kClose_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[4] == SkPath::kMove_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[5] == SkPath::kLine_Verb);
|
||||
REPORTER_ASSERT(reporter, verbs[6] == SkPath::kLine_Verb);
|
||||
|
||||
SkPoint pt;
|
||||
REPORTER_ASSERT(reporter, p.getLastPt(&pt));
|
||||
REPORTER_ASSERT(reporter, pt == SkPoint::Make(2, 3));
|
||||
REPORTER_ASSERT(reporter, p.getPoint(3) == SkPoint::Make(1, 1));
|
||||
}
|
||||
|
||||
static void test_addEmptyPath(skiatest::Reporter* reporter, SkPath::AddPathMode mode) {
|
||||
SkPath p, q, r;
|
||||
// case 1: dst is empty
|
||||
p.moveTo(2, 1);
|
||||
p.lineTo(2, 3);
|
||||
q.addPath(p, mode);
|
||||
REPORTER_ASSERT(reporter, q == p);
|
||||
// case 2: src is empty
|
||||
p.addPath(r, mode);
|
||||
REPORTER_ASSERT(reporter, q == p);
|
||||
// case 3: src and dst are empty
|
||||
q.reset();
|
||||
q.addPath(r, mode);
|
||||
REPORTER_ASSERT(reporter, q.isEmpty());
|
||||
}
|
||||
|
||||
static void test_conicTo_special_case(skiatest::Reporter* reporter) {
|
||||
SkPath p;
|
||||
p.conicTo(1, 2, 3, 4, -1);
|
||||
@ -3377,6 +3439,13 @@ DEF_TEST(Paths, reporter) {
|
||||
test_arc(reporter);
|
||||
test_arcTo(reporter);
|
||||
test_addPath(reporter);
|
||||
test_addPathMode(reporter, false, false);
|
||||
test_addPathMode(reporter, true, false);
|
||||
test_addPathMode(reporter, false, true);
|
||||
test_addPathMode(reporter, true, true);
|
||||
test_extendClosedPath(reporter);
|
||||
test_addEmptyPath(reporter, SkPath::kExtend_AddPathMode);
|
||||
test_addEmptyPath(reporter, SkPath::kAppend_AddPathMode);
|
||||
test_conicTo_special_case(reporter);
|
||||
test_get_point(reporter);
|
||||
test_contains(reporter);
|
||||
|
Loading…
Reference in New Issue
Block a user