PathTest.cpp revision f68154a3cf43eb22d45be11f3b09e25440c366a6
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
83abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com#include "Test.h"
98cae8358f78b81539f1006afe592a37f1604e67creed@google.com#include "SkCanvas.h"
1055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com#include "SkPaint.h"
113abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com#include "SkPath.h"
1204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com#include "SkParse.h"
133e71a887628ff25c806675366b081c70bb10b74dreed@google.com#include "SkParsePath.h"
148b06f1a7ff6d5a59387a90433064550de20787eereed@google.com#include "SkPathEffect.h"
156630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org#include "SkRandom.h"
1653effc5e327749ea47bc0c678cb45246644600b0reed@google.com#include "SkReader32.h"
1760bc6d5cb0af7cef0e49cc35f28f36f89b10853ereed@android.com#include "SkSize.h"
1853effc5e327749ea47bc0c678cb45246644600b0reed@google.com#include "SkWriter32.h"
198cae8358f78b81539f1006afe592a37f1604e67creed@google.com#include "SkSurface.h"
208cae8358f78b81539f1006afe592a37f1604e67creed@google.com
2156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com#if defined(WIN32)
2256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    #define SUPPRESS_VISIBILITY_WARNING
2356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com#else
2456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    #define SUPPRESS_VISIBILITY_WARNING __attribute__((visibility("hidden")))
2556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com#endif
2656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
278cae8358f78b81539f1006afe592a37f1604e67creed@google.comstatic SkSurface* new_surface(int w, int h) {
288cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkImage::Info info = {
298cae8358f78b81539f1006afe592a37f1604e67creed@google.com        w, h, SkImage::kPMColor_ColorType, SkImage::kPremul_AlphaType
308cae8358f78b81539f1006afe592a37f1604e67creed@google.com    };
31b947625800a26194fcf63d7b57dadb1a63677f6amike@reedtribe.org    return SkSurface::NewRaster(info);
328cae8358f78b81539f1006afe592a37f1604e67creed@google.com}
338cae8358f78b81539f1006afe592a37f1604e67creed@google.com
34a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com// Make sure we stay non-finite once we get there (unless we reset or rewind).
35a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.comstatic void test_addrect_isfinite(skiatest::Reporter* reporter) {
36a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    SkPath path;
378b0e2340e11e973d27aea39ec65e6bc9738224a5skia.committer@gmail.com
38a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.addRect(SkRect::MakeWH(50, 100));
39a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
40a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
41a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.moveTo(0, 0);
42a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.lineTo(SK_ScalarInfinity, 42);
43a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
44a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
45a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.addRect(SkRect::MakeWH(50, 100));
46a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
47a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
48a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.reset();
49a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
508b0e2340e11e973d27aea39ec65e6bc9738224a5skia.committer@gmail.com
51a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.addRect(SkRect::MakeWH(50, 100));
52a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
53a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com}
54a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
558cae8358f78b81539f1006afe592a37f1604e67creed@google.com// Inspired by http://ie.microsoft.com/testdrive/Performance/Chalkboard/
568cae8358f78b81539f1006afe592a37f1604e67creed@google.com// which triggered an assert, from a tricky cubic. This test replicates that
578cae8358f78b81539f1006afe592a37f1604e67creed@google.com// example, so we can ensure that we handle it (in SkEdge.cpp), and don't
588cae8358f78b81539f1006afe592a37f1604e67creed@google.com// assert in the SK_DEBUG build.
598cae8358f78b81539f1006afe592a37f1604e67creed@google.comstatic void test_tricky_cubic(skiatest::Reporter* reporter) {
608cae8358f78b81539f1006afe592a37f1604e67creed@google.com    const SkPoint pts[] = {
61055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.8943768),    SkDoubleToScalar(129.121277) },
62055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.8937435),    SkDoubleToScalar(129.121689) },
63055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.8950119),    SkDoubleToScalar(129.120422) },
64055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.5030727),    SkDoubleToScalar(129.13121)  },
658cae8358f78b81539f1006afe592a37f1604e67creed@google.com    };
668cae8358f78b81539f1006afe592a37f1604e67creed@google.com
678cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkPath path;
688cae8358f78b81539f1006afe592a37f1604e67creed@google.com    path.moveTo(pts[0]);
698cae8358f78b81539f1006afe592a37f1604e67creed@google.com    path.cubicTo(pts[1], pts[2], pts[3]);
708cae8358f78b81539f1006afe592a37f1604e67creed@google.com
718cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkPaint paint;
728cae8358f78b81539f1006afe592a37f1604e67creed@google.com    paint.setAntiAlias(true);
738cae8358f78b81539f1006afe592a37f1604e67creed@google.com
748cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkSurface* surface = new_surface(19, 130);
758cae8358f78b81539f1006afe592a37f1604e67creed@google.com    surface->getCanvas()->drawPath(path, paint);
768cae8358f78b81539f1006afe592a37f1604e67creed@google.com    surface->unref();
778cae8358f78b81539f1006afe592a37f1604e67creed@google.com}
783abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
79ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com// Inspired by http://code.google.com/p/chromium/issues/detail?id=141651
80ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com//
81ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.comstatic void test_isfinite_after_transform(skiatest::Reporter* reporter) {
82ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    SkPath path;
83ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    path.quadTo(157, 366, 286, 208);
84ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    path.arcTo(37, 442, 315, 163, 957494590897113.0f);
85d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
86ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    SkMatrix matrix;
87ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    matrix.setScale(1000*1000, 1000*1000);
88ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com
89ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // Be sure that path::transform correctly updates isFinite and the bounds
90ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // if the transformation overflows. The previous bug was that isFinite was
91ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // set to true in this case, but the bounds were not set to empty (which
92ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // they should be).
93ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    while (path.isFinite()) {
94ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com        REPORTER_ASSERT(reporter, path.getBounds().isFinite());
95ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com        REPORTER_ASSERT(reporter, !path.getBounds().isEmpty());
96ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com        path.transform(matrix);
97ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    }
98ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    REPORTER_ASSERT(reporter, path.getBounds().isEmpty());
99ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com
100ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    matrix.setTranslate(SK_Scalar1, SK_Scalar1);
101ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    path.transform(matrix);
102ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // we need to still be non-finite
103ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
104ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    REPORTER_ASSERT(reporter, path.getBounds().isEmpty());
105ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com}
106ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com
1076a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.comstatic void add_corner_arc(SkPath* path, const SkRect& rect,
1086a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.com                           SkScalar xIn, SkScalar yIn,
109b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com                           int startAngle)
110b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com{
111b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
112b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkScalar rx = SkMinScalar(rect.width(), xIn);
113b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkScalar ry = SkMinScalar(rect.height(), yIn);
114b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
115b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkRect arcRect;
116b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    arcRect.set(-rx, -ry, rx, ry);
117b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    switch (startAngle) {
118b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 0:
119b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
120b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
121b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 90:
122b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
123b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
124b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 180:
125b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
126b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
127b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 270:
128b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
129b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
130b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    default:
131b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
132b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    }
133b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
134b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
135b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com}
136b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
1376a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.comstatic void make_arb_round_rect(SkPath* path, const SkRect& r,
138b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com                                SkScalar xCorner, SkScalar yCorner) {
139b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    // we are lazy here and use the same x & y for each corner
140b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 270);
141b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 0);
142b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 90);
143b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 180);
144158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    path->close();
145b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com}
146b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
147b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// Chrome creates its own round rects with each corner possibly being different.
148b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// Performance will suffer if they are not convex.
149b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// Note: PathBench::ArbRoundRectBench performs almost exactly
150b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// the same test (but with drawing)
151b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.comstatic void test_arb_round_rect_is_convex(skiatest::Reporter* reporter) {
152b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkRandom rand;
153b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkRect r;
154b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
155b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    for (int i = 0; i < 5000; ++i) {
156b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
157158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkScalar size = rand.nextUScalar1() * 30;
158158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        if (size < SK_Scalar1) {
159b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com            continue;
160b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        }
161b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        r.fLeft = rand.nextUScalar1() * 300;
162b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        r.fTop =  rand.nextUScalar1() * 300;
163158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fRight =  r.fLeft + 2 * size;
164158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fBottom = r.fTop + 2 * size;
165b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
166b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        SkPath temp;
167b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
168b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
169b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
170c7a37c7bb2279d8c15d6fcbaf38f59dbd727eb6crobertphillips@google.com#ifdef SK_REDEFINE_ROOT2OVER2_TO_MAKE_ARCTOS_CONVEX
171b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        REPORTER_ASSERT(reporter, temp.isConvex());
172c7a37c7bb2279d8c15d6fcbaf38f59dbd727eb6crobertphillips@google.com#endif
173b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    }
174b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com}
175b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
176158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// Chrome will sometimes create a 0 radius round rect. The degenerate
177158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// quads prevent the path from being converted to a rect
178158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// Note: PathBench::ArbRoundRectBench performs almost exactly
179158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// the same test (but with drawing)
180158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.comstatic void test_arb_zero_rad_round_rect_is_rect(skiatest::Reporter* reporter) {
181158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    SkRandom rand;
182158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    SkRect r;
183158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
184158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    for (int i = 0; i < 5000; ++i) {
185158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
186158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkScalar size = rand.nextUScalar1() * 30;
187158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        if (size < SK_Scalar1) {
188158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com            continue;
189158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        }
190158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fLeft = rand.nextUScalar1() * 300;
191158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fTop =  rand.nextUScalar1() * 300;
192158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fRight =  r.fLeft + 2 * size;
193158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fBottom = r.fTop + 2 * size;
194158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
195158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkPath temp;
196158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
197158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        make_arb_round_rect(&temp, r, 0, 0);
198158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
199158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com#ifdef SK_REDEFINE_ROOT2OVER2_TO_MAKE_ARCTOS_CONVEX
200158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkRect result;
201158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        REPORTER_ASSERT(reporter, temp.isRect(&result));
202158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        REPORTER_ASSERT(reporter, r == result);
203158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com#endif
204158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    }
205158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com}
206158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
2070bb18bb264b26afca45452910437c09445e23a3creed@google.comstatic void test_rect_isfinite(skiatest::Reporter* reporter) {
2080bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar inf = SK_ScalarInfinity;
2090bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar nan = SK_ScalarNaN;
210d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2110bb18bb264b26afca45452910437c09445e23a3creed@google.com    SkRect r;
2120bb18bb264b26afca45452910437c09445e23a3creed@google.com    r.setEmpty();
2130bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, r.isFinite());
2140bb18bb264b26afca45452910437c09445e23a3creed@google.com    r.set(0, 0, inf, -inf);
2150bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !r.isFinite());
2160bb18bb264b26afca45452910437c09445e23a3creed@google.com    r.set(0, 0, nan, 0);
2170bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !r.isFinite());
218d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2190bb18bb264b26afca45452910437c09445e23a3creed@google.com    SkPoint pts[] = {
2200bb18bb264b26afca45452910437c09445e23a3creed@google.com        { 0, 0 },
2210bb18bb264b26afca45452910437c09445e23a3creed@google.com        { SK_Scalar1, 0 },
2220bb18bb264b26afca45452910437c09445e23a3creed@google.com        { 0, SK_Scalar1 },
2230bb18bb264b26afca45452910437c09445e23a3creed@google.com    };
224d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2250bb18bb264b26afca45452910437c09445e23a3creed@google.com    bool isFine = r.setBoundsCheck(pts, 3);
2260bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, isFine);
2270bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !r.isEmpty());
228d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2290bb18bb264b26afca45452910437c09445e23a3creed@google.com    pts[1].set(inf, 0);
2300bb18bb264b26afca45452910437c09445e23a3creed@google.com    isFine = r.setBoundsCheck(pts, 3);
2310bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !isFine);
2320bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, r.isEmpty());
233d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2340bb18bb264b26afca45452910437c09445e23a3creed@google.com    pts[1].set(nan, 0);
2350bb18bb264b26afca45452910437c09445e23a3creed@google.com    isFine = r.setBoundsCheck(pts, 3);
2360bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !isFine);
2370bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, r.isEmpty());
2380bb18bb264b26afca45452910437c09445e23a3creed@google.com}
2390bb18bb264b26afca45452910437c09445e23a3creed@google.com
2400bb18bb264b26afca45452910437c09445e23a3creed@google.comstatic void test_path_isfinite(skiatest::Reporter* reporter) {
2410bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar inf = SK_ScalarInfinity;
2420bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar nan = SK_ScalarNaN;
243d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2440bb18bb264b26afca45452910437c09445e23a3creed@google.com    SkPath path;
2450bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
2460bb18bb264b26afca45452910437c09445e23a3creed@google.com
2470bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2480bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
2490bb18bb264b26afca45452910437c09445e23a3creed@google.com
2500bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2510bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.moveTo(SK_Scalar1, 0);
2520bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
2530bb18bb264b26afca45452910437c09445e23a3creed@google.com
2540bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2550bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.moveTo(inf, -inf);
2560bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
2570bb18bb264b26afca45452910437c09445e23a3creed@google.com
2580bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2590bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.moveTo(nan, 0);
2600bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
2610bb18bb264b26afca45452910437c09445e23a3creed@google.com}
2620bb18bb264b26afca45452910437c09445e23a3creed@google.com
2630bb18bb264b26afca45452910437c09445e23a3creed@google.comstatic void test_isfinite(skiatest::Reporter* reporter) {
2640bb18bb264b26afca45452910437c09445e23a3creed@google.com    test_rect_isfinite(reporter);
2650bb18bb264b26afca45452910437c09445e23a3creed@google.com    test_path_isfinite(reporter);
2660bb18bb264b26afca45452910437c09445e23a3creed@google.com}
2670bb18bb264b26afca45452910437c09445e23a3creed@google.com
268744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com// assert that we always
269744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  start with a moveTo
270744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  only have 1 moveTo
271744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  only have Lines after that
272744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  end with a single close
273744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  only have (at most) 1 close
274744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//
275744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.comstatic void test_poly(skiatest::Reporter* reporter, const SkPath& path,
276744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                      const SkPoint srcPts[], int count, bool expectClose) {
277744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkPath::RawIter iter(path);
278744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkPoint         pts[4];
279744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
280744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    bool firstTime = true;
281744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    bool foundClose = false;
282744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    for (;;) {
283744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        switch (iter.next(pts)) {
284744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kMove_Verb:
285744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, firstTime);
286744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, pts[0] == srcPts[0]);
287744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                srcPts++;
288744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                firstTime = false;
289744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
290744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kLine_Verb:
291744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !firstTime);
292744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, pts[1] == srcPts[0]);
293744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                srcPts++;
294744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
295744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kQuad_Verb:
296744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !"unexpected quad verb");
297744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
298744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kCubic_Verb:
299744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !"unexpected cubic verb");
300744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
301744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kClose_Verb:
302744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !firstTime);
303744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !foundClose);
304744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, expectClose);
305744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                foundClose = true;
306744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
307744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kDone_Verb:
308744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                goto DONE;
309744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        }
310744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    }
311744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.comDONE:
312744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    REPORTER_ASSERT(reporter, foundClose == expectClose);
313744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com}
314744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
315744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.comstatic void test_addPoly(skiatest::Reporter* reporter) {
316744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkPoint pts[32];
317744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkRandom rand;
318d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
319744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(pts); ++i) {
320744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        pts[i].fX = rand.nextSScalar1();
321744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        pts[i].fY = rand.nextSScalar1();
322744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    }
323744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
324744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    for (int doClose = 0; doClose <= 1; ++doClose) {
325744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        for (size_t count = 1; count <= SK_ARRAY_COUNT(pts); ++count) {
326744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            SkPath path;
327744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            path.addPoly(pts, count, SkToBool(doClose));
328744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            test_poly(reporter, path, pts, count, SkToBool(doClose));
329744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        }
330744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    }
331744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com}
332744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
3338b06f1a7ff6d5a59387a90433064550de20787eereed@google.comstatic void test_strokerec(skiatest::Reporter* reporter) {
3348b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
3358b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, rec.isFillStyle());
336d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3378b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setHairlineStyle();
3388b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, rec.isHairlineStyle());
339d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3408b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(SK_Scalar1, false);
3418b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kStroke_Style == rec.getStyle());
342d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3438b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(SK_Scalar1, true);
3448b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kStrokeAndFill_Style == rec.getStyle());
345d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3468b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(0, false);
3478b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kHairline_Style == rec.getStyle());
348d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3498b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(0, true);
3508b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kFill_Style == rec.getStyle());
3518b06f1a7ff6d5a59387a90433064550de20787eereed@google.com}
3528b06f1a7ff6d5a59387a90433064550de20787eereed@google.com
35330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com// Set this for paths that don't have a consistent direction such as a bowtie.
35430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com// (cheapComputeDirection is not expected to catch these.)
35530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.comstatic const SkPath::Direction kDontCheckDir = static_cast<SkPath::Direction>(-1);
35630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
35730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.comstatic void check_direction(skiatest::Reporter* reporter, const SkPath& path,
35830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                            SkPath::Direction expected) {
35930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    if (expected == kDontCheckDir) {
36030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        return;
36130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    }
36230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkPath copy(path); // we make a copy so that we don't cache the result on the passed in path.
36330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
36430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkPath::Direction dir;
36530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    if (copy.cheapComputeDirection(&dir)) {
36630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        REPORTER_ASSERT(reporter, dir == expected);
36730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    } else {
36830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        REPORTER_ASSERT(reporter, SkPath::kUnknown_Direction == expected);
369f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    }
370f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com}
371f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com
3723e71a887628ff25c806675366b081c70bb10b74dreed@google.comstatic void test_direction(skiatest::Reporter* reporter) {
3733e71a887628ff25c806675366b081c70bb10b74dreed@google.com    size_t i;
3743e71a887628ff25c806675366b081c70bb10b74dreed@google.com    SkPath path;
3753e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, !path.cheapComputeDirection(NULL));
3763e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCW_Direction));
3773e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCCW_Direction));
3783e71a887628ff25c806675366b081c70bb10b74dreed@google.com
3793e71a887628ff25c806675366b081c70bb10b74dreed@google.com    static const char* gDegen[] = {
3803e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10",
3813e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 M 20 20",
3823e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 L 20 20",
3833e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 L 10 10 L 10 10",
3843e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 Q 10 10 10 10",
3853e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 C 10 10 10 10 10 10",
3863e71a887628ff25c806675366b081c70bb10b74dreed@google.com    };
3873e71a887628ff25c806675366b081c70bb10b74dreed@google.com    for (i = 0; i < SK_ARRAY_COUNT(gDegen); ++i) {
3883e71a887628ff25c806675366b081c70bb10b74dreed@google.com        path.reset();
3893e71a887628ff25c806675366b081c70bb10b74dreed@google.com        bool valid = SkParsePath::FromSVGString(gDegen[i], &path);
3903e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, valid);
3913e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, !path.cheapComputeDirection(NULL));
3923e71a887628ff25c806675366b081c70bb10b74dreed@google.com    }
393d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3943e71a887628ff25c806675366b081c70bb10b74dreed@google.com    static const char* gCW[] = {
395cabaf1daf3fdcc151c12d59b05bdbe136c178b3breed@google.com        "M 10 10 L 10 10 Q 20 10 20 20",
3963e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 C 20 10 20 20 20 20",
397d414666d18fa9dca1cb310bc66c574aac3d79b72reed@google.com        "M 20 10 Q 20 20 30 20 L 10 20", // test double-back at y-max
3984eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // rect with top two corners replaced by cubics with identical middle
3994eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // control points
40020fb0c7f22a0bee68bf620f765836a60ca80f9b5reed@google.com        "M 10 10 C 10 0 10 0 20 0 L 40 0 C 50 0 50 0 50 10",
40120fb0c7f22a0bee68bf620f765836a60ca80f9b5reed@google.com        "M 20 10 L 0 10 Q 10 10 20 0",  // left, degenerate serif
4023e71a887628ff25c806675366b081c70bb10b74dreed@google.com    };
4033e71a887628ff25c806675366b081c70bb10b74dreed@google.com    for (i = 0; i < SK_ARRAY_COUNT(gCW); ++i) {
4043e71a887628ff25c806675366b081c70bb10b74dreed@google.com        path.reset();
4053e71a887628ff25c806675366b081c70bb10b74dreed@google.com        bool valid = SkParsePath::FromSVGString(gCW[i], &path);
4063e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, valid);
40730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        check_direction(reporter, path, SkPath::kCW_Direction);
4083e71a887628ff25c806675366b081c70bb10b74dreed@google.com    }
409d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
4103e71a887628ff25c806675366b081c70bb10b74dreed@google.com    static const char* gCCW[] = {
411cabaf1daf3fdcc151c12d59b05bdbe136c178b3breed@google.com        "M 10 10 L 10 10 Q 20 10 20 -20",
4123e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 C 20 10 20 -20 20 -20",
413d414666d18fa9dca1cb310bc66c574aac3d79b72reed@google.com        "M 20 10 Q 20 20 10 20 L 30 20", // test double-back at y-max
4144eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // rect with top two corners replaced by cubics with identical middle
4154eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // control points
41620fb0c7f22a0bee68bf620f765836a60ca80f9b5reed@google.com        "M 50 10 C 50 0 50 0 40 0 L 20 0 C 10 0 10 0 10 10",
41720fb0c7f22a0bee68bf620f765836a60ca80f9b5reed@google.com        "M 10 10 L 30 10 Q 20 10 10 0",  // right, degenerate serif
4183e71a887628ff25c806675366b081c70bb10b74dreed@google.com    };
4193e71a887628ff25c806675366b081c70bb10b74dreed@google.com    for (i = 0; i < SK_ARRAY_COUNT(gCCW); ++i) {
4203e71a887628ff25c806675366b081c70bb10b74dreed@google.com        path.reset();
4213e71a887628ff25c806675366b081c70bb10b74dreed@google.com        bool valid = SkParsePath::FromSVGString(gCCW[i], &path);
4223e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, valid);
42330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        check_direction(reporter, path, SkPath::kCCW_Direction);
4243e71a887628ff25c806675366b081c70bb10b74dreed@google.com    }
425ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com
426ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    // Test two donuts, each wound a different direction. Only the outer contour
427ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    // determines the cheap direction
428ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.reset();
429ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCW_Direction);
430ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCCW_Direction);
43130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, path, SkPath::kCW_Direction);
432f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com
433ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.reset();
434ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCW_Direction);
435ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCCW_Direction);
43630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, path, SkPath::kCCW_Direction);
437f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com
4386843ac4bebd00eef9af28f9f069e7c188b466af3bsalomon@google.com#ifdef SK_SCALAR_IS_FLOAT
439f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    // triangle with one point really far from the origin.
440f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    path.reset();
441f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    // the first point is roughly 1.05e10, 1.05e10
44253aab7813ca20360426524361941cf43567fc7aebsalomon@google.com    path.moveTo(SkFloatToScalar(SkBits2Float(0x501c7652)), SkFloatToScalar(SkBits2Float(0x501c7652)));
44353aab7813ca20360426524361941cf43567fc7aebsalomon@google.com    path.lineTo(110 * SK_Scalar1, -10 * SK_Scalar1);
44453aab7813ca20360426524361941cf43567fc7aebsalomon@google.com    path.lineTo(-10 * SK_Scalar1, 60 * SK_Scalar1);
44530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, path, SkPath::kCCW_Direction);
44653aab7813ca20360426524361941cf43567fc7aebsalomon@google.com#endif
4473e71a887628ff25c806675366b081c70bb10b74dreed@google.com}
4483e71a887628ff25c806675366b081c70bb10b74dreed@google.com
449ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.comstatic void add_rect(SkPath* path, const SkRect& r) {
450ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->moveTo(r.fLeft, r.fTop);
451ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->lineTo(r.fRight, r.fTop);
452ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->lineTo(r.fRight, r.fBottom);
453ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->lineTo(r.fLeft, r.fBottom);
454ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->close();
455ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com}
456ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
457ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.comstatic void test_bounds(skiatest::Reporter* reporter) {
458ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    static const SkRect rects[] = {
4593563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(160) },
4603563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(610), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(199) },
4613563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(10), SkIntToScalar(198), SkIntToScalar(610), SkIntToScalar(199) },
4623563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(10), SkIntToScalar(199) },
463ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    };
464ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
465ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    SkPath path0, path1;
466ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(rects); ++i) {
467ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com        path0.addRect(rects[i]);
468ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com        add_rect(&path1, rects[i]);
469ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    }
470ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
471ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    REPORTER_ASSERT(reporter, path0.getBounds() == path1.getBounds());
472ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com}
473ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
47455b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.comstatic void stroke_cubic(const SkPoint pts[4]) {
47555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPath path;
47655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    path.moveTo(pts[0]);
47755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    path.cubicTo(pts[1], pts[2], pts[3]);
478d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
47955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPaint paint;
48055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    paint.setStyle(SkPaint::kStroke_Style);
48155b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    paint.setStrokeWidth(SK_Scalar1 * 2);
482d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
48355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPath fill;
48455b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    paint.getFillPath(path, &fill);
48555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com}
48655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com
48755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com// just ensure this can run w/o any SkASSERTS firing in the debug build
48855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com// we used to assert due to differences in how we determine a degenerate vector
48955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com// but that was fixed with the introduction of SkPoint::CanNormalize
49055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.comstatic void stroke_tiny_cubic() {
49155b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPoint p0[] = {
49255b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
49355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
49455b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
49555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
49655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    };
497d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
49855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    stroke_cubic(p0);
499d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
50055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPoint p1[] = {
50155b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,       92.0f },
50255b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0007f,    92.000755f },
50355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 371.99927f,   92.003922f },
50455b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 371.99826f,   92.003899f },
50555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    };
506d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
50755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    stroke_cubic(p1);
50855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com}
50955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com
510b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.comstatic void check_close(skiatest::Reporter* reporter, const SkPath& path) {
511b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    for (int i = 0; i < 2; ++i) {
51209042b80d22837c760bb530124aaa67469b19b8frobertphillips@google.com        SkPath::Iter iter(path, SkToBool(i));
513b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        SkPoint mv;
514b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        SkPoint pts[4];
515b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        SkPath::Verb v;
516b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        int nMT = 0;
517b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        int nCL = 0;
518221db3c3364eb110bc03db78cb09aae51d117b27tomhudson@google.com        mv.set(0, 0);
519b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        while (SkPath::kDone_Verb != (v = iter.next(pts))) {
520b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com            switch (v) {
521b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                case SkPath::kMove_Verb:
522b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    mv = pts[0];
523b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    ++nMT;
524b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    break;
525b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                case SkPath::kClose_Verb:
526b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    REPORTER_ASSERT(reporter, mv == pts[0]);
527b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    ++nCL;
528b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    break;
529b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                default:
530b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    break;
531b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com            }
532b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        }
533b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        // if we force a close on the interator we should have a close
534b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        // for every moveTo
535b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        REPORTER_ASSERT(reporter, !i || nMT == nCL);
536b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    }
537b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com}
538b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
539b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.comstatic void test_close(skiatest::Reporter* reporter) {
540b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath closePt;
541b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    closePt.moveTo(0, 0);
542b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    closePt.close();
543b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, closePt);
544b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
545b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath openPt;
546b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    openPt.moveTo(0, 0);
547b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, openPt);
548b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
549b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath empty;
550b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, empty);
551b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    empty.close();
552b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, empty);
553b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
554b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath rect;
555b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
556b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect);
557b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect.close();
558b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect);
559b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
560b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath quad;
561b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    quad.quadTo(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
562b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, quad);
563b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    quad.close();
564b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, quad);
565b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
566b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath cubic;
567d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    quad.cubicTo(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1,
568b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                 10*SK_Scalar1, 20 * SK_Scalar1, 20*SK_Scalar1);
569b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, cubic);
570b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    cubic.close();
571b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, cubic);
572b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
573b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath line;
574b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    line.moveTo(SK_Scalar1, SK_Scalar1);
575b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    line.lineTo(10 * SK_Scalar1, 10*SK_Scalar1);
576b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, line);
577b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    line.close();
578b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, line);
579b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
580b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath rect2;
581b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
582b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.close();
583b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
584b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect2);
585b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.close();
586b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect2);
587b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
588b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath oval3;
589b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.addOval(SkRect::MakeWH(SK_Scalar1*100,SK_Scalar1*100));
590b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.close();
591b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.addOval(SkRect::MakeWH(SK_Scalar1*200,SK_Scalar1*200));
592b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, oval3);
593b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.close();
594b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, oval3);
595b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
596b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath moves;
597b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(SK_Scalar1, SK_Scalar1);
598b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(5 * SK_Scalar1, SK_Scalar1);
599b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(SK_Scalar1, 10 * SK_Scalar1);
600b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(10 *SK_Scalar1, SK_Scalar1);
601b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, moves);
60255b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com
60355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    stroke_tiny_cubic();
604b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com}
605b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
6067c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.comstatic void check_convexity(skiatest::Reporter* reporter, const SkPath& path,
6077c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com                            SkPath::Convexity expected) {
60830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkPath copy(path); // we make a copy so that we don't cache the result on the passed in path.
60930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkPath::Convexity c = copy.getConvexity();
6107c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    REPORTER_ASSERT(reporter, c == expected);
6117c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com}
6127c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com
6137c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.comstatic void test_convexity2(skiatest::Reporter* reporter) {
6147c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath pt;
6157c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    pt.moveTo(0, 0);
6167c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    pt.close();
617b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    check_convexity(reporter, pt, SkPath::kConvex_Convexity);
61830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, pt, SkPath::kUnknown_Direction);
619d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6207c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath line;
6216c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    line.moveTo(12*SK_Scalar1, 20*SK_Scalar1);
6226c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    line.lineTo(-12*SK_Scalar1, -20*SK_Scalar1);
6237c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    line.close();
62430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_convexity(reporter, line, SkPath::kConvex_Convexity);
62530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, line, SkPath::kUnknown_Direction);
626d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6277c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath triLeft;
6287c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triLeft.moveTo(0, 0);
6296c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triLeft.lineTo(SK_Scalar1, 0);
6306c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triLeft.lineTo(SK_Scalar1, SK_Scalar1);
6317c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triLeft.close();
6327c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, triLeft, SkPath::kConvex_Convexity);
63330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, triLeft, SkPath::kCW_Direction);
634d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6357c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath triRight;
6367c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triRight.moveTo(0, 0);
6376c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triRight.lineTo(-SK_Scalar1, 0);
6386c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triRight.lineTo(SK_Scalar1, SK_Scalar1);
6397c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triRight.close();
6407c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, triRight, SkPath::kConvex_Convexity);
64130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, triRight, SkPath::kCCW_Direction);
642d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6437c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath square;
6447c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    square.moveTo(0, 0);
6456c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    square.lineTo(SK_Scalar1, 0);
6466c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    square.lineTo(SK_Scalar1, SK_Scalar1);
6476c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    square.lineTo(0, SK_Scalar1);
6487c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    square.close();
6497c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, square, SkPath::kConvex_Convexity);
65030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, square, SkPath::kCW_Direction);
651d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6527c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath redundantSquare;
6537c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.moveTo(0, 0);
6547c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.lineTo(0, 0);
6557c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.lineTo(0, 0);
6566c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, 0);
6576c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, 0);
6586c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, 0);
6596c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
6606c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
6616c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
6626c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(0, SK_Scalar1);
6636c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(0, SK_Scalar1);
6646c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(0, SK_Scalar1);
6657c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.close();
6667c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, redundantSquare, SkPath::kConvex_Convexity);
66730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, redundantSquare, SkPath::kCW_Direction);
668d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6697c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath bowTie;
6707c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.moveTo(0, 0);
6717c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.lineTo(0, 0);
6727c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.lineTo(0, 0);
6736c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
6746c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
6756c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
6766c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, 0);
6776c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, 0);
6786c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, 0);
6796c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(0, SK_Scalar1);
6806c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(0, SK_Scalar1);
6816c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(0, SK_Scalar1);
6827c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.close();
6837c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, bowTie, SkPath::kConcave_Convexity);
68430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, bowTie, kDontCheckDir);
685d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6867c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath spiral;
6877c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    spiral.moveTo(0, 0);
6886c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(100*SK_Scalar1, 0);
6896c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
6906c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(0, 100*SK_Scalar1);
6916c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(0, 50*SK_Scalar1);
6926c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(50*SK_Scalar1, 50*SK_Scalar1);
6936c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(50*SK_Scalar1, 75*SK_Scalar1);
6947c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    spiral.close();
69585b6e399d56d2421980daa432f30910beda41922reed@google.com    check_convexity(reporter, spiral, SkPath::kConcave_Convexity);
69630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, spiral, kDontCheckDir);
697d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6987c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath dent;
6996c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.moveTo(0, 0);
7006c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
7016c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(0, 100*SK_Scalar1);
7026c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(-50*SK_Scalar1, 200*SK_Scalar1);
7036c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(-200*SK_Scalar1, 100*SK_Scalar1);
7047c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    dent.close();
7057c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, dent, SkPath::kConcave_Convexity);
70630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_direction(reporter, dent, SkPath::kCW_Direction);
7077c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com}
7087c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com
7096b82d1adc6a4726e36674e468ff1157e0b75373freed@android.comstatic void check_convex_bounds(skiatest::Reporter* reporter, const SkPath& p,
7106b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com                                const SkRect& bounds) {
7116b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p.isConvex());
7126b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p.getBounds() == bounds);
71362047cf1980861234e7367a225928b84ce492c68reed@google.com
7146b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    SkPath p2(p);
7156b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p2.isConvex());
7166b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p2.getBounds() == bounds);
7176b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
7186b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    SkPath other;
7196b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    other.swap(p2);
7206b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, other.isConvex());
7216b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, other.getBounds() == bounds);
7226b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com}
7236b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
72404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.comstatic void setFromString(SkPath* path, const char str[]) {
72504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    bool first = true;
72604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    while (str) {
72704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkScalar x, y;
72804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        str = SkParse::FindScalar(str, &x);
72904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        if (NULL == str) {
73004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            break;
73104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        }
73204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        str = SkParse::FindScalar(str, &y);
73304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkASSERT(str);
73404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        if (first) {
73504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            path->moveTo(x, y);
73604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            first = false;
73704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        } else {
73804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            path->lineTo(x, y);
73904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        }
74004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    }
74104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com}
74204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
74304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.comstatic void test_convexity(skiatest::Reporter* reporter) {
74404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    SkPath path;
74504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
74630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_convexity(reporter, path, SkPath::kConvex_Convexity);
747e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addCircle(0, 0, SkIntToScalar(10));
74830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_convexity(reporter, path, SkPath::kConvex_Convexity);
749e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addCircle(0, 0, SkIntToScalar(10));   // 2nd circle
75030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_convexity(reporter, path, SkPath::kConcave_Convexity);
75130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
75204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    path.reset();
753e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPath::kCCW_Direction);
75430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_convexity(reporter, path, SkPath::kConvex_Convexity);
7553e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCCW_Direction));
75630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
75704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    path.reset();
758e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPath::kCW_Direction);
75930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_convexity(reporter, path, SkPath::kConvex_Convexity);
7603e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCW_Direction));
761d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
76204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    static const struct {
76304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        const char*         fPathStr;
76404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkPath::Convexity   fExpectedConvexity;
76530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        SkPath::Direction   fExpectedDirection;
76604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    } gRec[] = {
76730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "", SkPath::kConvex_Convexity, SkPath::kUnknown_Direction },
76830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "0 0", SkPath::kConvex_Convexity, SkPath::kUnknown_Direction },
76930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "0 0 10 10", SkPath::kConvex_Convexity, SkPath::kUnknown_Direction },
77030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "0 0 10 10 20 20 0 0 10 10", SkPath::kConcave_Convexity, SkPath::kUnknown_Direction },
77130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "0 0 10 10 10 20", SkPath::kConvex_Convexity, SkPath::kCW_Direction },
77230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "0 0 10 10 10 0", SkPath::kConvex_Convexity, SkPath::kCCW_Direction },
77330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "0 0 10 10 10 0 0 10", SkPath::kConcave_Convexity, kDontCheckDir },
77430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        { "0 0 10 0 0 10 -10 -10", SkPath::kConcave_Convexity, SkPath::kCW_Direction },
77504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    };
77604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
77704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
77804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkPath path;
77904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        setFromString(&path, gRec[i].fPathStr);
78030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        check_convexity(reporter, path, gRec[i].fExpectedConvexity);
78130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        check_direction(reporter, path, gRec[i].fExpectedDirection);
78204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    }
78304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com}
78404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
7857e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.comstatic void test_isLine(skiatest::Reporter* reporter) {
7867e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkPath path;
7877e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkPoint pts[2];
7887e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar value = SkIntToScalar(5);
7897e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
7907e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(NULL));
791d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
7927e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    // set some non-zero values
7937e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    pts[0].set(value, value);
7947e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    pts[1].set(value, value);
7957e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(pts));
7967e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    // check that pts was untouched
7977e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(value, value));
7987e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(value, value));
7997e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8007e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar moveX = SkIntToScalar(1);
8017e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar moveY = SkIntToScalar(2);
8027e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkASSERT(value != moveX && value != moveY);
8037e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8047e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    path.moveTo(moveX, moveY);
8057e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(NULL));
8067e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(pts));
8077e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    // check that pts was untouched
8087e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(value, value));
8097e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(value, value));
8107e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8117e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar lineX = SkIntToScalar(2);
8127e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar lineY = SkIntToScalar(2);
8137e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkASSERT(value != lineX && value != lineY);
8147e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8157e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    path.lineTo(lineX, lineY);
8167e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, path.isLine(NULL));
8177e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8187e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !pts[0].equals(moveX, moveY));
8197e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !pts[1].equals(lineX, lineY));
8207e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, path.isLine(pts));
8217e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
8227e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
8237e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8247e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    path.lineTo(0, 0);  // too many points/verbs
8257e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(NULL));
8267e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(pts));
8277e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
8287e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
8297e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com}
8307e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8319bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.comstatic void test_conservativelyContains(skiatest::Reporter* reporter) {
8329bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    SkPath path;
8339bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8349bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // kBaseRect is used to construct most our test paths: a rect, a circle, and a round-rect.
8359bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    static const SkRect kBaseRect = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
8369bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8379bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // A circle that bounds kBaseRect (with a significant amount of slop)
8389bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    SkScalar circleR = SkMaxScalar(kBaseRect.width(), kBaseRect.height());
8399bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    circleR = SkScalarMul(circleR, SkFloatToScalar(1.75f)) / 2;
8409bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    static const SkPoint kCircleC = {kBaseRect.centerX(), kBaseRect.centerY()};
8419bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8429bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // round-rect radii
8439bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    static const SkScalar kRRRadii[] = {SkIntToScalar(5), SkIntToScalar(3)};
844cec8de68217186d0f5676a696de44343aaa61de7skia.committer@gmail.com
84556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    static const struct SUPPRESS_VISIBILITY_WARNING {
8469bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        SkRect fQueryRect;
8479bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        bool   fInRect;
8489bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        bool   fInCircle;
8499bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        bool   fInRR;
8509bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    } kQueries[] = {
8519bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {kBaseRect, true, true, false},
8529bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8539bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // rect well inside of kBaseRect
8549bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeLTRB(kBaseRect.fLeft + SkFloatToScalar(0.25f)*kBaseRect.width(),
8559bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.fTop + SkFloatToScalar(0.25f)*kBaseRect.height(),
8569bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.fRight - SkFloatToScalar(0.25f)*kBaseRect.width(),
8579bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.fBottom - SkFloatToScalar(0.25f)*kBaseRect.height()),
8589bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          true, true, true},
8599bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8609bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // rects with edges off by one from kBaseRect's edges
8619bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
8629bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width(), kBaseRect.height() + 1),
8639bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
8649bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
8659bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width() + 1, kBaseRect.height()),
8669bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
8679bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
8689bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width() + 1, kBaseRect.height() + 1),
8699bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
8709bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop,
8719bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width(), kBaseRect.height()),
8729bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
8739bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1,
8749bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width(), kBaseRect.height()),
8759bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
8769bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop,
8779bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width() + 2, kBaseRect.height()),
8789bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
8799bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1,
8809bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width() + 2, kBaseRect.height()),
8819bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
8829bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8839bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // zero-w/h rects at each corner of kBaseRect
8849bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop, 0, 0), true, true, false},
8859bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fTop, 0, 0), true, true, false},
8869bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fBottom, 0, 0), true, true, false},
8879bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fBottom, 0, 0), true, true, false},
8889bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8899bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // far away rect
8909bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(10 * kBaseRect.fRight, 10 * kBaseRect.fBottom,
8919bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          SkIntToScalar(10), SkIntToScalar(10)),
8929bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, false, false},
8939bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
8949bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // very large rect containing kBaseRect
8959bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft - 5 * kBaseRect.width(),
8969bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.fTop - 5 * kBaseRect.height(),
8979bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          11 * kBaseRect.width(), 11 * kBaseRect.height()),
8989bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, false, false},
8999bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9009bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // skinny rect that spans same y-range as kBaseRect
9019bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop,
9029bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          SkIntToScalar(1), kBaseRect.height()),
9039bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         true, true, true},
9049bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9059bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // short rect that spans same x-range as kBaseRect
9069bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(), kBaseRect.width(), SkScalar(1)),
9079bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         true, true, true},
9089bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9099bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // skinny rect that spans slightly larger y-range than kBaseRect
9109bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop,
9119bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          SkIntToScalar(1), kBaseRect.height() + 1),
9129bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
9139bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9149bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        // short rect that spans slightly larger x-range than kBaseRect
9159bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(),
9169bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                          kBaseRect.width() + 1, SkScalar(1)),
9179bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com         false, true, false},
9189bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    };
9199bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9209bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    for (int inv = 0; inv < 4; ++inv) {
92156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        for (size_t q = 0; q < SK_ARRAY_COUNT(kQueries); ++q) {
9229bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            SkRect qRect = kQueries[q].fQueryRect;
9239bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            if (inv & 0x1) {
9249bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                SkTSwap(qRect.fLeft, qRect.fRight);
9259bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            }
9269bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            if (inv & 0x2) {
9279bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                SkTSwap(qRect.fTop, qRect.fBottom);
9289bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            }
9299bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            for (int d = 0; d < 2; ++d) {
9309bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                SkPath::Direction dir = d ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
9319bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                path.reset();
9329bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                path.addRect(kBaseRect, dir);
9339bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                REPORTER_ASSERT(reporter, kQueries[q].fInRect ==
9349bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                          path.conservativelyContainsRect(qRect));
9359bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9369bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                path.reset();
9379bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                path.addCircle(kCircleC.fX, kCircleC.fY, circleR, dir);
9389bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                REPORTER_ASSERT(reporter, kQueries[q].fInCircle ==
9399bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                          path.conservativelyContainsRect(qRect));
9409bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9419bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                path.reset();
9429bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                path.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1], dir);
9439bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                REPORTER_ASSERT(reporter, kQueries[q].fInRR ==
9449bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                          path.conservativelyContainsRect(qRect));
9459bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            }
9469bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            // Slightly non-convex shape, shouldn't contain any rects.
9479bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            path.reset();
9489bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            path.moveTo(0, 0);
9499bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            path.lineTo(SkIntToScalar(50), SkFloatToScalar(0.05f));
9509bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            path.lineTo(SkIntToScalar(100), 0);
9519bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            path.lineTo(SkIntToScalar(100), SkIntToScalar(100));
9529bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            path.lineTo(0, SkIntToScalar(100));
9539bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            path.close();
9549bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com            REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(qRect));
9559bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        }
9569bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    }
9579bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9589bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // make sure a minimal convex shape works, a right tri with edges along pos x and y axes.
9599bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    path.reset();
9609bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    path.moveTo(0, 0);
9619bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    path.lineTo(SkIntToScalar(100), 0);
9629bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    path.lineTo(0, SkIntToScalar(100));
9639bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9649bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // inside, on along top edge
9659bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    REPORTER_ASSERT(reporter, path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(50), 0,
9669bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                               SkIntToScalar(10),
9679bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                               SkIntToScalar(10))));
9689bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // above
9699bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(
9709bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com        SkRect::MakeXYWH(SkIntToScalar(50),
9719bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                         SkIntToScalar(-10),
9729bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                         SkIntToScalar(10),
9739bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                         SkIntToScalar(10))));
9749bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // to the left
9759bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(-10),
9769bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                                SkIntToScalar(5),
9779bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                                SkIntToScalar(5),
9789bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                                SkIntToScalar(5))));
9799bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
9809bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    // outside the diagonal edge
9819bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(10),
9829bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                                SkIntToScalar(200),
9839bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                                SkIntToScalar(20),
9849bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com                                                                                SkIntToScalar(5))));
9859bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com}
9869bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com
987f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com// Simple isRect test is inline TestPath, below.
988f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com// test_isRect provides more extensive testing.
989f131694617ce0410eafcb01124459382576bb1d9caryclark@google.comstatic void test_isRect(skiatest::Reporter* reporter) {
990f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // passing tests (all moveTo / lineTo...
991f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
992f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
993f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
994f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
995f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
996f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
997f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
998f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
999f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
1000f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f},
1001f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        {1, 0}, {.5f, 0}};
1002f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1},
1003f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        {0, 1}, {0, .5f}};
1004f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};
1005f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
1006f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}};
1007bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPoint rf[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 0}};
1008d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1009f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // failing tests
1010f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}}; // too few points
1011f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}}; // diagonal
1012f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}}; // wraps
1013f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}}; // backs up
1014f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}}; // end overshoots
1015f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}}; // end overshoots
1016f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}}; // end overshoots
1017f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}}; // 'L'
1018bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPoint f9[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 0}, {2, 0}}; // overlaps
1019bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPoint fa[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, -1}, {1, -1}}; // non colinear gap
1020bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPoint fb[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 1}}; // falls short
1021d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1022f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // failing, no close
1023f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; // close doesn't match
1024f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}}; // ditto
1025f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com
1026f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    size_t testLen[] = {
1027f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(r1), sizeof(r2), sizeof(r3), sizeof(r4), sizeof(r5), sizeof(r6),
1028f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(r7), sizeof(r8), sizeof(r9), sizeof(ra), sizeof(rb), sizeof(rc),
1029bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com        sizeof(rd), sizeof(re), sizeof(rf),
1030f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(f1), sizeof(f2), sizeof(f3), sizeof(f4), sizeof(f5), sizeof(f6),
1031bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com        sizeof(f7), sizeof(f8), sizeof(f9), sizeof(fa), sizeof(fb),
1032d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        sizeof(c1), sizeof(c2)
1033f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    };
1034f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint* tests[] = {
1035bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com        r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re, rf,
1036bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com        f1, f2, f3, f4, f5, f6, f7, f8, f9, fa, fb,
1037d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        c1, c2
1038f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    };
1039bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPoint* lastPass = rf;
1040bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPoint* lastClose = fb;
1041f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    bool fail = false;
1042f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    bool close = true;
1043f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    const size_t testCount = sizeof(tests) / sizeof(tests[0]);
1044f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    size_t index;
1045f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (size_t testIndex = 0; testIndex < testCount; ++testIndex) {
1046f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        SkPath path;
1047f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path.moveTo(tests[testIndex][0].fX, tests[testIndex][0].fY);
1048f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        for (index = 1; index < testLen[testIndex] / sizeof(SkPoint); ++index) {
1049f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path.lineTo(tests[testIndex][index].fX, tests[testIndex][index].fY);
1050f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
1051f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (close) {
1052f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path.close();
1053f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
1054f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path.isRect(0));
1055f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path.isRect(NULL, NULL));
1056f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com
105756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (!fail) {
105856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            SkRect computed, expected;
105956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            expected.set(tests[testIndex], testLen[testIndex] / sizeof(SkPoint));
106056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            REPORTER_ASSERT(reporter, path.isRect(&computed));
106156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            REPORTER_ASSERT(reporter, expected == computed);
1062f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com
1063f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            bool isClosed;
1064f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            SkPath::Direction direction, cheapDirection;
1065f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, path.cheapComputeDirection(&cheapDirection));
1066f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, path.isRect(&isClosed, &direction));
1067f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, isClosed == close);
1068f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, direction == cheapDirection);
1069f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com        } else {
1070f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            SkRect computed;
1071f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            computed.set(123, 456, 789, 1011);
1072f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, !path.isRect(&computed));
1073f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, computed.fLeft == 123 && computed.fTop == 456);
1074f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, computed.fRight == 789 && computed.fBottom == 1011);
1075f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com
1076f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            bool isClosed = (bool) -1;
1077f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            SkPath::Direction direction = (SkPath::Direction) -1;
1078f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, !path.isRect(&isClosed, &direction));
1079f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, isClosed == (bool) -1);
1080f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com            REPORTER_ASSERT(reporter, direction == (SkPath::Direction) -1);
108156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
1082f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com
1083f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (tests[testIndex] == lastPass) {
1084f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            fail = true;
1085f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
1086f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (tests[testIndex] == lastClose) {
1087f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            close = false;
1088f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
1089f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
1090d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1091f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, close then line
1092f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPath path1;
1093f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
1094f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
1095f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
1096f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
1097f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
1098f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.lineTo(1, 0);
1099f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
1100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1101f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, move in the middle
1102f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
1103f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
1104f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
1105f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (index == 2) {
1106f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path1.moveTo(1, .5f);
1107f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
1108f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
1109f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
1110f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
1111f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
1112f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com
1113f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, move on the edge
1114f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
1115f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
1116f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.moveTo(r1[index - 1].fX, r1[index - 1].fY);
1117f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
1118f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
1119f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
1120f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
1121d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1122f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, quad
1123f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
1124f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
1125f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
1126f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (index == 2) {
1127f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path1.quadTo(1, .5f, 1, .5f);
1128f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
1129f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
1130f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
1131f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
1132f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
1133d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1134f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, cubic
1135f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
1136f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
1137f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
1138f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (index == 2) {
1139f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path1.cubicTo(1, .5f, 1, .5f, 1, .5f);
1140f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
1141f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
1142f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
1143f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
1144f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
1145f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com}
1146f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com
114756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.comstatic void test_isNestedRects(skiatest::Reporter* reporter) {
114856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    // passing tests (all moveTo / lineTo...
114956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
115056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
115156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
115256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
115356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
115456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
115556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
115656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
115756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
115856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f},
115956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        {1, 0}, {.5f, 0}};
116056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1},
116156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        {0, 1}, {0, .5f}};
116256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};
116356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
116456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}};
116556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
116656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    // failing tests
116756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}}; // too few points
116856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}}; // diagonal
116956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}}; // wraps
117056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}}; // backs up
117156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}}; // end overshoots
117256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}}; // end overshoots
117356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}}; // end overshoots
117456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}}; // 'L'
117556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
117656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    // failing, no close
117756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; // close doesn't match
117856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}}; // ditto
117956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
118056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    size_t testLen[] = {
118156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        sizeof(r1), sizeof(r2), sizeof(r3), sizeof(r4), sizeof(r5), sizeof(r6),
118256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        sizeof(r7), sizeof(r8), sizeof(r9), sizeof(ra), sizeof(rb), sizeof(rc),
118356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        sizeof(rd), sizeof(re),
118456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        sizeof(f1), sizeof(f2), sizeof(f3), sizeof(f4), sizeof(f5), sizeof(f6),
118556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        sizeof(f7), sizeof(f8),
118656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        sizeof(c1), sizeof(c2)
118756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    };
118856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    SkPoint* tests[] = {
118956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re,
119056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        f1, f2, f3, f4, f5, f6, f7, f8,
119156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        c1, c2
119256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    };
119356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    const SkPoint* lastPass = re;
119456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    const SkPoint* lastClose = f8;
119556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    const size_t testCount = sizeof(tests) / sizeof(tests[0]);
119656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    size_t index;
119756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    for (int rectFirst = 0; rectFirst <= 1; ++rectFirst) {
119856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        bool fail = false;
119956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        bool close = true;
120056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        for (size_t testIndex = 0; testIndex < testCount; ++testIndex) {
120156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            SkPath path;
120256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (rectFirst) {
120356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                path.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
120456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
120556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path.moveTo(tests[testIndex][0].fX, tests[testIndex][0].fY);
120656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            for (index = 1; index < testLen[testIndex] / sizeof(SkPoint); ++index) {
120756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                path.lineTo(tests[testIndex][index].fX, tests[testIndex][index].fY);
120856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
120956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (close) {
121056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                path.close();
121156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
121256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (!rectFirst) {
121356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                path.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
121456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
121556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            REPORTER_ASSERT(reporter, fail ^ path.isNestedRects(0));
121656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (!fail) {
121756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                SkRect expected[2], computed[2];
121856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                SkRect testBounds;
121956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                testBounds.set(tests[testIndex], testLen[testIndex] / sizeof(SkPoint));
122056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                expected[0] = SkRect::MakeLTRB(-1, -1, 2, 2);
122156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                expected[1] = testBounds;
122256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                REPORTER_ASSERT(reporter, path.isNestedRects(computed));
122356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                REPORTER_ASSERT(reporter, expected[0] == computed[0]);
122456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                REPORTER_ASSERT(reporter, expected[1] == computed[1]);
122556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
122656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (tests[testIndex] == lastPass) {
122756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                fail = true;
122856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
122956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (tests[testIndex] == lastClose) {
123056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                close = false;
123156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
123256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
123356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
123456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        // fail, close then line
123556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        SkPath path1;
123656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (rectFirst) {
123756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
123856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
123956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.moveTo(r1[0].fX, r1[0].fY);
124056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
124156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.lineTo(r1[index].fX, r1[index].fY);
124256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
124356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.close();
124456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.lineTo(1, 0);
124556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (!rectFirst) {
124656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
124756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
124856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path1.isNestedRects(0));
124956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
125056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        // fail, move in the middle
125156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.reset();
125256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (rectFirst) {
125356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
125456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
125556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.moveTo(r1[0].fX, r1[0].fY);
125656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
125756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (index == 2) {
125856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                path1.moveTo(1, .5f);
125956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
126056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.lineTo(r1[index].fX, r1[index].fY);
126156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
126256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.close();
126356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (!rectFirst) {
126456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
126556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
126656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path1.isNestedRects(0));
126756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
126856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        // fail, move on the edge
126956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.reset();
127056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (rectFirst) {
127156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
127256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
127356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
127456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.moveTo(r1[index - 1].fX, r1[index - 1].fY);
127556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.lineTo(r1[index].fX, r1[index].fY);
127656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
127756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.close();
127856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (!rectFirst) {
127956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
128056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
128156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path1.isNestedRects(0));
128256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
128356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        // fail, quad
128456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.reset();
128556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (rectFirst) {
128656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
128756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
128856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.moveTo(r1[0].fX, r1[0].fY);
128956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
129056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (index == 2) {
129156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                path1.quadTo(1, .5f, 1, .5f);
129256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
129356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.lineTo(r1[index].fX, r1[index].fY);
129456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
129556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.close();
129656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (!rectFirst) {
129756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
129856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
129956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path1.isNestedRects(0));
130056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
130156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        // fail, cubic
130256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.reset();
130356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (rectFirst) {
130456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
130556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
130656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.moveTo(r1[0].fX, r1[0].fY);
130756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
130856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            if (index == 2) {
130956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com                path1.cubicTo(1, .5f, 1, .5f, 1, .5f);
131056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            }
131156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.lineTo(r1[index].fX, r1[index].fY);
131256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
131356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.close();
131456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        if (!rectFirst) {
131556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
131656f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        }
131756f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path1.isNestedRects(0));
13183458716b52aa25dcd1b270141c7628c380696e35skia.committer@gmail.com
131956f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        // fail,  not nested
132056f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.reset();
132156f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.addRect(1, 1, 3, 3, SkPath::kCW_Direction);
132256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        path1.addRect(2, 2, 4, 4, SkPath::kCW_Direction);
132356f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path1.isNestedRects(0));
132456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    }
1325bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com
1326bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    // pass, stroke rect
1327bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPath src, dst;
1328bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    src.addRect(1, 1, 7, 7, SkPath::kCW_Direction);
1329bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    SkPaint strokePaint;
1330bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    strokePaint.setStyle(SkPaint::kStroke_Style);
1331bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    strokePaint.setStrokeWidth(2);
1332bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    strokePaint.getFillPath(src, &dst);
1333bfe90370ea68798b2b9b5ba44142db67d99555e8caryclark@google.com    REPORTER_ASSERT(reporter, dst.isNestedRects(0));
133456f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com}
133556f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com
13362972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.comstatic void write_and_read_back(skiatest::Reporter* reporter,
13372972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com                                const SkPath& p) {
13382972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkWriter32 writer(100);
13392972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    writer.writePath(p);
13402972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    size_t size = writer.size();
13412972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkAutoMalloc storage(size);
13422972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    writer.flatten(storage.get());
13432972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkReader32 reader(storage.get(), size);
13442972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
13452972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkPath readBack;
13462972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, readBack != p);
13472972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    reader.readPath(&readBack);
13482972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, readBack == p);
13492972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
1350d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    REPORTER_ASSERT(reporter, readBack.getConvexityOrUnknown() ==
13512972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com                              p.getConvexityOrUnknown());
13522972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
13532972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, readBack.isOval(NULL) == p.isOval(NULL));
13542972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
13552972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    const SkRect& origBounds = p.getBounds();
13562972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    const SkRect& readBackBounds = readBack.getBounds();
13572972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
13582972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, origBounds == readBackBounds);
13592972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com}
13602972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
136153effc5e327749ea47bc0c678cb45246644600b0reed@google.comstatic void test_flattening(skiatest::Reporter* reporter) {
136253effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkPath p;
136353effc5e327749ea47bc0c678cb45246644600b0reed@google.com
136453effc5e327749ea47bc0c678cb45246644600b0reed@google.com    static const SkPoint pts[] = {
136553effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 },
136653effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(10), SkIntToScalar(10) },
136753effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 },
136853effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }
136953effc5e327749ea47bc0c678cb45246644600b0reed@google.com    };
137053effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.moveTo(pts[0]);
137153effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.lineTo(pts[1]);
137253effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.quadTo(pts[2], pts[3]);
137353effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.cubicTo(pts[4], pts[5], pts[6]);
137453effc5e327749ea47bc0c678cb45246644600b0reed@google.com
13752972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    write_and_read_back(reporter, p);
137694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
137794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    // create a buffer that should be much larger than the path so we don't
137894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    // kill our stack if writer goes too far.
137994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    char buffer[1024];
138094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t size1 = p.writeToMemory(NULL);
138194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t size2 = p.writeToMemory(buffer);
138294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, size1 == size2);
138394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
138494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    SkPath p2;
138594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t size3 = p2.readFromMemory(buffer);
138694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, size1 == size3);
138794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, p == p2);
138894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
138994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    char buffer2[1024];
139094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    size3 = p2.writeToMemory(buffer2);
139194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, size1 == size3);
139294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0);
13932972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
13942972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    // test persistence of the oval flag & convexity
13952972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    {
13962972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        SkPath oval;
13972972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        SkRect rect = SkRect::MakeWH(10, 10);
13982972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        oval.addOval(rect);
13992972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
14002972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        write_and_read_back(reporter, oval);
14012972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    }
140253effc5e327749ea47bc0c678cb45246644600b0reed@google.com}
140353effc5e327749ea47bc0c678cb45246644600b0reed@google.com
140453effc5e327749ea47bc0c678cb45246644600b0reed@google.comstatic void test_transform(skiatest::Reporter* reporter) {
140553effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkPath p, p1;
1406d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
140753effc5e327749ea47bc0c678cb45246644600b0reed@google.com    static const SkPoint pts[] = {
140853effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 },
140953effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(10), SkIntToScalar(10) },
141053effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 },
141153effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }
141253effc5e327749ea47bc0c678cb45246644600b0reed@google.com    };
141353effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.moveTo(pts[0]);
141453effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.lineTo(pts[1]);
141553effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.quadTo(pts[2], pts[3]);
141653effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.cubicTo(pts[4], pts[5], pts[6]);
1417d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
141853effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkMatrix matrix;
141953effc5e327749ea47bc0c678cb45246644600b0reed@google.com    matrix.reset();
142053effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.transform(matrix, &p1);
142153effc5e327749ea47bc0c678cb45246644600b0reed@google.com    REPORTER_ASSERT(reporter, p == p1);
1422d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
142353effc5e327749ea47bc0c678cb45246644600b0reed@google.com    matrix.setScale(SK_Scalar1 * 2, SK_Scalar1 * 3);
142453effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.transform(matrix, &p1);
142553effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkPoint pts1[7];
142653effc5e327749ea47bc0c678cb45246644600b0reed@google.com    int count = p1.getPoints(pts1, 7);
142753effc5e327749ea47bc0c678cb45246644600b0reed@google.com    REPORTER_ASSERT(reporter, 7 == count);
142853effc5e327749ea47bc0c678cb45246644600b0reed@google.com    for (int i = 0; i < count; ++i) {
142953effc5e327749ea47bc0c678cb45246644600b0reed@google.com        SkPoint newPt = SkPoint::Make(pts[i].fX * 2, pts[i].fY * 3);
143053effc5e327749ea47bc0c678cb45246644600b0reed@google.com        REPORTER_ASSERT(reporter, newPt == pts1[i]);
143153effc5e327749ea47bc0c678cb45246644600b0reed@google.com    }
143253effc5e327749ea47bc0c678cb45246644600b0reed@google.com}
143353effc5e327749ea47bc0c678cb45246644600b0reed@google.com
14344da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.orgstatic void test_zero_length_paths(skiatest::Reporter* reporter) {
14356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath  p;
14367e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    uint8_t verbs[32];
14377e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
143856f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    struct SUPPRESS_VISIBILITY_WARNING zeroPathTestData {
14397e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const char* testPath;
14407e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t numResultPts;
14417e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkRect resultBound;
14427e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkPath::Verb* resultVerbs;
14437e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t numResultVerbs;
14447e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
14454da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
14467e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs1[] = { SkPath::kMove_Verb };
14477e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs2[] = { SkPath::kMove_Verb, SkPath::kMove_Verb };
14487e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs3[] = { SkPath::kMove_Verb, SkPath::kClose_Verb };
14497e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs4[] = { SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb };
14507e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs5[] = { SkPath::kMove_Verb, SkPath::kLine_Verb };
14517e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs6[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kMove_Verb, SkPath::kLine_Verb };
14527e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs7[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb };
14537e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs8[] = {
14547e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb
14557e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
14567e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs9[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb };
14577e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs10[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kMove_Verb, SkPath::kQuad_Verb };
14587e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs11[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb };
14597e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs12[] = {
14607e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb
14617e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
14627e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs13[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb };
14637e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs14[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kMove_Verb, SkPath::kCubic_Verb };
14647e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs15[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb };
14657e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs16[] = {
14667e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb
14677e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
14687e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const struct zeroPathTestData gZeroLengthTests[] = {
14697e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "M 1 1", 1, {0, 0, 0, 0}, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1470aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 M 2 1", 2, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs2, SK_ARRAY_COUNT(resultVerbs2) },
14717e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "M 1 1 z", 1, {0, 0, 0, 0}, resultVerbs3, SK_ARRAY_COUNT(resultVerbs3) },
1472aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 z M 2 1 z", 2, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs4, SK_ARRAY_COUNT(resultVerbs4) },
1473aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 L 1 1", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs5, SK_ARRAY_COUNT(resultVerbs5) },
1474aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 L 1 1 M 2 1 L 2 1", 4, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs6, SK_ARRAY_COUNT(resultVerbs6) },
1475aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 L 1 1 z", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs7, SK_ARRAY_COUNT(resultVerbs7) },
1476aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 L 1 1 z M 2 1 L 2 1 z", 4, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs8, SK_ARRAY_COUNT(resultVerbs8) },
1477aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 Q 1 1 1 1", 3, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs9, SK_ARRAY_COUNT(resultVerbs9) },
1478aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 Q 1 1 1 1 M 2 1 Q 2 1 2 1", 6, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs10, SK_ARRAY_COUNT(resultVerbs10) },
1479aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 Q 1 1 1 1 z", 3, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs11, SK_ARRAY_COUNT(resultVerbs11) },
1480aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 Q 1 1 1 1 z M 2 1 Q 2 1 2 1 z", 6, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs12, SK_ARRAY_COUNT(resultVerbs12) },
1481aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 C 1 1 1 1 1 1", 4, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs13, SK_ARRAY_COUNT(resultVerbs13) },
1482aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 C 1 1 1 1 1 1 M 2 1 C 2 1 2 1 2 1", 8, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs14,
14837e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            SK_ARRAY_COUNT(resultVerbs14)
14847e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        },
1485aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 C 1 1 1 1 1 1 z", 4, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs15, SK_ARRAY_COUNT(resultVerbs15) },
1486aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 C 1 1 1 1 1 1 z M 2 1 C 2 1 2 1 2 1 z", 8, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs16,
14877e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            SK_ARRAY_COUNT(resultVerbs16)
14887e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        }
14897e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
14904da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
14917e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(gZeroLengthTests); ++i) {
14927e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        p.reset();
14937e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        bool valid = SkParsePath::FromSVGString(gZeroLengthTests[i].testPath, &p);
14947e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, valid);
14957e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, !p.isEmpty());
14967e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultPts == (size_t)p.countPoints());
14977e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultBound == p.getBounds());
14987e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultVerbs == (size_t)p.getVerbs(verbs, SK_ARRAY_COUNT(verbs)));
14997e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        for (size_t j = 0; j < gZeroLengthTests[i].numResultVerbs; ++j) {
15007e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultVerbs[j] == verbs[j]);
15017e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        }
1502df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    }
15034da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org}
15044da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
15054da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.orgstruct SegmentInfo {
15064da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    SkPath fPath;
15074da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    int    fPointCount;
15084da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org};
15094da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
151010296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com#define kCurveSegmentMask   (SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask)
151110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
15126630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.orgstatic void test_segment_masks(skiatest::Reporter* reporter) {
1513eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    SkPath p, p2;
1514eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com
15156630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(0, 0);
15166630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.quadTo(100, 100, 200, 200);
15176630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, SkPath::kQuad_SegmentMask == p.getSegmentMasks());
15186630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
1519eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    p2 = p;
1520eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
15216630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.cubicTo(100, 100, 200, 200, 300, 300);
15226630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, kCurveSegmentMask == p.getSegmentMasks());
15236630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
1524eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    p2 = p;
1525eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
1526eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com
15276630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.reset();
15286630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(0, 0);
15296630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.cubicTo(100, 100, 200, 200, 300, 300);
15306630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, SkPath::kCubic_SegmentMask == p.getSegmentMasks());
1531eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    p2 = p;
1532eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
1533d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
15346630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
15356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org}
15366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
15376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.orgstatic void test_iter(skiatest::Reporter* reporter) {
15387e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    SkPath  p;
15396630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint pts[4];
15406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
15416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with no path
15426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::Iter noPathIter;
15436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
15447e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
15456630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that setting an empty path works
15466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    noPathIter.setPath(p, false);
15476630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
15487e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
15496630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that close path makes no difference for an empty path
15506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    noPathIter.setPath(p, true);
15516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
15527e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
15536630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with an initial empty path
15546630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::Iter iter(p, false);
15556630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
15566630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
15576630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that close path makes no difference
15587e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    iter.setPath(p, true);
15596630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
15606630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
1561d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
15627e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    struct iterTestData {
15637e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const char* testPath;
15647e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const bool forceClose;
15657e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const bool consumeDegenerates;
15667e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t* numResultPtsPerVerb;
15677e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkPoint* resultPts;
15687e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkPath::Verb* resultVerbs;
15697e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t numResultVerbs;
15707e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
15716630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
15727e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs1[] = { SkPath::kDone_Verb };
15737e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs2[] = {
15747e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kDone_Verb
15757e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
15767e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs3[] = {
15777e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb
15787e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
15797e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs4[] = {
15807e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb
15817e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
15827e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs5[] = {
15837e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb
15847e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
15857e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const size_t resultPtsSizes1[] = { 0 };
1586fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes2[] = { 1, 2, 2, 0 };
1587fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes3[] = { 1, 2, 2, 2, 1, 0 };
1588fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes4[] = { 1, 2, 1, 1, 0 };
1589fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes5[] = { 1, 2, 1, 1, 1, 0 };
1590aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org    static const SkPoint* resultPts1 = 0;
15917e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts2[] = {
15927e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, SK_Scalar1 }, { SK_Scalar1, SK_Scalar1 }, { 0, SK_Scalar1 }
15937e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
15947e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts3[] = {
15957e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, SK_Scalar1 }, { SK_Scalar1, SK_Scalar1 }, { 0, SK_Scalar1 },
15967e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { 0, SK_Scalar1 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }
15977e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
15987e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts4[] = {
15997e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 }
16007e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
16017e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts5[] = {
16027e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 }
16037e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
16047e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const struct iterTestData gIterTests[] = {
16057e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "M 1 0", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1606aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 M 2 0 M 3 0 M 4 0 M 5 0", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1607aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 M 1 0 M 3 0 M 4 0 M 5 0", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
16087e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
16097e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
16107e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "z M 1 0 z z M 2 0 z M 3 0 M 4 0 z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
16117e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "z M 1 0 z z M 2 0 z M 3 0 M 4 0 z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1612aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 1 L 0 1 M 0 0 z", false, true, resultPtsSizes2, resultPts2, resultVerbs2, SK_ARRAY_COUNT(resultVerbs2) },
1613aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 1 L 0 1 M 0 0 z", true, true, resultPtsSizes3, resultPts3, resultVerbs3, SK_ARRAY_COUNT(resultVerbs3) },
1614aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1615aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1616aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", false, false, resultPtsSizes4, resultPts4, resultVerbs4, SK_ARRAY_COUNT(resultVerbs4) },
1617aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", true, false, resultPtsSizes5, resultPts5, resultVerbs5, SK_ARRAY_COUNT(resultVerbs5) }
16187e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
16196630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16207e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(gIterTests); ++i) {
16217e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        p.reset();
16227e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        bool valid = SkParsePath::FromSVGString(gIterTests[i].testPath, &p);
16237e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, valid);
16247e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        iter.setPath(p, gIterTests[i].forceClose);
16257e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        int j = 0, l = 0;
16267e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        do {
16277e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            REPORTER_ASSERT(reporter, iter.next(pts, gIterTests[i].consumeDegenerates) == gIterTests[i].resultVerbs[j]);
16287e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            for (int k = 0; k < (int)gIterTests[i].numResultPtsPerVerb[j]; ++k) {
16297e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org                REPORTER_ASSERT(reporter, pts[k] == gIterTests[i].resultPts[l++]);
16307e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            }
16317e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        } while (gIterTests[i].resultVerbs[j++] != SkPath::kDone_Verb);
16327e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, j == (int)gIterTests[i].numResultVerbs);
16337e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    }
16346630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // The GM degeneratesegments.cpp test is more extensive
16366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org}
16376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16386630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.orgstatic void test_raw_iter(skiatest::Reporter* reporter) {
16396630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath p;
16406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint pts[4];
16416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with no path
16436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::RawIter noPathIter;
16446630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
16456630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that setting an empty path works
16466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    noPathIter.setPath(p);
16476630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
1648d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
16496630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with an initial empty path
16506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::RawIter iter(p);
16516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
16526630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16536630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that a move-only path returns the move.
16546630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1, 0);
16556630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
16566630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
16576630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
16586630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
16596630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
16606630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16616630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // No matter how many moves we add, we should get them all back
16626630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*2, SK_Scalar1);
16636630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*3, SK_Scalar1*2);
16646630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
16656630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
16666630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
16676630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
16686630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
16696630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
16706630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
16716630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
16726630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
16736630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
16746630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
16756630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16766630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Initial close is never ever stored
16776630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.reset();
16786630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
16796630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
16806630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
16816630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
16826630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Move/close sequences
16836630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.reset();
16846630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close(); // Not stored, no purpose
16856630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1, 0);
16866630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
16876630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close(); // Not stored, no purpose
16886630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*2, SK_Scalar1);
16896630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
16906630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*3, SK_Scalar1*2);
16916630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*4, SK_Scalar1*3);
16926630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
16936630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
16946630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
16956630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
16966630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
16976630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
16986630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
16996630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
17006630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
17016630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
17026630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
17036630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
17046630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
17056630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
17066630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
17076630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
17086630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
17096630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
17106630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*4);
17116630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*3);
17126630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
17136630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*4);
17146630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*3);
17156630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
17166630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
17176630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Generate random paths and verify
17186630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint randomPts[25];
17196630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    for (int i = 0; i < 5; ++i) {
17206630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        for (int j = 0; j < 5; ++j) {
17216630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            randomPts[i*5+j].set(SK_Scalar1*i, SK_Scalar1*j);
17226630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        }
17236630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    }
17246630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
17256630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Max of 10 segments, max 3 points per segment
17266630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkRandom rand(9876543);
17276630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint          expectedPts[31]; // May have leading moveTo
1728d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    SkPath::Verb     expectedVerbs[22]; // May have leading moveTo
17296630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::Verb     nextVerb;
1730d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com
17316630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    for (int i = 0; i < 500; ++i) {
17326630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        p.reset();
17336630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        bool lastWasClose = true;
17346630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        bool haveMoveTo = false;
1735d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com        SkPoint lastMoveToPt = { 0, 0 };
17366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numPoints = 0;
17376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numVerbs = (rand.nextU() >> 16) % 10;
17386630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numIterVerbs = 0;
17396630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        for (int j = 0; j < numVerbs; ++j) {
17406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            do {
17416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                nextVerb = static_cast<SkPath::Verb>((rand.nextU() >> 16) % SkPath::kDone_Verb);
17426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            } while (lastWasClose && nextVerb == SkPath::kClose_Verb);
17436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            switch (nextVerb) {
17446630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kMove_Verb:
17456630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
17466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.moveTo(expectedPts[numPoints]);
1747d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                    lastMoveToPt = expectedPts[numPoints];
17486630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 1;
17496630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
17506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    haveMoveTo = true;
17516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
17526630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kLine_Verb:
17536630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    if (!haveMoveTo) {
1754d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                        expectedPts[numPoints++] = lastMoveToPt;
17556630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
17566630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        haveMoveTo = true;
17576630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    }
17586630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
17596630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.lineTo(expectedPts[numPoints]);
17606630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 1;
17616630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
17626630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
17636630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kQuad_Verb:
17646630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    if (!haveMoveTo) {
1765d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                        expectedPts[numPoints++] = lastMoveToPt;
17666630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
17676630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        haveMoveTo = true;
17686630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    }
17696630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
17706630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
17716630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.quadTo(expectedPts[numPoints], expectedPts[numPoints + 1]);
17726630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 2;
17736630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
17746630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
17756630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kCubic_Verb:
17766630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    if (!haveMoveTo) {
1777d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                        expectedPts[numPoints++] = lastMoveToPt;
17786630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
17796630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        haveMoveTo = true;
17806630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    }
17816630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
17826630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
17836630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints + 2] = randomPts[(rand.nextU() >> 16) % 25];
17846630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.cubicTo(expectedPts[numPoints], expectedPts[numPoints + 1],
17856630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                              expectedPts[numPoints + 2]);
17866630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 3;
17876630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
17886630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
17896630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kClose_Verb:
17906630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.close();
1791d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                    haveMoveTo = false;
17926630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = true;
17936630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
17946630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                default:;
17956630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            }
17966630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            expectedVerbs[numIterVerbs++] = nextVerb;
17976630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        }
1798d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
17996630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        iter.setPath(p);
18006630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        numVerbs = numIterVerbs;
18016630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        numIterVerbs = 0;
18026630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numIterPts = 0;
18036630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        SkPoint lastMoveTo;
18046630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        SkPoint lastPt;
18056630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        lastMoveTo.set(0, 0);
18066630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        lastPt.set(0, 0);
18076630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        while ((nextVerb = iter.next(pts)) != SkPath::kDone_Verb) {
18086630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            REPORTER_ASSERT(reporter, nextVerb == expectedVerbs[numIterVerbs]);
18096630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            numIterVerbs++;
18106630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            switch (nextVerb) {
18116630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kMove_Verb:
18126630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints);
18136630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == expectedPts[numIterPts]);
18146630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = lastMoveTo = pts[0];
18156630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 1;
18166630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
18176630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kLine_Verb:
18186630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 1);
18196630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
18206630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
18216630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = pts[1];
18226630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 1;
18236630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
18246630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kQuad_Verb:
18256630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 2);
18266630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
18276630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
18286630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
18296630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = pts[2];
18306630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 2;
18316630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
18326630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kCubic_Verb:
18336630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 3);
18346630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
18356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
18366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
18376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[3] == expectedPts[numIterPts + 2]);
18386630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = pts[3];
18396630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 3;
18406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
18416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kClose_Verb:
18426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastMoveTo);
18436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = lastMoveTo;
18446630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
18456630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                default:;
18466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            }
18476630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        }
18486630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        REPORTER_ASSERT(reporter, numIterPts == numPoints);
18496630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        REPORTER_ASSERT(reporter, numIterVerbs == numVerbs);
18506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    }
18516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org}
18526630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
18536aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void check_for_circle(skiatest::Reporter* reporter,
185430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                             const SkPath& path,
185530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                             bool expectedCircle,
185630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                             SkPath::Direction expectedDir) {
18576aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkRect rect;
185830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(&rect) == expectedCircle);
185930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    REPORTER_ASSERT(reporter, path.cheapIsDirection(expectedDir));
1860fbb0ed959de64f16d236d2f0d81ddf5cb318e1feskia.committer@gmail.com
186130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    if (expectedCircle) {
18626aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        REPORTER_ASSERT(reporter, rect.height() == rect.width());
18636aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    }
18646aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
18656aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
18666aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_skew(skiatest::Reporter* reporter,
186730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                             const SkPath& path,
186830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                             SkPath::Direction dir) {
18696aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath tmp;
18706aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
18716aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix m;
18726aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setSkew(SkIntToScalar(3), SkIntToScalar(5));
18736aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
187430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    // this matrix reverses the direction.
187530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    if (SkPath::kCCW_Direction == dir) {
187630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        dir = SkPath::kCW_Direction;
187730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    } else {
187830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        SkASSERT(SkPath::kCW_Direction == dir);
187930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        dir = SkPath::kCCW_Direction;
188030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    }
188130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, tmp, false, dir);
18826aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
18836aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
18846aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_translate(skiatest::Reporter* reporter,
188530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                  const SkPath& path,
188630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                  SkPath::Direction dir) {
18876aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath tmp;
18886aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
18896aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // translate at small offset
18906aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix m;
18916aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setTranslate(SkIntToScalar(15), SkIntToScalar(15));
18926aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
189330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, tmp, true, dir);
18946aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
18956aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
18966aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.reset();
18976aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
18986aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // translate at a relatively big offset
18996aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setTranslate(SkIntToScalar(1000), SkIntToScalar(1000));
19006aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
190130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, tmp, true, dir);
19026aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
19036aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
19046aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_rotate(skiatest::Reporter* reporter,
190530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                               const SkPath& path,
190630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                               SkPath::Direction dir) {
19076aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    for (int angle = 0; angle < 360; ++angle) {
19086aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        SkPath tmp;
19096aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        SkMatrix m;
19106aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        m.setRotate(SkIntToScalar(angle));
19116aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        path.transform(m, &tmp);
19126aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
191330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        // TODO: a rotated circle whose rotated angle is not a multiple of 90
19146aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        // degrees is not an oval anymore, this can be improved.  we made this
19156aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        // for the simplicity of our implementation.
19166aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        if (angle % 90 == 0) {
191730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com            check_for_circle(reporter, tmp, true, dir);
19186aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        } else {
191930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com            check_for_circle(reporter, tmp, false, dir);
19206aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        }
19216aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    }
19226aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
19236aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
192430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.comstatic void test_circle_mirror_x(skiatest::Reporter* reporter,
192530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                 const SkPath& path,
192630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                 SkPath::Direction dir) {
192730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkPath tmp;
192830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkMatrix m;
192930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    m.reset();
193030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    m.setScaleX(-SK_Scalar1);
193130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    path.transform(m, &tmp);
193230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
193330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    if (SkPath::kCW_Direction == dir) {
193430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        dir = SkPath::kCCW_Direction;
193530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    } else {
193630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        SkASSERT(SkPath::kCCW_Direction == dir);
193730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        dir = SkPath::kCW_Direction;
193830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    }
193930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
194030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, tmp, true, dir);
194130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com}
194230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
194330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.comstatic void test_circle_mirror_y(skiatest::Reporter* reporter,
194430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                 const SkPath& path,
194530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                 SkPath::Direction dir) {
194630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkPath tmp;
194730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkMatrix m;
194830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    m.reset();
194930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    m.setScaleY(-SK_Scalar1);
195030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    path.transform(m, &tmp);
195130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
195230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    if (SkPath::kCW_Direction == dir) {
195330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        dir = SkPath::kCCW_Direction;
195430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    } else {
195530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        SkASSERT(SkPath::kCCW_Direction == dir);
195630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com        dir = SkPath::kCW_Direction;
195730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    }
195830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
195930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, tmp, true, dir);
196030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com}
196130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
196230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.comstatic void test_circle_mirror_xy(skiatest::Reporter* reporter,
196330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                 const SkPath& path,
196430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com                                 SkPath::Direction dir) {
196530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkPath tmp;
196630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    SkMatrix m;
196730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    m.reset();
196830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    m.setScaleX(-SK_Scalar1);
196930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    m.setScaleY(-SK_Scalar1);
197030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    path.transform(m, &tmp);
197130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
197230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, tmp, true, dir);
197330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com}
197430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
19756aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_with_direction(skiatest::Reporter* reporter,
19766aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                                       SkPath::Direction dir) {
19776aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
19786aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
19796aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // circle at origin
19806aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(20), dir);
198130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, true, dir);
198230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_rotate(reporter, path, dir);
198330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_translate(reporter, path, dir);
198430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_skew(reporter, path, dir);
19856aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
19866aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // circle at an offset at (10, 10)
19876aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
19886aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(SkIntToScalar(10), SkIntToScalar(10),
19896aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                   SkIntToScalar(20), dir);
199030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, true, dir);
199130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_rotate(reporter, path, dir);
199230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_translate(reporter, path, dir);
199330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_skew(reporter, path, dir);
199430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_mirror_x(reporter, path, dir);
199530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_mirror_y(reporter, path, dir);
199630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    test_circle_mirror_xy(reporter, path, dir);
19976aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
19986aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
19996aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_with_add_paths(skiatest::Reporter* reporter) {
20006aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
20016aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath circle;
20026aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath rect;
20036aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath empty;
20046aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
200530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    static const SkPath::Direction kCircleDir = SkPath::kCW_Direction;
200630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    static const SkPath::Direction kCircleDirOpposite = SkPath::kCCW_Direction;
200730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com
200830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    circle.addCircle(0, 0, SkIntToScalar(10), kCircleDir);
20096aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    rect.addRect(SkIntToScalar(5), SkIntToScalar(5),
20106aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                 SkIntToScalar(20), SkIntToScalar(20), SkPath::kCW_Direction);
20116aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20126aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix translate;
20136aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    translate.setTranslate(SkIntToScalar(12), SkIntToScalar(12));
20146aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20156aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // For simplicity, all the path concatenation related operations
20166aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // would mark it non-circle, though in theory it's still a circle.
20176aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20186aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // empty + circle (translate)
20196aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = empty;
20206aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addPath(circle, translate);
202130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, false, kCircleDir);
20226aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20236aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // circle + empty (translate)
20246aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = circle;
20256aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addPath(empty, translate);
202630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, false, kCircleDir);
20276aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20286aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // test reverseAddPath
20296aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = circle;
20306aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reverseAddPath(rect);
203130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, false, kCircleDirOpposite);
20326aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
20336aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20346aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle(skiatest::Reporter* reporter) {
20356aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_with_direction(reporter, SkPath::kCW_Direction);
20366aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_with_direction(reporter, SkPath::kCCW_Direction);
20376aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20386aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // multiple addCircle()
20396aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
20406aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
20416aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(20), SkPath::kCW_Direction);
204230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, false, SkPath::kCW_Direction);
20436aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20446aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // some extra lineTo() would make isOval() fail
20456aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
20466aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
20476aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.lineTo(0, 0);
204830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, false, SkPath::kCW_Direction);
20496aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20506aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // not back to the original point
20516aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
20526aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
20536aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.setLastPt(SkIntToScalar(5), SkIntToScalar(5));
205430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com    check_for_circle(reporter, path, false, SkPath::kCW_Direction);
20556aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20566aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_with_add_paths(reporter);
20576aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
20586aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20596aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_oval(skiatest::Reporter* reporter) {
20606aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkRect rect;
20616aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix m;
20626aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
20636aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20646aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    rect = SkRect::MakeWH(SkIntToScalar(30), SkIntToScalar(50));
20656aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addOval(rect);
20666aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20676aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(NULL));
20686aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20696aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setRotate(SkIntToScalar(90));
20706aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath tmp;
20716aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
20726aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // an oval rotated 90 degrees is still an oval.
20736aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, tmp.isOval(NULL));
20746aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20756aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.reset();
20766aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setRotate(SkIntToScalar(30));
20776aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
20786aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
20796aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // an oval rotated 30 degrees is not an oval anymore.
20806aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
20816aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20826aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // since empty path being transformed.
20836aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
20846aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
20856aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.reset();
20866aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
20876aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
20886aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20896aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // empty path is not an oval
20906aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
20916aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
20926aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20936aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // only has moveTo()s
20946aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
20956aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.moveTo(0, 0);
20966aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.moveTo(SkIntToScalar(10), SkIntToScalar(10));
20976aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
20986aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
20996aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // mimic WebKit's calling convention,
21006aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // call moveTo() first and then call addOval()
21016aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
21026aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.moveTo(0, 0);
21036aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addOval(rect);
21046aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(NULL));
21056aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
21066aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // copy path
21076aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
21086aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
21096aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.addOval(rect);
21106aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = tmp;
21116aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(NULL));
21126aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
21136aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
211442639cddc33746b351bbf07c540711eefffe191acaryclark@google.comstatic void TestPath(skiatest::Reporter* reporter) {
211560bc6d5cb0af7cef0e49cc35f28f36f89b10853ereed@android.com    SkTSize<SkScalar>::Make(3,4);
211660bc6d5cb0af7cef0e49cc35f28f36f89b10853ereed@android.com
21173abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    SkPath  p, p2;
21183abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    SkRect  bounds, bounds2;
211980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
21203abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.isEmpty());
21214da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, 0 == p.countPoints());
2122df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, 0 == p.countVerbs());
212310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
2124b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    REPORTER_ASSERT(reporter, p.isConvex());
21253abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType);
21263abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !p.isInverseFillType());
21273abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p == p2);
21283abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !(p != p2));
21293abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
2130d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    REPORTER_ASSERT(reporter, p.getBounds().isEmpty());
213180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
21323abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds.set(0, 0, SK_Scalar1, SK_Scalar1);
21336b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
21346b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1);
21356b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    check_convex_bounds(reporter, p, bounds);
213610296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    // we have quads or cubics
213710296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, p.getSegmentMasks() & kCurveSegmentMask);
21384da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
213962047cf1980861234e7367a225928b84ce492c68reed@google.com
21406b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.reset();
214110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
21424da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, p.isEmpty());
214310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
21446b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.addOval(bounds);
21456b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    check_convex_bounds(reporter, p, bounds);
21464da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
214762047cf1980861234e7367a225928b84ce492c68reed@google.com
21486b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.reset();
21493abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    p.addRect(bounds);
21506b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    check_convex_bounds(reporter, p, bounds);
215110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    // we have only lines
215210296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_SegmentMask == p.getSegmentMasks());
21534da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
21543abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
21553abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p != p2);
21563abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !(p == p2));
21573abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
2158df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    // do getPoints and getVerbs return the right result
2159df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, p.getPoints(NULL, 0) == 4);
2160df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, p.getVerbs(NULL, 0) == 5);
21613abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    SkPoint pts[4];
21623abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    int count = p.getPoints(pts, 4);
21633abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, count == 4);
2164df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    uint8_t verbs[6];
2165df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    verbs[5] = 0xff;
2166df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    p.getVerbs(verbs, 5);
2167df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]);
2168df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[1]);
2169df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[2]);
2170df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[3]);
2171df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[4]);
2172df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, 0xff == verbs[5]);
21733abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds2.set(pts, 4);
21743abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, bounds == bounds2);
217580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
21763abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds.offset(SK_Scalar1*3, SK_Scalar1*4);
21773abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    p.offset(SK_Scalar1*3, SK_Scalar1*4);
2178d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    REPORTER_ASSERT(reporter, bounds == p.getBounds());
21793abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
21803abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.isRect(NULL));
2181f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    bounds2.setEmpty();
21823abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.isRect(&bounds2));
21833abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, bounds == bounds2);
218480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
21853abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    // now force p to not be a rect
21863abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds.set(0, 0, SK_Scalar1/2, SK_Scalar1/2);
21873abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    p.addRect(bounds);
21883abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !p.isRect(NULL));
21893abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
21907e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    test_isLine(reporter);
21917e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    test_isRect(reporter);
219256f233ab54d228f3ce05d0f7e15996424f9d5dd2caryclark@google.com    test_isNestedRects(reporter);
21934da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    test_zero_length_paths(reporter);
2194cabaf1daf3fdcc151c12d59b05bdbe136c178b3breed@google.com    test_direction(reporter);
219504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    test_convexity(reporter);
21967c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    test_convexity2(reporter);
21979bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com    test_conservativelyContains(reporter);
2198b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    test_close(reporter);
21996630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    test_segment_masks(reporter);
220053effc5e327749ea47bc0c678cb45246644600b0reed@google.com    test_flattening(reporter);
220153effc5e327749ea47bc0c678cb45246644600b0reed@google.com    test_transform(reporter);
22023563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com    test_bounds(reporter);
22036630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    test_iter(reporter);
22046630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    test_raw_iter(reporter);
22056aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle(reporter);
22066aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_oval(reporter);
22078b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    test_strokerec(reporter);
2208744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    test_addPoly(reporter);
22090bb18bb264b26afca45452910437c09445e23a3creed@google.com    test_isfinite(reporter);
2210ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    test_isfinite_after_transform(reporter);
22118cae8358f78b81539f1006afe592a37f1604e67creed@google.com    test_tricky_cubic(reporter);
2212b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    test_arb_round_rect_is_convex(reporter);
2213158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    test_arb_zero_rad_round_rect_is_rect(reporter);
2214a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    test_addrect_isfinite(reporter);
22153abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com}
22163abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
22173abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com#include "TestClassDef.h"
22183abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.comDEFINE_TESTCLASS("Path", PathTestClass, TestPath)
2219