PathTest.cpp revision a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2dd
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
218cae8358f78b81539f1006afe592a37f1604e67creed@google.comstatic SkSurface* new_surface(int w, int h) {
228cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkImage::Info info = {
238cae8358f78b81539f1006afe592a37f1604e67creed@google.com        w, h, SkImage::kPMColor_ColorType, SkImage::kPremul_AlphaType
248cae8358f78b81539f1006afe592a37f1604e67creed@google.com    };
258cae8358f78b81539f1006afe592a37f1604e67creed@google.com    return SkSurface::NewRaster(info, NULL);
268cae8358f78b81539f1006afe592a37f1604e67creed@google.com}
278cae8358f78b81539f1006afe592a37f1604e67creed@google.com
28a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com// Make sure we stay non-finite once we get there (unless we reset or rewind).
29a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.comstatic void test_addrect_isfinite(skiatest::Reporter* reporter) {
30a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    SkPath path;
31a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
32a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.addRect(SkRect::MakeWH(50, 100));
33a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
34a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
35a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.moveTo(0, 0);
36a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.lineTo(SK_ScalarInfinity, 42);
37a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
38a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
39a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.addRect(SkRect::MakeWH(50, 100));
40a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
41a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com
42a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    path.reset();
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
498cae8358f78b81539f1006afe592a37f1604e67creed@google.com// Inspired by http://ie.microsoft.com/testdrive/Performance/Chalkboard/
508cae8358f78b81539f1006afe592a37f1604e67creed@google.com// which triggered an assert, from a tricky cubic. This test replicates that
518cae8358f78b81539f1006afe592a37f1604e67creed@google.com// example, so we can ensure that we handle it (in SkEdge.cpp), and don't
528cae8358f78b81539f1006afe592a37f1604e67creed@google.com// assert in the SK_DEBUG build.
538cae8358f78b81539f1006afe592a37f1604e67creed@google.comstatic void test_tricky_cubic(skiatest::Reporter* reporter) {
548cae8358f78b81539f1006afe592a37f1604e67creed@google.com    const SkPoint pts[] = {
55055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.8943768),    SkDoubleToScalar(129.121277) },
56055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.8937435),    SkDoubleToScalar(129.121689) },
57055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.8950119),    SkDoubleToScalar(129.120422) },
58055c7c299cb47eebd360b809ad58a0006e2e55f7skia.committer@gmail.com        { SkDoubleToScalar(18.5030727),    SkDoubleToScalar(129.13121)  },
598cae8358f78b81539f1006afe592a37f1604e67creed@google.com    };
608cae8358f78b81539f1006afe592a37f1604e67creed@google.com
618cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkPath path;
628cae8358f78b81539f1006afe592a37f1604e67creed@google.com    path.moveTo(pts[0]);
638cae8358f78b81539f1006afe592a37f1604e67creed@google.com    path.cubicTo(pts[1], pts[2], pts[3]);
648cae8358f78b81539f1006afe592a37f1604e67creed@google.com
658cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkPaint paint;
668cae8358f78b81539f1006afe592a37f1604e67creed@google.com    paint.setAntiAlias(true);
678cae8358f78b81539f1006afe592a37f1604e67creed@google.com
688cae8358f78b81539f1006afe592a37f1604e67creed@google.com    SkSurface* surface = new_surface(19, 130);
698cae8358f78b81539f1006afe592a37f1604e67creed@google.com    surface->getCanvas()->drawPath(path, paint);
708cae8358f78b81539f1006afe592a37f1604e67creed@google.com    surface->unref();
718cae8358f78b81539f1006afe592a37f1604e67creed@google.com}
723abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
73ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com// Inspired by http://code.google.com/p/chromium/issues/detail?id=141651
74ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com//
75ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.comstatic void test_isfinite_after_transform(skiatest::Reporter* reporter) {
76ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    SkPath path;
77ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    path.quadTo(157, 366, 286, 208);
78ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    path.arcTo(37, 442, 315, 163, 957494590897113.0f);
79d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
80ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    SkMatrix matrix;
81ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    matrix.setScale(1000*1000, 1000*1000);
82ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com
83ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // Be sure that path::transform correctly updates isFinite and the bounds
84ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // if the transformation overflows. The previous bug was that isFinite was
85ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // set to true in this case, but the bounds were not set to empty (which
86ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // they should be).
87ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    while (path.isFinite()) {
88ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com        REPORTER_ASSERT(reporter, path.getBounds().isFinite());
89ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com        REPORTER_ASSERT(reporter, !path.getBounds().isEmpty());
90ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com        path.transform(matrix);
91ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    }
92ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    REPORTER_ASSERT(reporter, path.getBounds().isEmpty());
93ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com
94ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    matrix.setTranslate(SK_Scalar1, SK_Scalar1);
95ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    path.transform(matrix);
96ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    // we need to still be non-finite
97ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
98ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    REPORTER_ASSERT(reporter, path.getBounds().isEmpty());
99ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com}
100ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com
1016a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.comstatic void add_corner_arc(SkPath* path, const SkRect& rect,
1026a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.com                           SkScalar xIn, SkScalar yIn,
103b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com                           int startAngle)
104b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com{
105b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
106b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkScalar rx = SkMinScalar(rect.width(), xIn);
107b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkScalar ry = SkMinScalar(rect.height(), yIn);
108b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
109b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkRect arcRect;
110b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    arcRect.set(-rx, -ry, rx, ry);
111b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    switch (startAngle) {
112b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 0:
113b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
114b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
115b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 90:
116b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
117b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
118b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 180:
119b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
120b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
121b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    case 270:
122b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
123b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
124b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    default:
125b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        break;
126b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    }
127b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
128b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
129b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com}
130b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
1316a748ad8d82576c4ce59e9b2409d41a93bf05cdfskia.committer@gmail.comstatic void make_arb_round_rect(SkPath* path, const SkRect& r,
132b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com                                SkScalar xCorner, SkScalar yCorner) {
133b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    // we are lazy here and use the same x & y for each corner
134b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 270);
135b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 0);
136b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 90);
137b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    add_corner_arc(path, r, xCorner, yCorner, 180);
138158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    path->close();
139b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com}
140b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
141b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// Chrome creates its own round rects with each corner possibly being different.
142b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// Performance will suffer if they are not convex.
143b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// Note: PathBench::ArbRoundRectBench performs almost exactly
144b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com// the same test (but with drawing)
145b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.comstatic void test_arb_round_rect_is_convex(skiatest::Reporter* reporter) {
146b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkRandom rand;
147b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    SkRect r;
148b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
149b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    for (int i = 0; i < 5000; ++i) {
150b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
151158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkScalar size = rand.nextUScalar1() * 30;
152158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        if (size < SK_Scalar1) {
153b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com            continue;
154b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        }
155b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        r.fLeft = rand.nextUScalar1() * 300;
156b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        r.fTop =  rand.nextUScalar1() * 300;
157158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fRight =  r.fLeft + 2 * size;
158158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fBottom = r.fTop + 2 * size;
159b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
160b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        SkPath temp;
161b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
162b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
163b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
164c7a37c7bb2279d8c15d6fcbaf38f59dbd727eb6crobertphillips@google.com#ifdef SK_REDEFINE_ROOT2OVER2_TO_MAKE_ARCTOS_CONVEX
165b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com        REPORTER_ASSERT(reporter, temp.isConvex());
166c7a37c7bb2279d8c15d6fcbaf38f59dbd727eb6crobertphillips@google.com#endif
167b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    }
168b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com}
169b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com
170158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// Chrome will sometimes create a 0 radius round rect. The degenerate
171158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// quads prevent the path from being converted to a rect
172158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// Note: PathBench::ArbRoundRectBench performs almost exactly
173158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com// the same test (but with drawing)
174158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.comstatic void test_arb_zero_rad_round_rect_is_rect(skiatest::Reporter* reporter) {
175158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    SkRandom rand;
176158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    SkRect r;
177158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
178158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    for (int i = 0; i < 5000; ++i) {
179158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
180158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkScalar size = rand.nextUScalar1() * 30;
181158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        if (size < SK_Scalar1) {
182158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com            continue;
183158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        }
184158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fLeft = rand.nextUScalar1() * 300;
185158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fTop =  rand.nextUScalar1() * 300;
186158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fRight =  r.fLeft + 2 * size;
187158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        r.fBottom = r.fTop + 2 * size;
188158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
189158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkPath temp;
190158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
191158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        make_arb_round_rect(&temp, r, 0, 0);
192158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
193158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com#ifdef SK_REDEFINE_ROOT2OVER2_TO_MAKE_ARCTOS_CONVEX
194158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        SkRect result;
195158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        REPORTER_ASSERT(reporter, temp.isRect(&result));
196158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com        REPORTER_ASSERT(reporter, r == result);
197158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com#endif
198158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    }
199158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com}
200158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com
2010bb18bb264b26afca45452910437c09445e23a3creed@google.comstatic void test_rect_isfinite(skiatest::Reporter* reporter) {
2020bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar inf = SK_ScalarInfinity;
2030bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar nan = SK_ScalarNaN;
204d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2050bb18bb264b26afca45452910437c09445e23a3creed@google.com    SkRect r;
2060bb18bb264b26afca45452910437c09445e23a3creed@google.com    r.setEmpty();
2070bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, r.isFinite());
2080bb18bb264b26afca45452910437c09445e23a3creed@google.com    r.set(0, 0, inf, -inf);
2090bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !r.isFinite());
2100bb18bb264b26afca45452910437c09445e23a3creed@google.com    r.set(0, 0, nan, 0);
2110bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !r.isFinite());
212d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2130bb18bb264b26afca45452910437c09445e23a3creed@google.com    SkPoint pts[] = {
2140bb18bb264b26afca45452910437c09445e23a3creed@google.com        { 0, 0 },
2150bb18bb264b26afca45452910437c09445e23a3creed@google.com        { SK_Scalar1, 0 },
2160bb18bb264b26afca45452910437c09445e23a3creed@google.com        { 0, SK_Scalar1 },
2170bb18bb264b26afca45452910437c09445e23a3creed@google.com    };
218d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2190bb18bb264b26afca45452910437c09445e23a3creed@google.com    bool isFine = r.setBoundsCheck(pts, 3);
2200bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, isFine);
2210bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !r.isEmpty());
222d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2230bb18bb264b26afca45452910437c09445e23a3creed@google.com    pts[1].set(inf, 0);
2240bb18bb264b26afca45452910437c09445e23a3creed@google.com    isFine = r.setBoundsCheck(pts, 3);
2250bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !isFine);
2260bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, r.isEmpty());
227d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2280bb18bb264b26afca45452910437c09445e23a3creed@google.com    pts[1].set(nan, 0);
2290bb18bb264b26afca45452910437c09445e23a3creed@google.com    isFine = r.setBoundsCheck(pts, 3);
2300bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !isFine);
2310bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, r.isEmpty());
2320bb18bb264b26afca45452910437c09445e23a3creed@google.com}
2330bb18bb264b26afca45452910437c09445e23a3creed@google.com
2340bb18bb264b26afca45452910437c09445e23a3creed@google.comstatic void test_path_isfinite(skiatest::Reporter* reporter) {
2350bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar inf = SK_ScalarInfinity;
2360bb18bb264b26afca45452910437c09445e23a3creed@google.com    const SkScalar nan = SK_ScalarNaN;
237d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2380bb18bb264b26afca45452910437c09445e23a3creed@google.com    SkPath path;
2390bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
2400bb18bb264b26afca45452910437c09445e23a3creed@google.com
2410bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2420bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
2430bb18bb264b26afca45452910437c09445e23a3creed@google.com
2440bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2450bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.moveTo(SK_Scalar1, 0);
2460bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, path.isFinite());
2470bb18bb264b26afca45452910437c09445e23a3creed@google.com
2480bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2490bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.moveTo(inf, -inf);
2500bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
2510bb18bb264b26afca45452910437c09445e23a3creed@google.com
2520bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.reset();
2530bb18bb264b26afca45452910437c09445e23a3creed@google.com    path.moveTo(nan, 0);
2540bb18bb264b26afca45452910437c09445e23a3creed@google.com    REPORTER_ASSERT(reporter, !path.isFinite());
2550bb18bb264b26afca45452910437c09445e23a3creed@google.com}
2560bb18bb264b26afca45452910437c09445e23a3creed@google.com
2570bb18bb264b26afca45452910437c09445e23a3creed@google.comstatic void test_isfinite(skiatest::Reporter* reporter) {
2580bb18bb264b26afca45452910437c09445e23a3creed@google.com    test_rect_isfinite(reporter);
2590bb18bb264b26afca45452910437c09445e23a3creed@google.com    test_path_isfinite(reporter);
2600bb18bb264b26afca45452910437c09445e23a3creed@google.com}
2610bb18bb264b26afca45452910437c09445e23a3creed@google.com
262744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com// assert that we always
263744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  start with a moveTo
264744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  only have 1 moveTo
265744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  only have Lines after that
266744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  end with a single close
267744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//  only have (at most) 1 close
268744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com//
269744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.comstatic void test_poly(skiatest::Reporter* reporter, const SkPath& path,
270744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                      const SkPoint srcPts[], int count, bool expectClose) {
271744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkPath::RawIter iter(path);
272744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkPoint         pts[4];
273744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
274744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    bool firstTime = true;
275744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    bool foundClose = false;
276744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    for (;;) {
277744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        switch (iter.next(pts)) {
278744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kMove_Verb:
279744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, firstTime);
280744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, pts[0] == srcPts[0]);
281744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                srcPts++;
282744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                firstTime = false;
283744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
284744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kLine_Verb:
285744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !firstTime);
286744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, pts[1] == srcPts[0]);
287744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                srcPts++;
288744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
289744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kQuad_Verb:
290744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !"unexpected quad verb");
291744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
292744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kCubic_Verb:
293744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !"unexpected cubic verb");
294744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
295744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kClose_Verb:
296744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !firstTime);
297744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, !foundClose);
298744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                REPORTER_ASSERT(reporter, expectClose);
299744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                foundClose = true;
300744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                break;
301744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            case SkPath::kDone_Verb:
302744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com                goto DONE;
303744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        }
304744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    }
305744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.comDONE:
306744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    REPORTER_ASSERT(reporter, foundClose == expectClose);
307744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com}
308744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
309744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.comstatic void test_addPoly(skiatest::Reporter* reporter) {
310744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkPoint pts[32];
311744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    SkRandom rand;
312d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
313744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(pts); ++i) {
314744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        pts[i].fX = rand.nextSScalar1();
315744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        pts[i].fY = rand.nextSScalar1();
316744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    }
317744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
318744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    for (int doClose = 0; doClose <= 1; ++doClose) {
319744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        for (size_t count = 1; count <= SK_ARRAY_COUNT(pts); ++count) {
320744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            SkPath path;
321744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            path.addPoly(pts, count, SkToBool(doClose));
322744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com            test_poly(reporter, path, pts, count, SkToBool(doClose));
323744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com        }
324744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    }
325744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com}
326744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
3278b06f1a7ff6d5a59387a90433064550de20787eereed@google.comstatic void test_strokerec(skiatest::Reporter* reporter) {
3288b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
3298b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, rec.isFillStyle());
330d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3318b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setHairlineStyle();
3328b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, rec.isHairlineStyle());
333d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3348b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(SK_Scalar1, false);
3358b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kStroke_Style == rec.getStyle());
336d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3378b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(SK_Scalar1, true);
3388b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kStrokeAndFill_Style == rec.getStyle());
339d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3408b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(0, false);
3418b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kHairline_Style == rec.getStyle());
342d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3438b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    rec.setStrokeStyle(0, true);
3448b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    REPORTER_ASSERT(reporter, SkStrokeRec::kFill_Style == rec.getStyle());
3458b06f1a7ff6d5a59387a90433064550de20787eereed@google.com}
3468b06f1a7ff6d5a59387a90433064550de20787eereed@google.com
347f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com/**
348f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com * cheapIsDirection can take a shortcut when a path is marked convex.
349f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com * This function ensures that we always test cheapIsDirection when the path
350f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com * is flagged with unknown convexity status.
351f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com */
352f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.comstatic void check_direction(SkPath* path,
353f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com                            SkPath::Direction expectedDir,
354f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com                            skiatest::Reporter* reporter) {
355f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    if (SkPath::kConvex_Convexity == path->getConvexity()) {
356f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com        REPORTER_ASSERT(reporter, path->cheapIsDirection(expectedDir));
357f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com        path->setConvexity(SkPath::kUnknown_Convexity);
358f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    }
359f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    REPORTER_ASSERT(reporter, path->cheapIsDirection(expectedDir));
360f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com}
361f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com
3623e71a887628ff25c806675366b081c70bb10b74dreed@google.comstatic void test_direction(skiatest::Reporter* reporter) {
3633e71a887628ff25c806675366b081c70bb10b74dreed@google.com    size_t i;
3643e71a887628ff25c806675366b081c70bb10b74dreed@google.com    SkPath path;
3653e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, !path.cheapComputeDirection(NULL));
3663e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCW_Direction));
3673e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCCW_Direction));
3683e71a887628ff25c806675366b081c70bb10b74dreed@google.com
3693e71a887628ff25c806675366b081c70bb10b74dreed@google.com    static const char* gDegen[] = {
3703e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10",
3713e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 M 20 20",
3723e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 L 20 20",
3733e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 L 10 10 L 10 10",
3743e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 Q 10 10 10 10",
3753e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 C 10 10 10 10 10 10",
3763e71a887628ff25c806675366b081c70bb10b74dreed@google.com    };
3773e71a887628ff25c806675366b081c70bb10b74dreed@google.com    for (i = 0; i < SK_ARRAY_COUNT(gDegen); ++i) {
3783e71a887628ff25c806675366b081c70bb10b74dreed@google.com        path.reset();
3793e71a887628ff25c806675366b081c70bb10b74dreed@google.com        bool valid = SkParsePath::FromSVGString(gDegen[i], &path);
3803e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, valid);
3813e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, !path.cheapComputeDirection(NULL));
3823e71a887628ff25c806675366b081c70bb10b74dreed@google.com    }
383d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3843e71a887628ff25c806675366b081c70bb10b74dreed@google.com    static const char* gCW[] = {
385cabaf1daf3fdcc151c12d59b05bdbe136c178b3breed@google.com        "M 10 10 L 10 10 Q 20 10 20 20",
3863e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 C 20 10 20 20 20 20",
387d414666d18fa9dca1cb310bc66c574aac3d79b72reed@google.com        "M 20 10 Q 20 20 30 20 L 10 20", // test double-back at y-max
3884eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // rect with top two corners replaced by cubics with identical middle
3894eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // control points
3904eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        "M 10 10 C 10 0 10 0 20 0 L 40 0 C 50 0 50 0 50 10"
3913e71a887628ff25c806675366b081c70bb10b74dreed@google.com    };
3923e71a887628ff25c806675366b081c70bb10b74dreed@google.com    for (i = 0; i < SK_ARRAY_COUNT(gCW); ++i) {
3933e71a887628ff25c806675366b081c70bb10b74dreed@google.com        path.reset();
3943e71a887628ff25c806675366b081c70bb10b74dreed@google.com        bool valid = SkParsePath::FromSVGString(gCW[i], &path);
3953e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, valid);
396f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com        check_direction(&path, SkPath::kCW_Direction, reporter);
3973e71a887628ff25c806675366b081c70bb10b74dreed@google.com    }
398d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3993e71a887628ff25c806675366b081c70bb10b74dreed@google.com    static const char* gCCW[] = {
400cabaf1daf3fdcc151c12d59b05bdbe136c178b3breed@google.com        "M 10 10 L 10 10 Q 20 10 20 -20",
4013e71a887628ff25c806675366b081c70bb10b74dreed@google.com        "M 10 10 C 20 10 20 -20 20 -20",
402d414666d18fa9dca1cb310bc66c574aac3d79b72reed@google.com        "M 20 10 Q 20 20 10 20 L 30 20", // test double-back at y-max
4034eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // rect with top two corners replaced by cubics with identical middle
4044eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        // control points
4054eefe6132cbf77696134f65762ebcae574227b77bsalomon@google.com        "M 50 10 C 50 0 50 0 40 0 L 20 0 C 10 0 10 0 10 10"
4063e71a887628ff25c806675366b081c70bb10b74dreed@google.com    };
4073e71a887628ff25c806675366b081c70bb10b74dreed@google.com    for (i = 0; i < SK_ARRAY_COUNT(gCCW); ++i) {
4083e71a887628ff25c806675366b081c70bb10b74dreed@google.com        path.reset();
4093e71a887628ff25c806675366b081c70bb10b74dreed@google.com        bool valid = SkParsePath::FromSVGString(gCCW[i], &path);
4103e71a887628ff25c806675366b081c70bb10b74dreed@google.com        REPORTER_ASSERT(reporter, valid);
411f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com        check_direction(&path, SkPath::kCCW_Direction, reporter);
4123e71a887628ff25c806675366b081c70bb10b74dreed@google.com    }
413ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com
414ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    // Test two donuts, each wound a different direction. Only the outer contour
415ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    // determines the cheap direction
416ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.reset();
417ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCW_Direction);
418ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCCW_Direction);
419f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    check_direction(&path, SkPath::kCW_Direction, reporter);
420f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com
421ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.reset();
422ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCW_Direction);
423ac8543ff574cb08ad46bee691d64e31fe31339e5reed@google.com    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCCW_Direction);
424f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    check_direction(&path, SkPath::kCCW_Direction, reporter);
425f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com
4266843ac4bebd00eef9af28f9f069e7c188b466af3bsalomon@google.com#ifdef SK_SCALAR_IS_FLOAT
427f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    // triangle with one point really far from the origin.
428f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    path.reset();
429f0ed80a7ebef9b9c08093390b173e64bf300d7d7bsalomon@google.com    // the first point is roughly 1.05e10, 1.05e10
43053aab7813ca20360426524361941cf43567fc7aebsalomon@google.com    path.moveTo(SkFloatToScalar(SkBits2Float(0x501c7652)), SkFloatToScalar(SkBits2Float(0x501c7652)));
43153aab7813ca20360426524361941cf43567fc7aebsalomon@google.com    path.lineTo(110 * SK_Scalar1, -10 * SK_Scalar1);
43253aab7813ca20360426524361941cf43567fc7aebsalomon@google.com    path.lineTo(-10 * SK_Scalar1, 60 * SK_Scalar1);
43353aab7813ca20360426524361941cf43567fc7aebsalomon@google.com    check_direction(&path, SkPath::kCCW_Direction, reporter);
43453aab7813ca20360426524361941cf43567fc7aebsalomon@google.com#endif
4353e71a887628ff25c806675366b081c70bb10b74dreed@google.com}
4363e71a887628ff25c806675366b081c70bb10b74dreed@google.com
437ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.comstatic void add_rect(SkPath* path, const SkRect& r) {
438ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->moveTo(r.fLeft, r.fTop);
439ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->lineTo(r.fRight, r.fTop);
440ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->lineTo(r.fRight, r.fBottom);
441ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->lineTo(r.fLeft, r.fBottom);
442ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    path->close();
443ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com}
444ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
445ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.comstatic void test_bounds(skiatest::Reporter* reporter) {
446ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    static const SkRect rects[] = {
4473563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(160) },
4483563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(610), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(199) },
4493563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(10), SkIntToScalar(198), SkIntToScalar(610), SkIntToScalar(199) },
4503563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com        { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(10), SkIntToScalar(199) },
451ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    };
452ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
453ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    SkPath path0, path1;
454ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(rects); ++i) {
455ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com        path0.addRect(rects[i]);
456ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com        add_rect(&path1, rects[i]);
457ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    }
458ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
459ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com    REPORTER_ASSERT(reporter, path0.getBounds() == path1.getBounds());
460ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com}
461ffdb018dae05f1688c6c036299f8c8a0f28342e5reed@google.com
46255b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.comstatic void stroke_cubic(const SkPoint pts[4]) {
46355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPath path;
46455b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    path.moveTo(pts[0]);
46555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    path.cubicTo(pts[1], pts[2], pts[3]);
466d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
46755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPaint paint;
46855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    paint.setStyle(SkPaint::kStroke_Style);
46955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    paint.setStrokeWidth(SK_Scalar1 * 2);
470d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
47155b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPath fill;
47255b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    paint.getFillPath(path, &fill);
47355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com}
47455b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com
47555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com// just ensure this can run w/o any SkASSERTS firing in the debug build
47655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com// we used to assert due to differences in how we determine a degenerate vector
47755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com// but that was fixed with the introduction of SkPoint::CanNormalize
47855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.comstatic void stroke_tiny_cubic() {
47955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPoint p0[] = {
48055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
48155b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
48255b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
48355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,   92.0f },
48455b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    };
485d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
48655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    stroke_cubic(p0);
487d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
48855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    SkPoint p1[] = {
48955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0f,       92.0f },
49055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 372.0007f,    92.000755f },
49155b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 371.99927f,   92.003922f },
49255b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com        { 371.99826f,   92.003899f },
49355b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    };
494d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
49555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    stroke_cubic(p1);
49655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com}
49755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com
498b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.comstatic void check_close(skiatest::Reporter* reporter, const SkPath& path) {
499b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    for (int i = 0; i < 2; ++i) {
50009042b80d22837c760bb530124aaa67469b19b8frobertphillips@google.com        SkPath::Iter iter(path, SkToBool(i));
501b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        SkPoint mv;
502b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        SkPoint pts[4];
503b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        SkPath::Verb v;
504b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        int nMT = 0;
505b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        int nCL = 0;
506221db3c3364eb110bc03db78cb09aae51d117b27tomhudson@google.com        mv.set(0, 0);
507b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        while (SkPath::kDone_Verb != (v = iter.next(pts))) {
508b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com            switch (v) {
509b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                case SkPath::kMove_Verb:
510b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    mv = pts[0];
511b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    ++nMT;
512b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    break;
513b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                case SkPath::kClose_Verb:
514b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    REPORTER_ASSERT(reporter, mv == pts[0]);
515b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    ++nCL;
516b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    break;
517b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                default:
518b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                    break;
519b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com            }
520b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        }
521b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        // if we force a close on the interator we should have a close
522b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        // for every moveTo
523b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        REPORTER_ASSERT(reporter, !i || nMT == nCL);
524b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    }
525b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com}
526b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
527b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.comstatic void test_close(skiatest::Reporter* reporter) {
528b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath closePt;
529b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    closePt.moveTo(0, 0);
530b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    closePt.close();
531b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, closePt);
532b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
533b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath openPt;
534b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    openPt.moveTo(0, 0);
535b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, openPt);
536b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
537b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath empty;
538b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, empty);
539b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    empty.close();
540b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, empty);
541b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
542b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath rect;
543b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
544b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect);
545b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect.close();
546b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect);
547b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
548b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath quad;
549b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    quad.quadTo(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
550b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, quad);
551b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    quad.close();
552b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, quad);
553b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
554b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath cubic;
555d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    quad.cubicTo(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1,
556b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com                 10*SK_Scalar1, 20 * SK_Scalar1, 20*SK_Scalar1);
557b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, cubic);
558b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    cubic.close();
559b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, cubic);
560b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
561b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath line;
562b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    line.moveTo(SK_Scalar1, SK_Scalar1);
563b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    line.lineTo(10 * SK_Scalar1, 10*SK_Scalar1);
564b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, line);
565b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    line.close();
566b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, line);
567b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
568b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath rect2;
569b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
570b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.close();
571b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
572b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect2);
573b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    rect2.close();
574b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, rect2);
575b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
576b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath oval3;
577b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.addOval(SkRect::MakeWH(SK_Scalar1*100,SK_Scalar1*100));
578b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.close();
579b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.addOval(SkRect::MakeWH(SK_Scalar1*200,SK_Scalar1*200));
580b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, oval3);
581b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    oval3.close();
582b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, oval3);
583b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
584b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    SkPath moves;
585b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(SK_Scalar1, SK_Scalar1);
586b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(5 * SK_Scalar1, SK_Scalar1);
587b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(SK_Scalar1, 10 * SK_Scalar1);
588b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    moves.moveTo(10 *SK_Scalar1, SK_Scalar1);
589b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    check_close(reporter, moves);
59055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com
59155b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    stroke_tiny_cubic();
592b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com}
593b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com
5947c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.comstatic void check_convexity(skiatest::Reporter* reporter, const SkPath& path,
5957c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com                            SkPath::Convexity expected) {
5967c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath::Convexity c = SkPath::ComputeConvexity(path);
5977c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    REPORTER_ASSERT(reporter, c == expected);
5987c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com}
5997c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com
6007c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.comstatic void test_convexity2(skiatest::Reporter* reporter) {
6017c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath pt;
6027c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    pt.moveTo(0, 0);
6037c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    pt.close();
604b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    check_convexity(reporter, pt, SkPath::kConvex_Convexity);
605d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6067c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath line;
6076c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    line.moveTo(12*SK_Scalar1, 20*SK_Scalar1);
6086c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    line.lineTo(-12*SK_Scalar1, -20*SK_Scalar1);
6097c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    line.close();
610b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    check_convexity(reporter, pt, SkPath::kConvex_Convexity);
611d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6127c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath triLeft;
6137c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triLeft.moveTo(0, 0);
6146c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triLeft.lineTo(SK_Scalar1, 0);
6156c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triLeft.lineTo(SK_Scalar1, SK_Scalar1);
6167c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triLeft.close();
6177c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, triLeft, SkPath::kConvex_Convexity);
618d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6197c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath triRight;
6207c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triRight.moveTo(0, 0);
6216c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triRight.lineTo(-SK_Scalar1, 0);
6226c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    triRight.lineTo(SK_Scalar1, SK_Scalar1);
6237c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    triRight.close();
6247c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, triRight, SkPath::kConvex_Convexity);
625d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6267c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath square;
6277c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    square.moveTo(0, 0);
6286c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    square.lineTo(SK_Scalar1, 0);
6296c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    square.lineTo(SK_Scalar1, SK_Scalar1);
6306c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    square.lineTo(0, SK_Scalar1);
6317c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    square.close();
6327c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, square, SkPath::kConvex_Convexity);
633d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6347c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath redundantSquare;
6357c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.moveTo(0, 0);
6367c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.lineTo(0, 0);
6377c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.lineTo(0, 0);
6386c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, 0);
6396c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, 0);
6406c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, 0);
6416c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
6426c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
6436c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
6446c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(0, SK_Scalar1);
6456c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(0, SK_Scalar1);
6466c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    redundantSquare.lineTo(0, SK_Scalar1);
6477c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    redundantSquare.close();
6487c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, redundantSquare, SkPath::kConvex_Convexity);
649d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6507c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath bowTie;
6517c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.moveTo(0, 0);
6527c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.lineTo(0, 0);
6537c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.lineTo(0, 0);
6546c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
6556c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
6566c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, SK_Scalar1);
6576c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, 0);
6586c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, 0);
6596c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(SK_Scalar1, 0);
6606c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(0, SK_Scalar1);
6616c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(0, SK_Scalar1);
6626c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    bowTie.lineTo(0, SK_Scalar1);
6637c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    bowTie.close();
6647c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, bowTie, SkPath::kConcave_Convexity);
665d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6667c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath spiral;
6677c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    spiral.moveTo(0, 0);
6686c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(100*SK_Scalar1, 0);
6696c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
6706c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(0, 100*SK_Scalar1);
6716c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(0, 50*SK_Scalar1);
6726c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(50*SK_Scalar1, 50*SK_Scalar1);
6736c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    spiral.lineTo(50*SK_Scalar1, 75*SK_Scalar1);
6747c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    spiral.close();
67585b6e399d56d2421980daa432f30910beda41922reed@google.com    check_convexity(reporter, spiral, SkPath::kConcave_Convexity);
676d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
6777c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    SkPath dent;
6786c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.moveTo(0, 0);
6796c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
6806c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(0, 100*SK_Scalar1);
6816c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(-50*SK_Scalar1, 200*SK_Scalar1);
6826c31d9d9b4ea183ec7be29f97e108c8cfb33533bschenney@chromium.org    dent.lineTo(-200*SK_Scalar1, 100*SK_Scalar1);
6837c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    dent.close();
6847c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    check_convexity(reporter, dent, SkPath::kConcave_Convexity);
6857c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com}
6867c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com
6876b82d1adc6a4726e36674e468ff1157e0b75373freed@android.comstatic void check_convex_bounds(skiatest::Reporter* reporter, const SkPath& p,
6886b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com                                const SkRect& bounds) {
6896b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p.isConvex());
6906b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p.getBounds() == bounds);
69162047cf1980861234e7367a225928b84ce492c68reed@google.com
6926b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    SkPath p2(p);
6936b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p2.isConvex());
6946b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, p2.getBounds() == bounds);
6956b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
6966b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    SkPath other;
6976b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    other.swap(p2);
6986b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, other.isConvex());
6996b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    REPORTER_ASSERT(reporter, other.getBounds() == bounds);
7006b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com}
7016b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
70204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.comstatic void setFromString(SkPath* path, const char str[]) {
70304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    bool first = true;
70404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    while (str) {
70504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkScalar x, y;
70604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        str = SkParse::FindScalar(str, &x);
70704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        if (NULL == str) {
70804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            break;
70904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        }
71004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        str = SkParse::FindScalar(str, &y);
71104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkASSERT(str);
71204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        if (first) {
71304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            path->moveTo(x, y);
71404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            first = false;
71504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        } else {
71604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com            path->lineTo(x, y);
71704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        }
71804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    }
71904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com}
72004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
72104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.comstatic void test_convexity(skiatest::Reporter* reporter) {
72204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    static const SkPath::Convexity C = SkPath::kConcave_Convexity;
72304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    static const SkPath::Convexity V = SkPath::kConvex_Convexity;
72404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
72504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    SkPath path;
72604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
727b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
728e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addCircle(0, 0, SkIntToScalar(10));
72904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
730e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addCircle(0, 0, SkIntToScalar(10));   // 2nd circle
73104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    REPORTER_ASSERT(reporter, C == SkPath::ComputeConvexity(path));
73204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    path.reset();
733e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPath::kCCW_Direction);
73404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
7353e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCCW_Direction));
73604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    path.reset();
737e354397dd9ac2f0d011fcdcdbae242bb0cfd0fa9reed@google.com    path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPath::kCW_Direction);
73804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path));
7393e71a887628ff25c806675366b081c70bb10b74dreed@google.com    REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kCW_Direction));
740d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
74104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    static const struct {
74204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        const char*         fPathStr;
74304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkPath::Convexity   fExpectedConvexity;
74404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    } gRec[] = {
745b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com        { "", SkPath::kConvex_Convexity },
746b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com        { "0 0", SkPath::kConvex_Convexity },
747b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com        { "0 0 10 10", SkPath::kConvex_Convexity },
74885b6e399d56d2421980daa432f30910beda41922reed@google.com        { "0 0 10 10 20 20 0 0 10 10", SkPath::kConcave_Convexity },
74904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        { "0 0 10 10 10 20", SkPath::kConvex_Convexity },
75004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        { "0 0 10 10 10 0", SkPath::kConvex_Convexity },
75104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        { "0 0 10 10 10 0 0 10", SkPath::kConcave_Convexity },
75204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        { "0 0 10 0 0 10 -10 -10", SkPath::kConcave_Convexity },
75304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    };
75404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
75504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
75604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkPath path;
75704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        setFromString(&path, gRec[i].fPathStr);
75804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        SkPath::Convexity c = SkPath::ComputeConvexity(path);
75904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        REPORTER_ASSERT(reporter, c == gRec[i].fExpectedConvexity);
76004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    }
76104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com}
76204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
7637e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.comstatic void test_isLine(skiatest::Reporter* reporter) {
7647e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkPath path;
7657e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkPoint pts[2];
7667e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar value = SkIntToScalar(5);
7677e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
7687e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(NULL));
769d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
7707e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    // set some non-zero values
7717e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    pts[0].set(value, value);
7727e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    pts[1].set(value, value);
7737e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(pts));
7747e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    // check that pts was untouched
7757e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(value, value));
7767e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(value, value));
7777e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
7787e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar moveX = SkIntToScalar(1);
7797e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar moveY = SkIntToScalar(2);
7807e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkASSERT(value != moveX && value != moveY);
7817e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
7827e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    path.moveTo(moveX, moveY);
7837e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(NULL));
7847e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(pts));
7857e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    // check that pts was untouched
7867e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(value, value));
7877e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(value, value));
7887e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
7897e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar lineX = SkIntToScalar(2);
7907e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    const SkScalar lineY = SkIntToScalar(2);
7917e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    SkASSERT(value != lineX && value != lineY);
7927e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
7937e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    path.lineTo(lineX, lineY);
7947e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, path.isLine(NULL));
7957e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
7967e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !pts[0].equals(moveX, moveY));
7977e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !pts[1].equals(lineX, lineY));
7987e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, path.isLine(pts));
7997e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
8007e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
8017e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
8027e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    path.lineTo(0, 0);  // too many points/verbs
8037e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(NULL));
8047e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, !path.isLine(pts));
8057e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
8067e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
8077e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com}
8087e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
809f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com// Simple isRect test is inline TestPath, below.
810f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com// test_isRect provides more extensive testing.
811f131694617ce0410eafcb01124459382576bb1d9caryclark@google.comstatic void test_isRect(skiatest::Reporter* reporter) {
812f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // passing tests (all moveTo / lineTo...
813f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
814f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
815f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
816f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
817f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
818f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
819f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
820f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
821f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
822f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f},
823f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        {1, 0}, {.5f, 0}};
824f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1},
825f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        {0, 1}, {0, .5f}};
826f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};
827f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
828f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}};
829d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
830f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // failing tests
831f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}}; // too few points
832f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}}; // diagonal
833f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}}; // wraps
834f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}}; // backs up
835f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}}; // end overshoots
836f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}}; // end overshoots
837f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}}; // end overshoots
838f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}}; // 'L'
839d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
840f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // failing, no close
841f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; // close doesn't match
842f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}}; // ditto
843f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com
844f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    size_t testLen[] = {
845f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(r1), sizeof(r2), sizeof(r3), sizeof(r4), sizeof(r5), sizeof(r6),
846f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(r7), sizeof(r8), sizeof(r9), sizeof(ra), sizeof(rb), sizeof(rc),
847f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(rd), sizeof(re),
848f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(f1), sizeof(f2), sizeof(f3), sizeof(f4), sizeof(f5), sizeof(f6),
849f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        sizeof(f7), sizeof(f8),
850d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        sizeof(c1), sizeof(c2)
851f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    };
852f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint* tests[] = {
853f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        r1, r2, r3, r4, r5, r6, r7, r8, r9, ra, rb, rc, rd, re,
854f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        f1, f2, f3, f4, f5, f6, f7, f8,
855d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        c1, c2
856f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    };
857f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint* lastPass = re;
858f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPoint* lastClose = f8;
859f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    bool fail = false;
860f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    bool close = true;
861f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    const size_t testCount = sizeof(tests) / sizeof(tests[0]);
862f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    size_t index;
863f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (size_t testIndex = 0; testIndex < testCount; ++testIndex) {
864f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        SkPath path;
865f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path.moveTo(tests[testIndex][0].fX, tests[testIndex][0].fY);
866f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        for (index = 1; index < testLen[testIndex] / sizeof(SkPoint); ++index) {
867f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path.lineTo(tests[testIndex][index].fX, tests[testIndex][index].fY);
868f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
869f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (close) {
870f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path.close();
871f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
872f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        REPORTER_ASSERT(reporter, fail ^ path.isRect(0));
873f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (tests[testIndex] == lastPass) {
874f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            fail = true;
875f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
876f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (tests[testIndex] == lastClose) {
877f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            close = false;
878f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
879f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
880d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
881f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, close then line
882f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    SkPath path1;
883f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
884f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
885f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
886f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
887f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
888f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.lineTo(1, 0);
889f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
890d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
891f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, move in the middle
892f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
893f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
894f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
895f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (index == 2) {
896f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path1.moveTo(1, .5f);
897f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
898f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
899f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
900f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
901f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
902f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com
903f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, move on the edge
904f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
905f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
906f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.moveTo(r1[index - 1].fX, r1[index - 1].fY);
907f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
908f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
909f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
910f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
911d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
912f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, quad
913f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
914f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
915f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
916f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (index == 2) {
917f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path1.quadTo(1, .5f, 1, .5f);
918f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
919f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
920f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
921f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
922f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
923d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
924f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    // fail, cubic
925f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.reset();
926f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.moveTo(r1[0].fX, r1[0].fY);
927f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    for (index = 1; index < testLen[0] / sizeof(SkPoint); ++index) {
928f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        if (index == 2) {
929f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com            path1.cubicTo(1, .5f, 1, .5f, 1, .5f);
930f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        }
931f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com        path1.lineTo(r1[index].fX, r1[index].fY);
932f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    }
933f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    path1.close();
934f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    REPORTER_ASSERT(reporter, fail ^ path1.isRect(0));
935f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com}
936f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com
9372972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.comstatic void write_and_read_back(skiatest::Reporter* reporter,
9382972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com                                const SkPath& p) {
9392972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkWriter32 writer(100);
9402972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    writer.writePath(p);
9412972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    size_t size = writer.size();
9422972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkAutoMalloc storage(size);
9432972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    writer.flatten(storage.get());
9442972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkReader32 reader(storage.get(), size);
9452972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
9462972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    SkPath readBack;
9472972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, readBack != p);
9482972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    reader.readPath(&readBack);
9492972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, readBack == p);
9502972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
951d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    REPORTER_ASSERT(reporter, readBack.getConvexityOrUnknown() ==
9522972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com                              p.getConvexityOrUnknown());
9532972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
9542972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, readBack.isOval(NULL) == p.isOval(NULL));
9552972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
9562972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    const SkRect& origBounds = p.getBounds();
9572972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    const SkRect& readBackBounds = readBack.getBounds();
9582972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
9592972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    REPORTER_ASSERT(reporter, origBounds == readBackBounds);
9602972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com}
9612972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
96253effc5e327749ea47bc0c678cb45246644600b0reed@google.comstatic void test_flattening(skiatest::Reporter* reporter) {
96353effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkPath p;
96453effc5e327749ea47bc0c678cb45246644600b0reed@google.com
96553effc5e327749ea47bc0c678cb45246644600b0reed@google.com    static const SkPoint pts[] = {
96653effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 },
96753effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(10), SkIntToScalar(10) },
96853effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 },
96953effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }
97053effc5e327749ea47bc0c678cb45246644600b0reed@google.com    };
97153effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.moveTo(pts[0]);
97253effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.lineTo(pts[1]);
97353effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.quadTo(pts[2], pts[3]);
97453effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.cubicTo(pts[4], pts[5], pts[6]);
97553effc5e327749ea47bc0c678cb45246644600b0reed@google.com
9762972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    write_and_read_back(reporter, p);
97794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
97894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    // create a buffer that should be much larger than the path so we don't
97994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    // kill our stack if writer goes too far.
98094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    char buffer[1024];
98194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t size1 = p.writeToMemory(NULL);
98294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t size2 = p.writeToMemory(buffer);
98394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, size1 == size2);
98494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
98594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    SkPath p2;
98694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t size3 = p2.readFromMemory(buffer);
98794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, size1 == size3);
98894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, p == p2);
98994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
99094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    char buffer2[1024];
99194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    size3 = p2.writeToMemory(buffer2);
99294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, size1 == size3);
99394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0);
9942972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
9952972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    // test persistence of the oval flag & convexity
9962972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    {
9972972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        SkPath oval;
9982972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        SkRect rect = SkRect::MakeWH(10, 10);
9992972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        oval.addOval(rect);
10002972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com
10012972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com        write_and_read_back(reporter, oval);
10022972bb5fd2441709026b350c6b9b66eecd80f868robertphillips@google.com    }
100353effc5e327749ea47bc0c678cb45246644600b0reed@google.com}
100453effc5e327749ea47bc0c678cb45246644600b0reed@google.com
100553effc5e327749ea47bc0c678cb45246644600b0reed@google.comstatic void test_transform(skiatest::Reporter* reporter) {
100653effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkPath p, p1;
1007d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
100853effc5e327749ea47bc0c678cb45246644600b0reed@google.com    static const SkPoint pts[] = {
100953effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 },
101053effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(10), SkIntToScalar(10) },
101153effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 },
101253effc5e327749ea47bc0c678cb45246644600b0reed@google.com        { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }
101353effc5e327749ea47bc0c678cb45246644600b0reed@google.com    };
101453effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.moveTo(pts[0]);
101553effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.lineTo(pts[1]);
101653effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.quadTo(pts[2], pts[3]);
101753effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.cubicTo(pts[4], pts[5], pts[6]);
1018d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
101953effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkMatrix matrix;
102053effc5e327749ea47bc0c678cb45246644600b0reed@google.com    matrix.reset();
102153effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.transform(matrix, &p1);
102253effc5e327749ea47bc0c678cb45246644600b0reed@google.com    REPORTER_ASSERT(reporter, p == p1);
1023d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
102453effc5e327749ea47bc0c678cb45246644600b0reed@google.com    matrix.setScale(SK_Scalar1 * 2, SK_Scalar1 * 3);
102553effc5e327749ea47bc0c678cb45246644600b0reed@google.com    p.transform(matrix, &p1);
102653effc5e327749ea47bc0c678cb45246644600b0reed@google.com    SkPoint pts1[7];
102753effc5e327749ea47bc0c678cb45246644600b0reed@google.com    int count = p1.getPoints(pts1, 7);
102853effc5e327749ea47bc0c678cb45246644600b0reed@google.com    REPORTER_ASSERT(reporter, 7 == count);
102953effc5e327749ea47bc0c678cb45246644600b0reed@google.com    for (int i = 0; i < count; ++i) {
103053effc5e327749ea47bc0c678cb45246644600b0reed@google.com        SkPoint newPt = SkPoint::Make(pts[i].fX * 2, pts[i].fY * 3);
103153effc5e327749ea47bc0c678cb45246644600b0reed@google.com        REPORTER_ASSERT(reporter, newPt == pts1[i]);
103253effc5e327749ea47bc0c678cb45246644600b0reed@google.com    }
103353effc5e327749ea47bc0c678cb45246644600b0reed@google.com}
103453effc5e327749ea47bc0c678cb45246644600b0reed@google.com
10354da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.orgstatic void test_zero_length_paths(skiatest::Reporter* reporter) {
10366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath  p;
10377e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    uint8_t verbs[32];
10387e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
10397e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    struct zeroPathTestData {
10407e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const char* testPath;
10417e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t numResultPts;
10427e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkRect resultBound;
10437e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkPath::Verb* resultVerbs;
10447e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t numResultVerbs;
10457e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
10464da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
10477e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs1[] = { SkPath::kMove_Verb };
10487e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs2[] = { SkPath::kMove_Verb, SkPath::kMove_Verb };
10497e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs3[] = { SkPath::kMove_Verb, SkPath::kClose_Verb };
10507e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs4[] = { SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb };
10517e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs5[] = { SkPath::kMove_Verb, SkPath::kLine_Verb };
10527e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs6[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kMove_Verb, SkPath::kLine_Verb };
10537e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs7[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb };
10547e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs8[] = {
10557e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb
10567e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
10577e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs9[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb };
10587e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs10[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kMove_Verb, SkPath::kQuad_Verb };
10597e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs11[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb };
10607e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs12[] = {
10617e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb
10627e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
10637e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs13[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb };
10647e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs14[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kMove_Verb, SkPath::kCubic_Verb };
10657e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs15[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb };
10667e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs16[] = {
10677e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb
10687e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
10697e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const struct zeroPathTestData gZeroLengthTests[] = {
10707e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "M 1 1", 1, {0, 0, 0, 0}, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1071aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 M 2 1", 2, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs2, SK_ARRAY_COUNT(resultVerbs2) },
10727e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "M 1 1 z", 1, {0, 0, 0, 0}, resultVerbs3, SK_ARRAY_COUNT(resultVerbs3) },
1073aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1074aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 L 1 1", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs5, SK_ARRAY_COUNT(resultVerbs5) },
1075aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1076aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 L 1 1 z", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs7, SK_ARRAY_COUNT(resultVerbs7) },
1077aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1078aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 1 Q 1 1 1 1", 3, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs9, SK_ARRAY_COUNT(resultVerbs9) },
1079aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1080aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1081aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1082aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1083aaf1688959ba5dc74007e711599552928d255dfaschenney@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,
10847e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            SK_ARRAY_COUNT(resultVerbs14)
10857e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        },
1086aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1087aaf1688959ba5dc74007e711599552928d255dfaschenney@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,
10887e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            SK_ARRAY_COUNT(resultVerbs16)
10897e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        }
10907e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
10914da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
10927e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(gZeroLengthTests); ++i) {
10937e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        p.reset();
10947e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        bool valid = SkParsePath::FromSVGString(gZeroLengthTests[i].testPath, &p);
10957e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, valid);
10967e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, !p.isEmpty());
10977e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultPts == (size_t)p.countPoints());
10987e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultBound == p.getBounds());
10997e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultVerbs == (size_t)p.getVerbs(verbs, SK_ARRAY_COUNT(verbs)));
11007e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        for (size_t j = 0; j < gZeroLengthTests[i].numResultVerbs; ++j) {
11017e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultVerbs[j] == verbs[j]);
11027e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        }
1103df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    }
11044da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org}
11054da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
11064da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.orgstruct SegmentInfo {
11074da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    SkPath fPath;
11084da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    int    fPointCount;
11094da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org};
11104da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
111110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com#define kCurveSegmentMask   (SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask)
111210296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
11136630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.orgstatic void test_segment_masks(skiatest::Reporter* reporter) {
1114eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    SkPath p, p2;
1115eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com
11166630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(0, 0);
11176630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.quadTo(100, 100, 200, 200);
11186630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, SkPath::kQuad_SegmentMask == p.getSegmentMasks());
11196630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
1120eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    p2 = p;
1121eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
11226630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.cubicTo(100, 100, 200, 200, 300, 300);
11236630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, kCurveSegmentMask == p.getSegmentMasks());
11246630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
1125eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    p2 = p;
1126eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
1127eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com
11286630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.reset();
11296630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(0, 0);
11306630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.cubicTo(100, 100, 200, 200, 300, 300);
11316630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, SkPath::kCubic_SegmentMask == p.getSegmentMasks());
1132eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    p2 = p;
1133eef938c0a764ca24bfebf38655124c8fcb8144f2reed@google.com    REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
1134d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
11356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
11366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org}
11376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
11386630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.orgstatic void test_iter(skiatest::Reporter* reporter) {
11397e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    SkPath  p;
11406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint pts[4];
11416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
11426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with no path
11436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::Iter noPathIter;
11446630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
11457e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
11466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that setting an empty path works
11476630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    noPathIter.setPath(p, false);
11486630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
11497e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
11506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that close path makes no difference for an empty path
11516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    noPathIter.setPath(p, true);
11526630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
11537e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org
11546630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with an initial empty path
11556630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::Iter iter(p, false);
11566630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
11576630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
11586630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that close path makes no difference
11597e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    iter.setPath(p, true);
11606630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
11616630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
1162d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
11637e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    struct iterTestData {
11647e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const char* testPath;
11657e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const bool forceClose;
11667e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const bool consumeDegenerates;
11677e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t* numResultPtsPerVerb;
11687e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkPoint* resultPts;
11697e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const SkPath::Verb* resultVerbs;
11707e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        const size_t numResultVerbs;
11717e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
11726630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
11737e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs1[] = { SkPath::kDone_Verb };
11747e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs2[] = {
11757e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kDone_Verb
11767e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
11777e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs3[] = {
11787e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb
11797e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
11807e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs4[] = {
11817e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb
11827e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
11837e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPath::Verb resultVerbs5[] = {
11847e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb, SkPath::kMove_Verb, SkPath::kClose_Verb, SkPath::kDone_Verb
11857e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
11867e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const size_t resultPtsSizes1[] = { 0 };
1187fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes2[] = { 1, 2, 2, 0 };
1188fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes3[] = { 1, 2, 2, 2, 1, 0 };
1189fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes4[] = { 1, 2, 1, 1, 0 };
1190fedd09ba7e218116df8a676069726de6e9d35277schenney@chromium.org    static const size_t resultPtsSizes5[] = { 1, 2, 1, 1, 1, 0 };
1191aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org    static const SkPoint* resultPts1 = 0;
11927e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts2[] = {
11937e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, SK_Scalar1 }, { SK_Scalar1, SK_Scalar1 }, { 0, SK_Scalar1 }
11947e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
11957e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts3[] = {
11967e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, SK_Scalar1 }, { SK_Scalar1, SK_Scalar1 }, { 0, SK_Scalar1 },
11977e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { 0, SK_Scalar1 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }
11987e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
11997e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts4[] = {
12007e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 }
12017e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
12027e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const SkPoint resultPts5[] = {
12037e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 }
12047e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
12057e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    static const struct iterTestData gIterTests[] = {
12067e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "M 1 0", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1207aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
1208aaf1688959ba5dc74007e711599552928d255dfaschenney@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) },
12097e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
12107e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        { "z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
12117e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@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) },
12127e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@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) },
1213aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 1 L 0 1 M 0 0 z", false, true, resultPtsSizes2, resultPts2, resultVerbs2, SK_ARRAY_COUNT(resultVerbs2) },
1214aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 1 L 0 1 M 0 0 z", true, true, resultPtsSizes3, resultPts3, resultVerbs3, SK_ARRAY_COUNT(resultVerbs3) },
1215aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", false, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1216aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", true, true, resultPtsSizes1, resultPts1, resultVerbs1, SK_ARRAY_COUNT(resultVerbs1) },
1217aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", false, false, resultPtsSizes4, resultPts4, resultVerbs4, SK_ARRAY_COUNT(resultVerbs4) },
1218aaf1688959ba5dc74007e711599552928d255dfaschenney@chromium.org        { "M 1 0 L 1 0 M 0 0 z", true, false, resultPtsSizes5, resultPts5, resultVerbs5, SK_ARRAY_COUNT(resultVerbs5) }
12197e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    };
12206630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12217e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    for (size_t i = 0; i < SK_ARRAY_COUNT(gIterTests); ++i) {
12227e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        p.reset();
12237e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        bool valid = SkParsePath::FromSVGString(gIterTests[i].testPath, &p);
12247e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, valid);
12257e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        iter.setPath(p, gIterTests[i].forceClose);
12267e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        int j = 0, l = 0;
12277e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        do {
12287e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            REPORTER_ASSERT(reporter, iter.next(pts, gIterTests[i].consumeDegenerates) == gIterTests[i].resultVerbs[j]);
12297e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            for (int k = 0; k < (int)gIterTests[i].numResultPtsPerVerb[j]; ++k) {
12307e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org                REPORTER_ASSERT(reporter, pts[k] == gIterTests[i].resultPts[l++]);
12317e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org            }
12327e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        } while (gIterTests[i].resultVerbs[j++] != SkPath::kDone_Verb);
12337e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org        REPORTER_ASSERT(reporter, j == (int)gIterTests[i].numResultVerbs);
12347e963605d5b8177c30afa0d8e5541b0fbe1b6e13schenney@chromium.org    }
12356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // The GM degeneratesegments.cpp test is more extensive
12376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org}
12386630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12396630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.orgstatic void test_raw_iter(skiatest::Reporter* reporter) {
12406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath p;
12416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint pts[4];
12426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with no path
12446630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::RawIter noPathIter;
12456630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
12466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that setting an empty path works
12476630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    noPathIter.setPath(p);
12486630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
1249d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
12506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test an iterator with an initial empty path
12516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::RawIter iter(p);
12526630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
12536630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12546630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Test that a move-only path returns the move.
12556630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1, 0);
12566630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
12576630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
12586630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
12596630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
12606630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
12616630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12626630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // No matter how many moves we add, we should get them all back
12636630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*2, SK_Scalar1);
12646630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*3, SK_Scalar1*2);
12656630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
12666630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
12676630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
12686630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
12696630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
12706630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
12716630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
12726630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
12736630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
12746630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
12756630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
12766630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12776630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Initial close is never ever stored
12786630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.reset();
12796630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
12806630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
12816630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
12826630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
12836630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Move/close sequences
12846630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.reset();
12856630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close(); // Not stored, no purpose
12866630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1, 0);
12876630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
12886630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close(); // Not stored, no purpose
12896630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*2, SK_Scalar1);
12906630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
12916630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*3, SK_Scalar1*2);
12926630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.moveTo(SK_Scalar1*4, SK_Scalar1*3);
12936630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    p.close();
12946630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    iter.setPath(p);
12956630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
12966630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
12976630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
12986630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
12996630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
13006630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == 0);
13016630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
13026630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
13036630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
13046630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
13056630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
13066630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
13076630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
13086630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
13096630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
13106630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kMove_Verb);
13116630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*4);
13126630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*3);
13136630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kClose_Verb);
13146630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*4);
13156630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*3);
13166630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
13176630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
13186630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Generate random paths and verify
13196630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint randomPts[25];
13206630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    for (int i = 0; i < 5; ++i) {
13216630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        for (int j = 0; j < 5; ++j) {
13226630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            randomPts[i*5+j].set(SK_Scalar1*i, SK_Scalar1*j);
13236630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        }
13246630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    }
13256630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
13266630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    // Max of 10 segments, max 3 points per segment
13276630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkRandom rand(9876543);
13286630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPoint          expectedPts[31]; // May have leading moveTo
1329d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    SkPath::Verb     expectedVerbs[22]; // May have leading moveTo
13306630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    SkPath::Verb     nextVerb;
1331d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com
13326630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    for (int i = 0; i < 500; ++i) {
13336630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        p.reset();
13346630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        bool lastWasClose = true;
13356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        bool haveMoveTo = false;
1336d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com        SkPoint lastMoveToPt = { 0, 0 };
13376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numPoints = 0;
13386630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numVerbs = (rand.nextU() >> 16) % 10;
13396630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numIterVerbs = 0;
13406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        for (int j = 0; j < numVerbs; ++j) {
13416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            do {
13426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                nextVerb = static_cast<SkPath::Verb>((rand.nextU() >> 16) % SkPath::kDone_Verb);
13436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            } while (lastWasClose && nextVerb == SkPath::kClose_Verb);
13446630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            switch (nextVerb) {
13456630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kMove_Verb:
13466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
13476630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.moveTo(expectedPts[numPoints]);
1348d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                    lastMoveToPt = expectedPts[numPoints];
13496630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 1;
13506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
13516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    haveMoveTo = true;
13526630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
13536630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kLine_Verb:
13546630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    if (!haveMoveTo) {
1355d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                        expectedPts[numPoints++] = lastMoveToPt;
13566630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
13576630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        haveMoveTo = true;
13586630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    }
13596630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
13606630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.lineTo(expectedPts[numPoints]);
13616630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 1;
13626630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
13636630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
13646630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kQuad_Verb:
13656630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    if (!haveMoveTo) {
1366d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                        expectedPts[numPoints++] = lastMoveToPt;
13676630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
13686630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        haveMoveTo = true;
13696630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    }
13706630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
13716630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
13726630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.quadTo(expectedPts[numPoints], expectedPts[numPoints + 1]);
13736630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 2;
13746630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
13756630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
13766630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kCubic_Verb:
13776630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    if (!haveMoveTo) {
1378d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                        expectedPts[numPoints++] = lastMoveToPt;
13796630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        expectedVerbs[numIterVerbs++] = SkPath::kMove_Verb;
13806630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                        haveMoveTo = true;
13816630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    }
13826630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
13836630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
13846630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    expectedPts[numPoints + 2] = randomPts[(rand.nextU() >> 16) % 25];
13856630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.cubicTo(expectedPts[numPoints], expectedPts[numPoints + 1],
13866630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                              expectedPts[numPoints + 2]);
13876630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numPoints += 3;
13886630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = false;
13896630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
13906630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kClose_Verb:
13916630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    p.close();
1392d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com                    haveMoveTo = false;
13936630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastWasClose = true;
13946630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
13956630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                default:;
13966630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            }
13976630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            expectedVerbs[numIterVerbs++] = nextVerb;
13986630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        }
1399d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
14006630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        iter.setPath(p);
14016630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        numVerbs = numIterVerbs;
14026630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        numIterVerbs = 0;
14036630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        int numIterPts = 0;
14046630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        SkPoint lastMoveTo;
14056630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        SkPoint lastPt;
14066630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        lastMoveTo.set(0, 0);
14076630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        lastPt.set(0, 0);
14086630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        while ((nextVerb = iter.next(pts)) != SkPath::kDone_Verb) {
14096630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            REPORTER_ASSERT(reporter, nextVerb == expectedVerbs[numIterVerbs]);
14106630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            numIterVerbs++;
14116630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            switch (nextVerb) {
14126630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kMove_Verb:
14136630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints);
14146630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == expectedPts[numIterPts]);
14156630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = lastMoveTo = pts[0];
14166630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 1;
14176630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
14186630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kLine_Verb:
14196630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 1);
14206630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
14216630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
14226630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = pts[1];
14236630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 1;
14246630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
14256630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kQuad_Verb:
14266630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 2);
14276630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
14286630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
14296630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
14306630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = pts[2];
14316630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 2;
14326630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
14336630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kCubic_Verb:
14346630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, numIterPts < numPoints + 3);
14356630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastPt);
14366630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
14376630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
14386630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[3] == expectedPts[numIterPts + 2]);
14396630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = pts[3];
14406630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    numIterPts += 3;
14416630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
14426630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                case SkPath::kClose_Verb:
14436630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    REPORTER_ASSERT(reporter, pts[0] == lastMoveTo);
14446630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    lastPt = lastMoveTo;
14456630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                    break;
14466630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org                default:;
14476630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            }
14486630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        }
14496630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        REPORTER_ASSERT(reporter, numIterPts == numPoints);
14506630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        REPORTER_ASSERT(reporter, numIterVerbs == numVerbs);
14516630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    }
14526630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org}
14536630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
14546aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void check_for_circle(skiatest::Reporter* reporter,
14556aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                             const SkPath& path, bool expected) {
14566aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkRect rect;
14576aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(&rect) == expected);
14586aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    if (expected) {
14596aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        REPORTER_ASSERT(reporter, rect.height() == rect.width());
14606aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    }
14616aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
14626aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
14636aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_skew(skiatest::Reporter* reporter,
14646aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                             const SkPath& path) {
14656aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath tmp;
14666aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
14676aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix m;
14686aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setSkew(SkIntToScalar(3), SkIntToScalar(5));
14696aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
14706aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, tmp, false);
14716aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
14726aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
14736aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_translate(skiatest::Reporter* reporter,
14746aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                                  const SkPath& path) {
14756aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath tmp;
14766aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
14776aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // translate at small offset
14786aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix m;
14796aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setTranslate(SkIntToScalar(15), SkIntToScalar(15));
14806aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
14816aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, tmp, true);
14826aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
14836aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
14846aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.reset();
14856aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
14866aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // translate at a relatively big offset
14876aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setTranslate(SkIntToScalar(1000), SkIntToScalar(1000));
14886aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
14896aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, tmp, true);
14906aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
14916aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
14926aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_rotate(skiatest::Reporter* reporter,
14936aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                               const SkPath& path) {
14946aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    for (int angle = 0; angle < 360; ++angle) {
14956aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        SkPath tmp;
14966aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        SkMatrix m;
14976aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        m.setRotate(SkIntToScalar(angle));
14986aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        path.transform(m, &tmp);
14996aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15006aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        // TODO: a rotated circle whose rotated angle is not a mutiple of 90
15016aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        // degrees is not an oval anymore, this can be improved.  we made this
15026aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        // for the simplicity of our implementation.
15036aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        if (angle % 90 == 0) {
15046aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com            check_for_circle(reporter, tmp, true);
15056aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        } else {
15066aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com            check_for_circle(reporter, tmp, false);
15076aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com        }
15086aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    }
15096aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
15106aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15116aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_with_direction(skiatest::Reporter* reporter,
15126aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                                       SkPath::Direction dir) {
15136aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
15146aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15156aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // circle at origin
15166aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(20), dir);
15176aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, true);
15186aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_rotate(reporter, path);
15196aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_translate(reporter, path);
15206aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_skew(reporter, path);
15216aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15226aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // circle at an offset at (10, 10)
15236aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
15246aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(SkIntToScalar(10), SkIntToScalar(10),
15256aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                   SkIntToScalar(20), dir);
15266aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, true);
15276aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_rotate(reporter, path);
15286aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_translate(reporter, path);
15296aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_skew(reporter, path);
15306aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
15316aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15326aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle_with_add_paths(skiatest::Reporter* reporter) {
15336aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
15346aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath circle;
15356aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath rect;
15366aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath empty;
15376aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15386aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    circle.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
15396aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    rect.addRect(SkIntToScalar(5), SkIntToScalar(5),
15406aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com                 SkIntToScalar(20), SkIntToScalar(20), SkPath::kCW_Direction);
15416aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15426aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix translate;
15436aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    translate.setTranslate(SkIntToScalar(12), SkIntToScalar(12));
15446aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15456aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // For simplicity, all the path concatenation related operations
15466aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // would mark it non-circle, though in theory it's still a circle.
15476aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15486aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // empty + circle (translate)
15496aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = empty;
15506aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addPath(circle, translate);
15516aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, false);
15526aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15536aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // circle + empty (translate)
15546aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = circle;
15556aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addPath(empty, translate);
15566aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, false);
15576aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15586aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // test reverseAddPath
15596aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = circle;
15606aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reverseAddPath(rect);
15616aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, false);
15626aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
15636aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15646aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_circle(skiatest::Reporter* reporter) {
15656aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_with_direction(reporter, SkPath::kCW_Direction);
15666aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_with_direction(reporter, SkPath::kCCW_Direction);
15676aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15686aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // multiple addCircle()
15696aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
15706aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
15716aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(20), SkPath::kCW_Direction);
15726aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, false);
15736aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15746aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // some extra lineTo() would make isOval() fail
15756aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
15766aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
15776aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.lineTo(0, 0);
15786aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, false);
15796aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15806aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // not back to the original point
15816aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
15826aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
15836aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.setLastPt(SkIntToScalar(5), SkIntToScalar(5));
15846aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    check_for_circle(reporter, path, false);
15856aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15866aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle_with_add_paths(reporter);
15876aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
15886aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15896aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.comstatic void test_oval(skiatest::Reporter* reporter) {
15906aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkRect rect;
15916aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkMatrix m;
15926aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath path;
15936aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15946aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    rect = SkRect::MakeWH(SkIntToScalar(30), SkIntToScalar(50));
15956aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addOval(rect);
15966aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15976aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(NULL));
15986aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
15996aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setRotate(SkIntToScalar(90));
16006aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    SkPath tmp;
16016aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
16026aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // an oval rotated 90 degrees is still an oval.
16036aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, tmp.isOval(NULL));
16046aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
16056aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.reset();
16066aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.setRotate(SkIntToScalar(30));
16076aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
16086aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
16096aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // an oval rotated 30 degrees is not an oval anymore.
16106aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
16116aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
16126aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // since empty path being transformed.
16136aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
16146aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
16156aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    m.reset();
16166aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.transform(m, &tmp);
16176aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
16186aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
16196aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // empty path is not an oval
16206aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
16216aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
16226aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
16236aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // only has moveTo()s
16246aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
16256aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.moveTo(0, 0);
16266aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.moveTo(SkIntToScalar(10), SkIntToScalar(10));
16276aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, !tmp.isOval(NULL));
16286aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
16296aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // mimic WebKit's calling convention,
16306aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // call moveTo() first and then call addOval()
16316aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
16326aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.moveTo(0, 0);
16336aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.addOval(rect);
16346aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(NULL));
16356aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
16366aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    // copy path
16376aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path.reset();
16386aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.reset();
16396aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    tmp.addOval(rect);
16406aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    path = tmp;
16416aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    REPORTER_ASSERT(reporter, path.isOval(NULL));
16426aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com}
16436aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
164442639cddc33746b351bbf07c540711eefffe191acaryclark@google.comstatic void TestPath(skiatest::Reporter* reporter) {
164560bc6d5cb0af7cef0e49cc35f28f36f89b10853ereed@android.com    SkTSize<SkScalar>::Make(3,4);
164660bc6d5cb0af7cef0e49cc35f28f36f89b10853ereed@android.com
16473abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    SkPath  p, p2;
16483abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    SkRect  bounds, bounds2;
164980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
16503abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.isEmpty());
16514da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, 0 == p.countPoints());
1652df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, 0 == p.countVerbs());
165310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
1654b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    REPORTER_ASSERT(reporter, p.isConvex());
16553abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType);
16563abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !p.isInverseFillType());
16573abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p == p2);
16583abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !(p != p2));
16593abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
1660d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    REPORTER_ASSERT(reporter, p.getBounds().isEmpty());
166180e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
16623abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds.set(0, 0, SK_Scalar1, SK_Scalar1);
16636b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
16646b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1);
16656b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    check_convex_bounds(reporter, p, bounds);
166610296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    // we have quads or cubics
166710296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, p.getSegmentMasks() & kCurveSegmentMask);
16684da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
166962047cf1980861234e7367a225928b84ce492c68reed@google.com
16706b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.reset();
167110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
16724da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, p.isEmpty());
167310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
16746b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.addOval(bounds);
16756b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    check_convex_bounds(reporter, p, bounds);
16764da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
167762047cf1980861234e7367a225928b84ce492c68reed@google.com
16786b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    p.reset();
16793abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    p.addRect(bounds);
16806b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com    check_convex_bounds(reporter, p, bounds);
168110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    // we have only lines
168210296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_SegmentMask == p.getSegmentMasks());
16834da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    REPORTER_ASSERT(reporter, !p.isEmpty());
16843abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
16853abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p != p2);
16863abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !(p == p2));
16873abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
1688df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    // do getPoints and getVerbs return the right result
1689df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, p.getPoints(NULL, 0) == 4);
1690df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, p.getVerbs(NULL, 0) == 5);
16913abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    SkPoint pts[4];
16923abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    int count = p.getPoints(pts, 4);
16933abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, count == 4);
1694df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    uint8_t verbs[6];
1695df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    verbs[5] = 0xff;
1696df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    p.getVerbs(verbs, 5);
1697df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kMove_Verb == verbs[0]);
1698df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[1]);
1699df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[2]);
1700df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kLine_Verb == verbs[3]);
1701df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, SkPath::kClose_Verb == verbs[4]);
1702df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    REPORTER_ASSERT(reporter, 0xff == verbs[5]);
17033abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds2.set(pts, 4);
17043abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, bounds == bounds2);
170580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
17063abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds.offset(SK_Scalar1*3, SK_Scalar1*4);
17073abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    p.offset(SK_Scalar1*3, SK_Scalar1*4);
1708d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    REPORTER_ASSERT(reporter, bounds == p.getBounds());
17093abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
17103abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.isRect(NULL));
1711f131694617ce0410eafcb01124459382576bb1d9caryclark@google.com    bounds2.setEmpty();
17123abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, p.isRect(&bounds2));
17133abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, bounds == bounds2);
171480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
17153abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    // now force p to not be a rect
17163abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    bounds.set(0, 0, SK_Scalar1/2, SK_Scalar1/2);
17173abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    p.addRect(bounds);
17183abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    REPORTER_ASSERT(reporter, !p.isRect(NULL));
17193abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
17207e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    test_isLine(reporter);
17217e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    test_isRect(reporter);
17224da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    test_zero_length_paths(reporter);
1723cabaf1daf3fdcc151c12d59b05bdbe136c178b3breed@google.com    test_direction(reporter);
172404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    test_convexity(reporter);
17257c42481c9d3f6c71f78cc1fc1d1cb7ac18df2d1breed@google.com    test_convexity2(reporter);
1726b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com    test_close(reporter);
17276630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    test_segment_masks(reporter);
172853effc5e327749ea47bc0c678cb45246644600b0reed@google.com    test_flattening(reporter);
172953effc5e327749ea47bc0c678cb45246644600b0reed@google.com    test_transform(reporter);
17303563c9ee527f524d421964b54d9b09e12ec0bf6breed@google.com    test_bounds(reporter);
17316630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    test_iter(reporter);
17326630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    test_raw_iter(reporter);
17336aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_circle(reporter);
17346aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    test_oval(reporter);
17358b06f1a7ff6d5a59387a90433064550de20787eereed@google.com    test_strokerec(reporter);
1736744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    test_addPoly(reporter);
17370bb18bb264b26afca45452910437c09445e23a3creed@google.com    test_isfinite(reporter);
1738ed02c4d05e3f2ed86dbf4276a69827ab23810598tomhudson@google.com    test_isfinite_after_transform(reporter);
17398cae8358f78b81539f1006afe592a37f1604e67creed@google.com    test_tricky_cubic(reporter);
1740b95eaa8d0842a8bba97f0bc7e19cfd9172d09722robertphillips@google.com    test_arb_round_rect_is_convex(reporter);
1741158618ec62c36b8261e195f04567e09ed76f6534robertphillips@google.com    test_arb_zero_rad_round_rect_is_rect(reporter);
1742a8790debaab6c5e3b6a4a51d2cc91ae5aea9b2ddreed@google.com    test_addrect_isfinite(reporter);
17433abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com}
17443abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com
17453abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com#include "TestClassDef.h"
17463abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.comDEFINE_TESTCLASS("Path", PathTestClass, TestPath)
1747