11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
8da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "Test.h"
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkPaint.h"
10da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "SkPath.h"
1135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#include "SkParse.h"
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkParsePath.h"
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkRandom.h"
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkReader32.h"
156b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed#include "SkSize.h"
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkWriter32.h"
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/**
194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * cheapIsDirection can take a shortcut when a path is marked convex.
204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * This function ensures that we always test cheapIsDirection when the path
214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * is flagged with unknown convexity status.
224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */
234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void check_direction(SkPath* path,
244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                            SkPath::Direction expectedDir,
254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                            skiatest::Reporter* reporter) {
264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (SkPath::kConvex_Convexity == path->getConvexity()) {
274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        REPORTER_ASSERT(reporter, path->cheapIsDirection(expectedDir));
284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        path->setConvexity(SkPath::kUnknown_Convexity);
294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    REPORTER_ASSERT(reporter, path->cheapIsDirection(expectedDir));
314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_direction(skiatest::Reporter* reporter) {
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t i;
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath path;
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !path.cheapComputeDirection(NULL));
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCW_Direction));
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCCW_Direction));
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const char* gDegen[] = {
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10",
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 M 20 20",
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 L 20 20",
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 L 10 10 L 10 10",
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 Q 10 10 10 10",
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 C 10 10 10 10 10 10",
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (i = 0; i < SK_ARRAY_COUNT(gDegen); ++i) {
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.reset();
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool valid = SkParsePath::FromSVGString(gDegen[i], &path);
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, valid);
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, !path.cheapComputeDirection(NULL));
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const char* gCW[] = {
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 L 10 10 Q 20 10 20 20",
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 C 20 10 20 20 20 20",
584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        "M 20 10 Q 20 20 30 20 L 10 20", // test double-back at y-max
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (i = 0; i < SK_ARRAY_COUNT(gCW); ++i) {
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.reset();
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool valid = SkParsePath::FromSVGString(gCW[i], &path);
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, valid);
644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        check_direction(&path, SkPath::kCW_Direction, reporter);
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const char* gCCW[] = {
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 L 10 10 Q 20 10 20 -20",
691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        "M 10 10 C 20 10 20 -20 20 -20",
704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        "M 20 10 Q 20 20 10 20 L 30 20", // test double-back at y-max
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (i = 0; i < SK_ARRAY_COUNT(gCCW); ++i) {
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.reset();
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool valid = SkParsePath::FromSVGString(gCCW[i], &path);
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, valid);
764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        check_direction(&path, SkPath::kCCW_Direction, reporter);
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // Test two donuts, each wound a different direction. Only the outer contour
804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // determines the cheap direction
814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.reset();
824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCW_Direction);
834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCCW_Direction);
844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    check_direction(&path, SkPath::kCW_Direction, reporter);
854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.reset();
874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCW_Direction);
884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCCW_Direction);
894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    check_direction(&path, SkPath::kCCW_Direction, reporter);
904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_SCALAR_IS_FLOAT
924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // triangle with one point really far from the origin.
934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.reset();
944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // the first point is roughly 1.05e10, 1.05e10
954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.moveTo(SkFloatToScalar(SkBits2Float(0x501c7652)), SkFloatToScalar(SkBits2Float(0x501c7652)));
964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.lineTo(110 * SK_Scalar1, -10 * SK_Scalar1);
974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    path.lineTo(-10 * SK_Scalar1, 60 * SK_Scalar1);
984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    check_direction(&path, SkPath::kCCW_Direction, reporter);
994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void add_rect(SkPath* path, const SkRect& r) {
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path->moveTo(r.fLeft, r.fTop);
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path->lineTo(r.fRight, r.fTop);
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path->lineTo(r.fRight, r.fBottom);
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path->lineTo(r.fLeft, r.fBottom);
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path->close();
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_bounds(skiatest::Reporter* reporter) {
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const SkRect rects[] = {
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(160) },
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(610), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(199) },
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(10), SkIntToScalar(198), SkIntToScalar(610), SkIntToScalar(199) },
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(10), SkIntToScalar(199) },
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath path0, path1;
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (size_t i = 0; i < SK_ARRAY_COUNT(rects); ++i) {
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path0.addRect(rects[i]);
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        add_rect(&path1, rects[i]);
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, path0.getBounds() == path1.getBounds());
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void stroke_cubic(const SkPoint pts[4]) {
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath path;
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path.moveTo(pts[0]);
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path.cubicTo(pts[1], pts[2], pts[3]);
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPaint paint;
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setStyle(SkPaint::kStroke_Style);
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setStrokeWidth(SK_Scalar1 * 2);
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath fill;
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.getFillPath(path, &fill);
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// just ensure this can run w/o any SkASSERTS firing in the debug build
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// we used to assert due to differences in how we determine a degenerate vector
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// but that was fixed with the introduction of SkPoint::CanNormalize
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void stroke_tiny_cubic() {
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint p0[] = {
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 372.0f,   92.0f },
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 372.0f,   92.0f },
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 372.0f,   92.0f },
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 372.0f,   92.0f },
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    stroke_cubic(p0);
1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint p1[] = {
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 372.0f,       92.0f },
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 372.0007f,    92.000755f },
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 371.99927f,   92.003922f },
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 371.99826f,   92.003899f },
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    stroke_cubic(p1);
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void check_close(skiatest::Reporter* reporter, const SkPath& path) {
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 2; ++i) {
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPath::Iter iter(path, (bool)i);
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint mv;
1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint pts[4];
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPath::Verb v;
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int nMT = 0;
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int nCL = 0;
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        mv.set(0, 0);
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        while (SkPath::kDone_Verb != (v = iter.next(pts))) {
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            switch (v) {
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kMove_Verb:
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    mv = pts[0];
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    ++nMT;
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kClose_Verb:
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, mv == pts[0]);
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    ++nCL;
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                default:
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // if we force a close on the interator we should have a close
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // for every moveTo
1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, !i || nMT == nCL);
1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_close(skiatest::Reporter* reporter) {
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath closePt;
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    closePt.moveTo(0, 0);
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    closePt.close();
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, closePt);
1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath openPt;
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    openPt.moveTo(0, 0);
2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, openPt);
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath empty;
2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, empty);
2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    empty.close();
2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, empty);
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath rect;
2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, rect);
2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect.close();
2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, rect);
2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath quad;
2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    quad.quadTo(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, quad);
2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    quad.close();
2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, quad);
2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath cubic;
2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    quad.cubicTo(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1,
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 10*SK_Scalar1, 20 * SK_Scalar1, 20*SK_Scalar1);
2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, cubic);
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    cubic.close();
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, cubic);
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath line;
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    line.moveTo(SK_Scalar1, SK_Scalar1);
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    line.lineTo(10 * SK_Scalar1, 10*SK_Scalar1);
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, line);
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    line.close();
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, line);
2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath rect2;
2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect2.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect2.close();
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect2.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, rect2);
2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect2.close();
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, rect2);
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath oval3;
2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    oval3.addOval(SkRect::MakeWH(SK_Scalar1*100,SK_Scalar1*100));
2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    oval3.close();
2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    oval3.addOval(SkRect::MakeWH(SK_Scalar1*200,SK_Scalar1*200));
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, oval3);
2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    oval3.close();
2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, oval3);
2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath moves;
2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    moves.moveTo(SK_Scalar1, SK_Scalar1);
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    moves.moveTo(5 * SK_Scalar1, SK_Scalar1);
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    moves.moveTo(SK_Scalar1, 10 * SK_Scalar1);
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    moves.moveTo(10 *SK_Scalar1, SK_Scalar1);
2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    check_close(reporter, moves);
2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    stroke_tiny_cubic();
2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
258da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
25935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerstatic void check_convexity(skiatest::Reporter* reporter, const SkPath& path,
26035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                            SkPath::Convexity expected) {
26135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath::Convexity c = SkPath::ComputeConvexity(path);
26235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    REPORTER_ASSERT(reporter, c == expected);
26335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger}
26435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
26535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerstatic void test_convexity2(skiatest::Reporter* reporter) {
26635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath pt;
26735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    pt.moveTo(0, 0);
26835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    pt.close();
2690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    check_convexity(reporter, pt, SkPath::kConvex_Convexity);
27035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
27135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath line;
2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    line.moveTo(12*SK_Scalar1, 20*SK_Scalar1);
2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    line.lineTo(-12*SK_Scalar1, -20*SK_Scalar1);
27435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    line.close();
2750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    check_convexity(reporter, pt, SkPath::kConvex_Convexity);
27635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
27735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath triLeft;
27835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    triLeft.moveTo(0, 0);
2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    triLeft.lineTo(SK_Scalar1, 0);
2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    triLeft.lineTo(SK_Scalar1, SK_Scalar1);
28135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    triLeft.close();
28235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    check_convexity(reporter, triLeft, SkPath::kConvex_Convexity);
28335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
28435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath triRight;
28535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    triRight.moveTo(0, 0);
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    triRight.lineTo(-SK_Scalar1, 0);
2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    triRight.lineTo(SK_Scalar1, SK_Scalar1);
28835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    triRight.close();
28935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    check_convexity(reporter, triRight, SkPath::kConvex_Convexity);
29035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
29135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath square;
29235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    square.moveTo(0, 0);
2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    square.lineTo(SK_Scalar1, 0);
2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    square.lineTo(SK_Scalar1, SK_Scalar1);
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    square.lineTo(0, SK_Scalar1);
29635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    square.close();
29735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    check_convexity(reporter, square, SkPath::kConvex_Convexity);
29835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
29935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath redundantSquare;
30035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    redundantSquare.moveTo(0, 0);
30135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    redundantSquare.lineTo(0, 0);
30235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    redundantSquare.lineTo(0, 0);
3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(SK_Scalar1, 0);
3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(SK_Scalar1, 0);
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(SK_Scalar1, 0);
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(0, SK_Scalar1);
3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(0, SK_Scalar1);
3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    redundantSquare.lineTo(0, SK_Scalar1);
31235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    redundantSquare.close();
31335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    check_convexity(reporter, redundantSquare, SkPath::kConvex_Convexity);
31435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
31535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath bowTie;
31635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    bowTie.moveTo(0, 0);
31735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    bowTie.lineTo(0, 0);
31835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    bowTie.lineTo(0, 0);
3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(SK_Scalar1, 0);
3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(SK_Scalar1, 0);
3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(SK_Scalar1, 0);
3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(0, SK_Scalar1);
3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(0, SK_Scalar1);
3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bowTie.lineTo(0, SK_Scalar1);
32835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    bowTie.close();
32935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    check_convexity(reporter, bowTie, SkPath::kConcave_Convexity);
33035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
33135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath spiral;
33235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    spiral.moveTo(0, 0);
3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    spiral.lineTo(100*SK_Scalar1, 0);
3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    spiral.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    spiral.lineTo(0, 100*SK_Scalar1);
3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    spiral.lineTo(0, 50*SK_Scalar1);
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    spiral.lineTo(50*SK_Scalar1, 50*SK_Scalar1);
3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    spiral.lineTo(50*SK_Scalar1, 75*SK_Scalar1);
33935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    spiral.close();
34035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    check_convexity(reporter, spiral, SkPath::kConcave_Convexity);
34135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
34235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath dent;
3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    dent.moveTo(0, 0);
3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    dent.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    dent.lineTo(0, 100*SK_Scalar1);
3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    dent.lineTo(-50*SK_Scalar1, 200*SK_Scalar1);
3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    dent.lineTo(-200*SK_Scalar1, 100*SK_Scalar1);
34835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    dent.close();
34935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    check_convexity(reporter, dent, SkPath::kConcave_Convexity);
35035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger}
35135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
35279377cbceeea970b663e7934d7cb1f27bb223d98Mike Reedstatic void check_convex_bounds(skiatest::Reporter* reporter, const SkPath& p,
35379377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed                                const SkRect& bounds) {
35479377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    REPORTER_ASSERT(reporter, p.isConvex());
35579377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    REPORTER_ASSERT(reporter, p.getBounds() == bounds);
35605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
35779377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    SkPath p2(p);
35879377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    REPORTER_ASSERT(reporter, p2.isConvex());
35979377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    REPORTER_ASSERT(reporter, p2.getBounds() == bounds);
36079377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed
36179377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    SkPath other;
36279377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    other.swap(p2);
36379377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    REPORTER_ASSERT(reporter, other.isConvex());
36479377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    REPORTER_ASSERT(reporter, other.getBounds() == bounds);
36579377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed}
36679377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed
36735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerstatic void setFromString(SkPath* path, const char str[]) {
36835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    bool first = true;
36935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    while (str) {
37035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkScalar x, y;
37135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        str = SkParse::FindScalar(str, &x);
37235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (NULL == str) {
37335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            break;
37435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
37535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        str = SkParse::FindScalar(str, &y);
37635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkASSERT(str);
37735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (first) {
37835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            path->moveTo(x, y);
37935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            first = false;
38035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        } else {
38135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            path->lineTo(x, y);
38235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
38335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
38435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger}
38535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
38635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerstatic void test_convexity(skiatest::Reporter* reporter) {
38735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static const SkPath::Convexity C = SkPath::kConcave_Convexity;
38835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static const SkPath::Convexity V = SkPath::kConvex_Convexity;
38935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
39035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPath path;
39135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
3920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path.addCircle(0, 0, SkIntToScalar(10));
39435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path.addCircle(0, 0, SkIntToScalar(10));   // 2nd circle
39635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    REPORTER_ASSERT(reporter, C == SkPath::ComputeConvexity(path));
39735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    path.reset();
3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPath::kCCW_Direction);
39935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCCW_Direction));
40135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    path.reset();
4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPath::kCW_Direction);
40335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCW_Direction));
40535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
40635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static const struct {
40735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        const char*         fPathStr;
40835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkPath::Convexity   fExpectedConvexity;
40935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    } gRec[] = {
4100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        { "", SkPath::kConvex_Convexity },
4110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        { "0 0", SkPath::kConvex_Convexity },
4120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        { "0 0 10 10", SkPath::kConvex_Convexity },
41335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        { "0 0 10 10 20 20 0 0 10 10", SkPath::kConcave_Convexity },
41435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        { "0 0 10 10 10 20", SkPath::kConvex_Convexity },
41535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        { "0 0 10 10 10 0", SkPath::kConvex_Convexity },
41635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        { "0 0 10 10 10 0 0 10", SkPath::kConcave_Convexity },
41735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        { "0 0 10 0 0 10 -10 -10", SkPath::kConcave_Convexity },
41835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    };
41935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
42035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
42135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkPath path;
42235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        setFromString(&path, gRec[i].fPathStr);
42335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkPath::Convexity c = SkPath::ComputeConvexity(path);
42435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        REPORTER_ASSERT(reporter, c == gRec[i].fExpectedConvexity);
42535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
42635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger}
42735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Simple isRect test is inline TestPath, below.
4291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// test_isRect provides more extensive testing.
4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_isRect(skiatest::Reporter* reporter) {
4311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // passing tests (all moveTo / lineTo...
4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
4351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
4361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
4381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f},
4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {1, 0}, {.5f, 0}};
4431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1},
4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {0, 1}, {0, .5f}};
4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};
4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}};
4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // failing tests
4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}}; // too few points
4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}}; // diagonal
4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}}; // wraps
4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}}; // backs up
4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}}; // end overshoots
4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}}; // end overshoots
4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}}; // end overshoots
4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}}; // 'L'
4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // failing, no close
4601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; // close doesn't match
4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}}; // ditto
4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t testLen[] = {
4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sizeof(r1), sizeof(r2), sizeof(r3), sizeof(r4), sizeof(r5), sizeof(r6),
4651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sizeof(r7), sizeof(r8), sizeof(r9), sizeof(ra), sizeof(rb), sizeof(rc),
4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sizeof(rd), sizeof(re),
4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sizeof(f1), sizeof(f2), sizeof(f3), sizeof(f4), sizeof(f5), sizeof(f6),
4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sizeof(f7), sizeof(f8),
4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        sizeof(c1), sizeof(c2)
4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint* tests[] = {
4721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re,
4731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        f1, f2, f3, f4, f5, f6, f7, f8,
4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        c1, c2
4751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint* lastPass = re;
4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint* lastClose = f8;
4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool fail = false;
4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool close = true;
4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const size_t testCount = sizeof(tests) / sizeof(tests[0]);
4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t index;
4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (size_t testIndex = 0; testIndex < testCount; ++testIndex) {
4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPath path;
4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path.moveTo(tests[testIndex][0].fX, tests[testIndex][0].fY);
4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (index = 1; index < testLen[testIndex] / sizeof(SkPoint); ++index) {
4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            path.lineTo(tests[testIndex][index].fX, tests[testIndex][index].fY);
4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (close) {
4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            path.close();
4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, fail ^ path.isRect(0));
4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (tests[testIndex] == lastPass) {
4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fail = true;
4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (tests[testIndex] == lastClose) {
4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            close = false;
4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // fail, close then line
5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath path1;
5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.moveTo(r1[0].fX, r1[0].fY);
5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path1.lineTo(r1[index].fX, r1[index].fY);
5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.close();
5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.lineTo(1, 0);
5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // fail, move in the middle
5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.reset();
5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.moveTo(r1[0].fX, r1[0].fY);
5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (index == 2) {
5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            path1.moveTo(1, .5f);
5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path1.lineTo(r1[index].fX, r1[index].fY);
5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.close();
5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // fail, move on the edge
5231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.reset();
5241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path1.moveTo(r1[index - 1].fX, r1[index - 1].fY);
5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path1.lineTo(r1[index].fX, r1[index].fY);
5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.close();
5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // fail, quad
5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.reset();
5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.moveTo(r1[0].fX, r1[0].fY);
5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (index == 2) {
5361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            path1.quadTo(1, .5f, 1, .5f);
5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path1.lineTo(r1[index].fX, r1[index].fY);
5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.close();
5411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // fail, cubic
5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.reset();
5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.moveTo(r1[0].fX, r1[0].fY);
5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (index == 2) {
5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            path1.cubicTo(1, .5f, 1, .5f, 1, .5f);
5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        path1.lineTo(r1[index].fX, r1[index].fY);
5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    path1.close();
5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_flattening(skiatest::Reporter* reporter) {
5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath p;
5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const SkPoint pts[] = {
5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 0, 0 },
5611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(10), SkIntToScalar(10) },
5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 },
5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }
5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(pts[0]);
5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.lineTo(pts[1]);
5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.quadTo(pts[2], pts[3]);
5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.cubicTo(pts[4], pts[5], pts[6]);
5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkWriter32 writer(100);
5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.flatten(writer);
5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t size = writer.size();
5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoMalloc storage(size);
5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    writer.flatten(storage.get());
5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkReader32 reader(storage.get(), size);
5761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath p1;
5781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, p1 != p);
5791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p1.unflatten(reader);
5801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, p1 == p);
5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_transform(skiatest::Reporter* reporter) {
5841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath p, p1;
5851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const SkPoint pts[] = {
5871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 0, 0 },
5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(10), SkIntToScalar(10) },
5891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 },
5901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }
5911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
5921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(pts[0]);
5931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.lineTo(pts[1]);
5941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.quadTo(pts[2], pts[3]);
5951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.cubicTo(pts[4], pts[5], pts[6]);
5961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkMatrix matrix;
5981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    matrix.reset();
5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.transform(matrix, &p1);
6001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, p == p1);
6011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    matrix.setScale(SK_Scalar1 * 2, SK_Scalar1 * 3);
6031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.transform(matrix, &p1);
6041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint pts1[7];
6051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int count = p1.getPoints(pts1, 7);
6061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 7 == count);
6071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < count; ++i) {
6081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint newPt = SkPoint::Make(pts[i].fX * 2, pts[i].fY * 3);
6091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, newPt == pts1[i]);
6101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_zero_length_paths(skiatest::Reporter* reporter) {
6141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath  p;
6151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint pt;
6161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect  bounds;
6171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Lone moveTo case
6191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
6201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 1 == p.countPoints());
6221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.getLastPt(&pt);
6231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1);
6241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pt.fY == SK_Scalar1);
6251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(0, 0, 0, 0);
6261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // MoveTo-MoveTo case
6291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
6301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 2 == p.countPoints());
6321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.getLastPt(&pt);
6331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1*2);
6341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pt.fY == SK_Scalar1);
6351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1);
6361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-close case
6391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
6401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
6411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
6421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(0, 0, 0, 0);
6431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 1 == p.countPoints());
6451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-close-moveTo-close case
6481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
6491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
6501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1);
6511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 2 == p.countPoints());
6531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-line case
6561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
6571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
6581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.lineTo(SK_Scalar1, SK_Scalar1);
6591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1);
6601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 2 == p.countPoints());
6621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-lineTo-moveTo-lineTo case
6651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
6661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.lineTo(SK_Scalar1*2, SK_Scalar1);
6671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1);
6681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 4 == p.countPoints());
6701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-line-close case
6731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
6741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
6751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.lineTo(SK_Scalar1, SK_Scalar1);
6761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
6771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1);
6781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 2 == p.countPoints());
6801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-line-close-moveTo-line-close case
6831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
6841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.lineTo(SK_Scalar1*2, SK_Scalar1);
6851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
6861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1);
6871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 4 == p.countPoints());
6891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-quadTo case
6921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
6931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
6941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.quadTo(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1);
6951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1);
6961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
6971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 3 == p.countPoints());
6981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
6991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-quadTo-close case
7011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
7021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 3 == p.countPoints());
7041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
7051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-quadTo-moveTo-quadTo case
7071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
7081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
7091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.quadTo(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1);
7101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
7111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.quadTo(SK_Scalar1*2, SK_Scalar1, SK_Scalar1*2, SK_Scalar1);
7121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1);
7131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 6 == p.countPoints());
7151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
7161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-cubicTo case
7181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
7191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
7201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.cubicTo(SK_Scalar1, SK_Scalar1,
7211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              SK_Scalar1, SK_Scalar1,
7221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              SK_Scalar1, SK_Scalar1);
7231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1);
7241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 4 == p.countPoints());
7261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
7271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-quadTo-close case
7291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
7301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 4 == p.countPoints());
7321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
7331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // moveTo-quadTo-moveTo-quadTo case
7351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
7361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, SK_Scalar1);
7371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.cubicTo(SK_Scalar1, SK_Scalar1,
7381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              SK_Scalar1, SK_Scalar1,
7391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              SK_Scalar1, SK_Scalar1);
7401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
7411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.cubicTo(SK_Scalar1*2, SK_Scalar1,
7421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              SK_Scalar1*2, SK_Scalar1,
7431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              SK_Scalar1*2, SK_Scalar1);
7441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(SK_Scalar1, SK_Scalar1, SK_Scalar1*2, SK_Scalar1);
7451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 8 == p.countPoints());
7471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, bounds == p.getBounds());
7481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstruct SegmentInfo {
7511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath fPath;
7521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int    fPointCount;
7531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
7541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define kCurveSegmentMask   (SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask)
7561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_segment_masks(skiatest::Reporter* reporter) {
7581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath p;
7591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(0, 0);
7601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.quadTo(100, 100, 200, 200);
7611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, SkPath::kQuad_SegmentMask == p.getSegmentMasks());
7621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.cubicTo(100, 100, 200, 200, 300, 300);
7641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, kCurveSegmentMask == p.getSegmentMasks());
7651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
7671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(0, 0);
7681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.cubicTo(100, 100, 200, 200, 300, 300);
7691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, SkPath::kCubic_SegmentMask == p.getSegmentMasks());
7701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
7711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_iter(skiatest::Reporter* reporter) {
7741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath p;
7751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint pts[4];
7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test an iterator with no path
7781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath::Iter noPathIter;
7791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
7801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test that setting an empty path works
7811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    noPathIter.setPath(p, false);
7821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
7831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test that close path makes no difference for an empty path
7841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    noPathIter.setPath(p, true);
7851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
7861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test an iterator with an initial empty path
7881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath::Iter iter(p, false);
7891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
7901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test that close path makes no difference
7921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath::Iter forceCloseIter(p, true);
7931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb);
7941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test that a move-only path produces nothing when iterated.
7961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, 0);
7971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p, false);
7981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
7991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // No matter how many moves we add, we should still get nothing back.
8011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, 0);
8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*3, 0);
8031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*4, 0);
8041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*5, 0);
8051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p, false);
8061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
8071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Nor should force closing
8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    forceCloseIter.setPath(p, true);
8101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb);
8111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Initial closes should be ignored
8131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p, false);
8161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
8171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Even if force closed
8181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    forceCloseIter.setPath(p, true);
8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb);
8201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Move/close sequences should also be ignored
8221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
8231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, 0);
8251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, 0);
8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*3, 0);
8301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*4, 0);
8311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p, false);
8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Even if force closed
8351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    forceCloseIter.setPath(p, true);
8361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, forceCloseIter.next(pts) == SkPath::kDone_Verb);
8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // The GM degeneratesegments.cpp test is more extensive
8391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
8401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_raw_iter(skiatest::Reporter* reporter) {
8421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath p;
8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint pts[4];
8441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test an iterator with no path
8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath::RawIter noPathIter;
8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
8481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test that setting an empty path works
8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    noPathIter.setPath(p);
8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test an iterator with an initial empty path
8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath::RawIter iter(p);
8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Test that a move-only path returns the move.
8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, 0);
8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p);
8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == 0);
8621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // No matter how many moves we add, we should get them all back
8651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
8661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*3, SK_Scalar1*2);
8671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p);
8681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
8691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
8701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == 0);
8711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
8721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
8731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
8741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
8751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
8761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
8771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
8781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Initial close is never ever stored
8801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p);
8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Move/close sequences
8861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.reset();
8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close(); // Not stored, no purpose
8881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1, 0);
8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close(); // Not stored, no purpose
8911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*2, SK_Scalar1);
8921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*3, SK_Scalar1*2);
8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.moveTo(SK_Scalar1*4, SK_Scalar1*3);
8951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    p.close();
8961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    iter.setPath(p);
8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
8981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
8991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == 0);
9001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
9011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
9021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == 0);
9031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
9041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
9051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
9061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
9071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
9081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
9091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
9101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
9121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
9131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*4);
9141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*3);
9151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
9161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*4);
9171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*3);
9181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
9191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Generate random paths and verify
9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint randomPts[25];
9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 5; ++i) {
9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int j = 0; j < 5; ++j) {
9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            randomPts[i*5+j].set(SK_Scalar1*i, SK_Scalar1*j);
9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
9261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Max of 10 segments, max 3 points per segment
9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRandom rand(9876543);
9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint          expectedPts[31]; // May have leading moveTo
9314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkPath::Verb     expectedVerbs[22]; // May have leading moveTo
9321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath::Verb     nextVerb;
9334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
9341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 500; ++i) {
9351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        p.reset();
9361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool lastWasClose = true;
9371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool haveMoveTo = false;
9384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        SkPoint lastMoveToPt = { 0, 0 };
9391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int numPoints = 0;
9401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int numVerbs = (rand.nextU() >> 16) % 10;
9411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int numIterVerbs = 0;
9421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int j = 0; j < numVerbs; ++j) {
9431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            do {
9441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                nextVerb = static_cast<SkPath::Verb>((rand.nextU() >> 16) % SkPath::kDone_Verb);
9451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } while (lastWasClose && nextVerb == SkPath::kClose_Verb);
9461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int numRequiredPts;
9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            switch (nextVerb) {
9481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kMove_Verb:
9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
9501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    p.moveTo(expectedPts[numPoints]);
9514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    lastMoveToPt = expectedPts[numPoints];
9521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numPoints += 1;
9531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastWasClose = false;
9541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    haveMoveTo = true;
9551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
9561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kLine_Verb:
9571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    if (!haveMoveTo) {
9584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                        expectedPts[numPoints++] = lastMoveToPt;
9591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
9601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        haveMoveTo = true;
9611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    }
9621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
9631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    p.lineTo(expectedPts[numPoints]);
9641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numPoints += 1;
9651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastWasClose = false;
9661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
9671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kQuad_Verb:
9681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    if (!haveMoveTo) {
9694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                        expectedPts[numPoints++] = lastMoveToPt;
9701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
9711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        haveMoveTo = true;
9721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    }
9731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
9741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
9751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    p.quadTo(expectedPts[numPoints], expectedPts[numPoints + 1]);
9761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numPoints += 2;
9771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastWasClose = false;
9781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
9791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kCubic_Verb:
9801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    if (!haveMoveTo) {
9814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                        expectedPts[numPoints++] = lastMoveToPt;
9821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
9831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        haveMoveTo = true;
9841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    }
9851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
9861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
9871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    expectedPts[numPoints + 2] = randomPts[(rand.nextU() >> 16) % 25];
9881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    p.cubicTo(expectedPts[numPoints], expectedPts[numPoints + 1],
9891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              expectedPts[numPoints + 2]);
9901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numPoints += 3;
9911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastWasClose = false;
9921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
9931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kClose_Verb:
9941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    p.close();
9954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                    haveMoveTo = false;
9961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastWasClose = true;
9971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
9981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                default:;
9991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
10001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            expectedVerbs[numIterVerbs++] = nextVerb;
10011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
10021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        iter.setPath(p);
10041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        numVerbs = numIterVerbs;
10051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        numIterVerbs = 0;
10061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int numIterPts = 0;
10071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint lastMoveTo;
10081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPoint lastPt;
10091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        lastMoveTo.set(0, 0);
10101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        lastPt.set(0, 0);
10111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        while ((nextVerb = iter.next(pts)) != SkPath::kDone_Verb) {
10121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            REPORTER_ASSERT(reporter, nextVerb == expectedVerbs[numIterVerbs]);
10131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            numIterVerbs++;
10141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            switch (nextVerb) {
10151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kMove_Verb:
10161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, numIterPts < numPoints);
10171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[0] == expectedPts[numIterPts]);
10181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastPt = lastMoveTo = pts[0];
10191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numIterPts += 1;
10201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kLine_Verb:
10221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 1);
10231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
10241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
10251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastPt = pts[1];
10261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numIterPts += 1;
10271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kQuad_Verb:
10291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 2);
10301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
10311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
10321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
10331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastPt = pts[2];
10341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numIterPts += 2;
10351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kCubic_Verb:
10371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 3);
10381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
10391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
10401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[3] == expectedPts[numIterPts + 2]);
10421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastPt = pts[3];
10431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    numIterPts += 3;
10441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                case SkPath::kClose_Verb:
10461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    REPORTER_ASSERT(reporter, pts[0] == lastMoveTo);
10471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    lastPt = lastMoveTo;
10481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    break;
10491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                default:;
10501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
10511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
10521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, numIterPts == numPoints);
10531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        REPORTER_ASSERT(reporter, numIterVerbs == numVerbs);
10541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
10561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
105735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid TestPath(skiatest::Reporter* reporter);
105835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid TestPath(skiatest::Reporter* reporter) {
10596b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed    {
10606b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed        SkSize size;
10616b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed        size.fWidth = 3.4f;
10626b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed        size.width();
10636b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed        size = SkSize::Make(3,4);
10646b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed        SkISize isize = SkISize::Make(3,4);
10656b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed    }
10666b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed
10676b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed    SkTSize<SkScalar>::Make(3,4);
10686b79d6ada02fb549f79a1f7ca5efa222be37dee5Mike Reed
1069da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    SkPath  p, p2;
1070da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    SkRect  bounds, bounds2;
1071da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1072da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p.isEmpty());
10731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 0 == p.countPoints());
10741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
10750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    REPORTER_ASSERT(reporter, p.isConvex());
1076da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType);
1077da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, !p.isInverseFillType());
1078da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p == p2);
1079da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, !(p != p2));
1080da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1081da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p.getBounds().isEmpty());
1082da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1083da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    bounds.set(0, 0, SK_Scalar1, SK_Scalar1);
108479377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed
108579377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1);
108679377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    check_convex_bounds(reporter, p, bounds);
10871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we have quads or cubics
10881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, p.getSegmentMasks() & kCurveSegmentMask);
10891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
109005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
109179377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    p.reset();
10921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
10931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, p.isEmpty());
10941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
109579377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    p.addOval(bounds);
109679377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    check_convex_bounds(reporter, p, bounds);
10971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
109805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
109979377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    p.reset();
1100da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    p.addRect(bounds);
110179377cbceeea970b663e7934d7cb1f27bb223d98Mike Reed    check_convex_bounds(reporter, p, bounds);
11021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we have only lines
11031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, SkPath::kLine_SegmentMask == p.getSegmentMasks());
11041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !p.isEmpty());
1105da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1106da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p != p2);
1107da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, !(p == p2));
1108da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1109da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    // does getPoints return the right result
1110da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p.getPoints(NULL, 5) == 4);
1111da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    SkPoint pts[4];
1112da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    int count = p.getPoints(pts, 4);
1113da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, count == 4);
1114da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    bounds2.set(pts, 4);
1115da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, bounds == bounds2);
1116da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1117da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    bounds.offset(SK_Scalar1*3, SK_Scalar1*4);
1118da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    p.offset(SK_Scalar1*3, SK_Scalar1*4);
1119da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, bounds == p.getBounds());
1120da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1121da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p.isRect(NULL));
11221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds2.setEmpty();
1123da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, p.isRect(&bounds2));
1124da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, bounds == bounds2);
1125da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1126da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    // now force p to not be a rect
1127da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    bounds.set(0, 0, SK_Scalar1/2, SK_Scalar1/2);
1128da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    p.addRect(bounds);
1129da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed    REPORTER_ASSERT(reporter, !p.isRect(NULL));
11301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_isRect(reporter);
113105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_zero_length_paths(reporter);
11331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_direction(reporter);
113435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    test_convexity(reporter);
113535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    test_convexity2(reporter);
11361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_close(reporter);
11371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_segment_masks(reporter);
11381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_flattening(reporter);
11391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_transform(reporter);
11401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_bounds(reporter);
11411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_iter(reporter);
11421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_raw_iter(reporter);
1143da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed}
1144da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed
1145da3b8b285a5e3e6f344461d67e3370b27701756dMike Reed#include "TestClassDef.h"
1146da3b8b285a5e3e6f344461d67e3370b27701756dMike ReedDEFINE_TESTCLASS("Path", PathTestClass, TestPath)
1147