diff options
author | schenney@chromium.org <schenney@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-13 17:05:43 +0000 |
---|---|---|
committer | schenney@chromium.org <schenney@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-13 17:05:43 +0000 |
commit | 7e963605d5b8177c30afa0d8e5541b0fbe1b6e13 (patch) | |
tree | b7fcc8a2cb6f39017a10a2e28d267ea1bc527405 /tests | |
parent | 761b37c0eb9ec84508cd36e20b81441cd09b4d8d (diff) |
Fix the problem of rendering closePath not properly after a moveTo call in
canvas 2D interface. If there is a polyline, followed by a moveTo and a
closePath, both the moveTo and the closePath should be ignored for the purposes
of drawing, and the polyline should not be closed (unless force closed is true
(for filling, for instance).
Tested for path with both valid and degenerate content, when asked to
consume degenerates and not, force closed and not.
This patch also includes a uni test refactoring to reduce the amount of code
to test path iteration and zero length paths.
BUG=6297049
TEST=tests/PathTest.cpp, testIter method.
Review URL: https://codereview.appspot.com/6300086
git-svn-id: http://skia.googlecode.com/svn/trunk@4247 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests')
-rw-r--r-- | tests/PathTest.cpp | 414 |
1 files changed, 140 insertions, 274 deletions
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index ff12e8eb53..d3e7408ac2 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -761,239 +761,72 @@ static void test_transform(skiatest::Reporter* reporter) { static void test_zero_length_paths(skiatest::Reporter* reporter) { SkPath p; - SkPoint pt; - SkRect bounds; - - // Lone moveTo case - p.moveTo(SK_Scalar1, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 1 == p.countPoints()); - p.getLastPt(&pt); - REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1); - REPORTER_ASSERT(reporter, pt.fY == SK_Scalar1); - bounds.set(0, 0, 0, 0); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[1]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - } - - // MoveTo-MoveTo case - p.moveTo(SK_Scalar1*2, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 2 == p.countPoints()); - REPORTER_ASSERT(reporter, 2 == p.countVerbs()); - p.getLastPt(&pt); - REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1*2); - REPORTER_ASSERT(reporter, pt.fY == SK_Scalar1); - bounds.set(SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[2]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[1]); - } - - // moveTo-close case - p.reset(); - p.moveTo(SK_Scalar1, SK_Scalar1); - p.close(); - bounds.set(0, 0, 0, 0); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 1 == p.countPoints()); - REPORTER_ASSERT(reporter, 2 == p.countVerbs()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[2]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[1]); - } - - // moveTo-close-moveTo-close case - p.moveTo(SK_Scalar1*2, SK_Scalar1); - p.close(); - bounds.set(SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 2 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[4]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[1]); - } - - // moveTo-line case - p.reset(); - p.moveTo(SK_Scalar1, SK_Scalar1); - p.lineTo(SK_Scalar1, SK_Scalar1); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 2 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[2]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[1]); - } - - // moveTo-lineTo-moveTo-lineTo case - p.moveTo(SK_Scalar1*2, SK_Scalar1); - p.lineTo(SK_Scalar1*2, SK_Scalar1); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 4 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[4]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[2]); - REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[3]); - } - - // moveTo-line-close case - p.reset(); - p.moveTo(SK_Scalar1, SK_Scalar1); - p.lineTo(SK_Scalar1, SK_Scalar1); - p.close(); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 2 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[3]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[2]); - } - - // moveTo-line-close-moveTo-line-close case - p.moveTo(SK_Scalar1*2, SK_Scalar1); - p.lineTo(SK_Scalar1*2, SK_Scalar1); - p.close(); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 4 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[6]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[2]); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[3]); - REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[4]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[5]); - } - - // moveTo-quadTo case - p.reset(); - p.moveTo(SK_Scalar1, SK_Scalar1); - p.quadTo(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 3 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[2]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kQuad_Verb == verbs[1]); - } - - // moveTo-quadTo-close case - p.close(); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 3 == p.countPoints()); - REPORTER_ASSERT(reporter, 3 == p.countVerbs()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[3]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kQuad_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[2]); - } - - // moveTo-quadTo-moveTo-quadTo case - p.reset(); - p.moveTo(SK_Scalar1, SK_Scalar1); - p.quadTo(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1); - p.moveTo(SK_Scalar1*2, SK_Scalar1); - p.quadTo(SK_Scalar1*2, SK_Scalar1, SK_Scalar1*2, SK_Scalar1); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 6 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[4]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kQuad_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kQuad_Verb == verbs[1]); - } - - // moveTo-cubicTo case - p.reset(); - p.moveTo(SK_Scalar1, SK_Scalar1); - p.cubicTo(SK_Scalar1, SK_Scalar1, - SK_Scalar1, SK_Scalar1, - SK_Scalar1, SK_Scalar1); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 4 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[2]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kCubic_Verb == verbs[1]); - } + uint8_t verbs[32]; + + struct zeroPathTestData { + const char* testPath; + const size_t numResultPts; + const SkRect resultBound; + const SkPath::Verb* resultVerbs; + const size_t numResultVerbs; + }; - // moveTo-cubicTo-close case - p.close(); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 4 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[3]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kCubic_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[2]); - } + static const SkPath::Verb resultVerbs1[] = { SkPath::kMove_Verb }; + static const SkPath::Verb resultVerbs2[] = { SkPath::kMove_Verb, SkPath::kMove_Verb }; + static const SkPath::Verb resultVerbs3[] = { SkPath::kMove_Verb, SkPath::kClose_Verb }; + static const SkPath::Verb resultVerbs4[] = { SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb }; + static const SkPath::Verb resultVerbs5[] = { SkPath::kMove_Verb, SkPath::kLine_Verb }; + static const SkPath::Verb resultVerbs6[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kMove_Verb, SkPath::kLine_Verb }; + static const SkPath::Verb resultVerbs7[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb }; + static const SkPath::Verb resultVerbs8[] = { + SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb + }; + static const SkPath::Verb resultVerbs9[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb }; + static const SkPath::Verb resultVerbs10[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kMove_Verb, SkPath::kQuad_Verb }; + static const SkPath::Verb resultVerbs11[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb }; + static const SkPath::Verb resultVerbs12[] = { + SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb + }; + static const SkPath::Verb resultVerbs13[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb }; + static const SkPath::Verb resultVerbs14[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kMove_Verb, SkPath::kCubic_Verb }; + static const SkPath::Verb resultVerbs15[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb }; + static const SkPath::Verb resultVerbs16[] = { + SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb + }; + static const struct zeroPathTestData gZeroLengthTests[] = { + { "M 1 1", 1, {0, 0, 0, 0}, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "M 1 1 m 1 0", 2, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs2, SK_ARRAY_COUNT(resultVerbs2) }, + { "M 1 1 z", 1, {0, 0, 0, 0}, resultVerbs3, SK_ARRAY_COUNT(resultVerbs3) }, + { "M 1 1 z m 1 0 z", 2, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs4, SK_ARRAY_COUNT(resultVerbs4) }, + { "M 1 1 l 0 0", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs5, SK_ARRAY_COUNT(resultVerbs5) }, + { "M 1 1 l 0 0 m 1 0 l 0 0", 4, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs6, SK_ARRAY_COUNT(resultVerbs6) }, + { "M 1 1 l 0 0 z", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs7, SK_ARRAY_COUNT(resultVerbs7) }, + { "M 1 1 l 0 0 z m 1 0 l 0 0 z", 4, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs8, SK_ARRAY_COUNT(resultVerbs8) }, + { "M 1 1 q 0 0 0 0", 3, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs9, SK_ARRAY_COUNT(resultVerbs9) }, + { "M 1 1 q 0 0 0 0 m 1 0 q 0 0 0 0", 6, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs10, SK_ARRAY_COUNT(resultVerbs10) }, + { "M 1 1 q 0 0 0 0 z", 3, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs11, SK_ARRAY_COUNT(resultVerbs11) }, + { "M 1 1 q 0 0 0 0 z m 1 0 q 0 0 0 0 z", 6, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs12, SK_ARRAY_COUNT(resultVerbs12) }, + { "M 1 1 c 0 0 0 0 0 0", 4, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs13, SK_ARRAY_COUNT(resultVerbs13) }, + { "M 1 1 c 0 0 0 0 0 0 m 1 0 c 0 0 0 0 0 0", 8, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs14, + SK_ARRAY_COUNT(resultVerbs14) + }, + { "M 1 1 c 0 0 0 0 0 0 z", 4, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs15, SK_ARRAY_COUNT(resultVerbs15) }, + { "M 1 1 c 0 0 0 0 0 0 z m 1 0 c 0 0 0 0 0 0 z", 8, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs16, + SK_ARRAY_COUNT(resultVerbs16) + } + }; - // moveTo-cubicTo-moveTo-cubicTo case - p.reset(); - p.moveTo(SK_Scalar1, SK_Scalar1); - p.cubicTo(SK_Scalar1, SK_Scalar1, - SK_Scalar1, SK_Scalar1, - SK_Scalar1, SK_Scalar1); - p.moveTo(SK_Scalar1*2, SK_Scalar1); - p.cubicTo(SK_Scalar1*2, SK_Scalar1, - SK_Scalar1*2, SK_Scalar1, - SK_Scalar1*2, SK_Scalar1); - bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1); - REPORTER_ASSERT(reporter, !p.isEmpty()); - REPORTER_ASSERT(reporter, 8 == p.countPoints()); - REPORTER_ASSERT(reporter, bounds == p.getBounds()); - { - uint8_t verbs[4]; - REPORTER_ASSERT(reporter, SK_ARRAY_COUNT(verbs) == p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]); - REPORTER_ASSERT(reporter, SkPath::kCubic_Verb == verbs[1]); - REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[2]); - REPORTER_ASSERT(reporter, SkPath::kCubic_Verb == verbs[3]); + for (size_t i = 0; i < SK_ARRAY_COUNT(gZeroLengthTests); ++i) { + p.reset(); + bool valid = SkParsePath::FromSVGString(gZeroLengthTests[i].testPath, &p); + REPORTER_ASSERT(reporter, valid); + REPORTER_ASSERT(reporter, !p.isEmpty()); + REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultPts == (size_t)p.countPoints()); + REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultBound == p.getBounds()); + REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultVerbs == (size_t)p.getVerbs(verbs, SK_ARRAY_COUNT(verbs))); + for (size_t j = 0; j < gZeroLengthTests[i].numResultVerbs; ++j) { + REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultVerbs[j] == verbs[j]); + } } } @@ -1021,69 +854,102 @@ static void test_segment_masks(skiatest::Reporter* reporter) { } static void test_iter(skiatest::Reporter* reporter) { - SkPath p; + SkPath p; SkPoint pts[4]; // Test an iterator with no path SkPath::Iter noPathIter; REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb); + // Test that setting an empty path works noPathIter.setPath(p, false); REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb); + // Test that close path makes no difference for an empty path noPathIter.setPath(p, true); REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb); - + // Test an iterator with an initial empty path SkPath::Iter iter(p, false); REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb); // Test that close path makes no difference - SkPath::Iter forceCloseIter(p, true); - REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb); - - // Test that a move-only path produces nothing when iterated. - p.moveTo(SK_Scalar1, 0); - iter.setPath(p, false); + iter.setPath(p, true); REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb); - // No matter how many moves we add, we should still get nothing back. - p.moveTo(SK_Scalar1*2, 0); - p.moveTo(SK_Scalar1*3, 0); - p.moveTo(SK_Scalar1*4, 0); - p.moveTo(SK_Scalar1*5, 0); - iter.setPath(p, false); - REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb); - - // Nor should force closing - forceCloseIter.setPath(p, true); - REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb); + + struct iterTestData { + const char* testPath; + const bool forceClose; + const bool consumeDegenerates; + const size_t* numResultPtsPerVerb; + const SkPoint* resultPts; + const SkPath::Verb* resultVerbs; + const size_t numResultVerbs; + }; - // Initial closes should be ignored - p.reset(); - p.close(); - iter.setPath(p, false); - REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb); - // Even if force closed - forceCloseIter.setPath(p, true); - REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb); + static const SkPath::Verb resultVerbs1[] = { SkPath::kDone_Verb }; + static const SkPath::Verb resultVerbs2[] = { + SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kDone_Verb + }; + static const SkPath::Verb resultVerbs3[] = { + SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb + }; + static const SkPath::Verb resultVerbs4[] = { + SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb + }; + static const SkPath::Verb resultVerbs5[] = { + SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb + }; + static const size_t resultPtsSizes1[] = { 0 }; + static const size_t resultPtsSizes2[] = { 1, 2, 2 }; + static const size_t resultPtsSizes3[] = { 1, 2, 2, 2, 1 }; + static const size_t resultPtsSizes4[] = { 1, 2, 1, 1 }; + static const size_t resultPtsSizes5[] = { 1, 2, 1, 1, 1 }; + static const SkPoint resultPts1[] = { }; + static const SkPoint resultPts2[] = { + { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, SK_Scalar1 }, { SK_Scalar1, SK_Scalar1 }, { 0, SK_Scalar1 } + }; + static const SkPoint resultPts3[] = { + { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, SK_Scalar1 }, { SK_Scalar1, SK_Scalar1 }, { 0, SK_Scalar1 }, + { 0, SK_Scalar1 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 } + }; + static const SkPoint resultPts4[] = { + { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 } + }; + static const SkPoint resultPts5[] = { + { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 } + }; + static const struct iterTestData gIterTests[] = { + { "M 1 0", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "M 1 0 m 1 0 m 1 0 m 1 0 m 1 0", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "M 1 0 m 1 0 m 1 0 m 1 0 m 1 0", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "z M 1 0 z z M 2 0 z M 3 0 M 4 0 z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "z M 1 0 z z M 2 0 z M 3 0 M 4 0 z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "M 1 0 l 0 1 L 0 1 M 0 0 z", false, true, resultPtsSizes2, resultPts2, resultVerbs2, SK_ARRAY_COUNT(resultVerbs2) }, + { "M 1 0 l 0 1 L 0 1 M 0 0 z", true, true, resultPtsSizes3, resultPts3, resultVerbs3, SK_ARRAY_COUNT(resultVerbs3) }, + { "M 1 0 l 0 0 M 0 0 z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "M 1 0 l 0 0 M 0 0 z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) }, + { "M 1 0 l 0 0 M 0 0 z", false, false, resultPtsSizes4, resultPts4, resultVerbs4, SK_ARRAY_COUNT(resultVerbs4) }, + { "M 1 0 l 0 0 M 0 0 z", true, false, resultPtsSizes5, resultPts5, resultVerbs5, SK_ARRAY_COUNT(resultVerbs5) } + }; - // Move/close sequences should also be ignored - p.reset(); - p.close(); - p.moveTo(SK_Scalar1, 0); - p.close(); - p.close(); - p.moveTo(SK_Scalar1*2, 0); - p.close(); - p.moveTo(SK_Scalar1*3, 0); - p.moveTo(SK_Scalar1*4, 0); - p.close(); - iter.setPath(p, false); - REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb); - // Even if force closed - forceCloseIter.setPath(p, true); - REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb); + for (size_t i = 0; i < SK_ARRAY_COUNT(gIterTests); ++i) { + p.reset(); + bool valid = SkParsePath::FromSVGString(gIterTests[i].testPath, &p); + REPORTER_ASSERT(reporter, valid); + iter.setPath(p, gIterTests[i].forceClose); + int j = 0, l = 0; + do { + REPORTER_ASSERT(reporter, iter.next(pts, gIterTests[i].consumeDegenerates) == gIterTests[i].resultVerbs[j]); + for (int k = 0; k < (int)gIterTests[i].numResultPtsPerVerb[j]; ++k) { + REPORTER_ASSERT(reporter, pts[k] == gIterTests[i].resultPts[l++]); + } + } while (gIterTests[i].resultVerbs[j++] != SkPath::kDone_Verb); + REPORTER_ASSERT(reporter, j == (int)gIterTests[i].numResultVerbs); + } // The GM degeneratesegments.cpp test is more extensive } |