1da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark/*
2da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark * Copyright 2015 Google Inc.
3da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark *
4da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark * Use of this source code is governed by a BSD-style license that can be
5da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark * found in the LICENSE file.
6da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark */
7da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
8da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark#include "SkMatrix.h"
9da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark#include "SkPath.h"
10da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark#include "SkPathRef.h"
11da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark#include "SkRRect.h"
12da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark#include "Test.h"
13da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
1478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomonstatic SkRRect path_contains_rrect(skiatest::Reporter* reporter, const SkPath& path,
1578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                   SkPath::Direction* dir, unsigned* start) {
16da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    SkRRect out;
1778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    REPORTER_ASSERT(reporter, path.isRRect(&out, dir, start));
1878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkPath recreatedPath;
1978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    recreatedPath.addRRect(out, *dir, *start);
2078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    REPORTER_ASSERT(reporter, path == recreatedPath);
2178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    // Test that rotations/mirrors of the rrect path are still rrect paths and the returned
2278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    // parameters for the transformed paths are correct.
2378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    static const SkMatrix kMatrices[] = {
2478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkMatrix::MakeScale(1, 1),
2578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkMatrix::MakeScale(-1, 1),
2678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkMatrix::MakeScale(1, -1),
2778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkMatrix::MakeScale(-1, -1),
2878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    };
2978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto& m : kMatrices) {
3078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkPath xformed;
3178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        path.transform(m, &xformed);
3278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkRRect xrr = SkRRect::MakeRect(SkRect::MakeEmpty());
3378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkPath::Direction xd = SkPath::kCCW_Direction;
3478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        unsigned xs = ~0U;
3578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        REPORTER_ASSERT(reporter, xformed.isRRect(&xrr, &xd, &xs));
3678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        recreatedPath.reset();
3778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        recreatedPath.addRRect(xrr, xd, xs);
3878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        REPORTER_ASSERT(reporter, recreatedPath == xformed);
39da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
40da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    return out;
41da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
42da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
4378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomonstatic SkRRect inner_path_contains_rrect(skiatest::Reporter* reporter, const SkRRect& in,
4478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                         SkPath::Direction dir, unsigned start) {
45da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    switch (in.getType()) {
46da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark        case SkRRect::kEmpty_Type:
47da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark        case SkRRect::kRect_Type:
48da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark        case SkRRect::kOval_Type:
49da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark            return in;
50da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark        default:
51da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark            break;
52da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
53da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    SkPath path;
5478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.addRRect(in, dir, start);
5578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkPath::Direction outDir;
5678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    unsigned outStart;
5778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkRRect rrect = path_contains_rrect(reporter, path, &outDir, &outStart);
5878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    REPORTER_ASSERT(reporter, outDir == dir && outStart == start);
5978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    return rrect;
60da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
61da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
6278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomonstatic void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRRect& in,
6378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                      SkPath::Direction dir, unsigned start) {
6478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkRRect out = inner_path_contains_rrect(reporter, in, dir, start);
65da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    if (in != out) {
66da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark        SkDebugf("");
67da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
68da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    REPORTER_ASSERT(reporter, in == out);
69da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
70da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
7178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomonstatic void path_contains_rrect_nocheck(skiatest::Reporter* reporter, const SkRRect& in,
7278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                        SkPath::Direction dir, unsigned start) {
7378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkRRect out = inner_path_contains_rrect(reporter, in, dir, start);
74da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    if (in == out) {
75da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark        SkDebugf("");
76da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
77da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
78da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
79da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRect& r,
8078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        SkVector v[4], SkPath::Direction dir, unsigned start) {
81da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    SkRRect rrect;
82da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    rrect.setRectRadii(r, v);
8378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path_contains_rrect_check(reporter, rrect, dir, start);
84da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
85da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
86da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkclass ForceIsRRect_Private {
87da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkpublic:
8878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    ForceIsRRect_Private(SkPath* path, SkPath::Direction dir, unsigned start) {
8978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        path->fPathRef->setIsRRect(true, dir == SkPath::kCCW_Direction, start);
90da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
91da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark};
92da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
9378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomonstatic void force_path_contains_rrect(skiatest::Reporter* reporter, SkPath& path,
9478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                      SkPath::Direction dir, unsigned start) {
9578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    ForceIsRRect_Private force_rrect(&path, dir, start);
9678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkPath::Direction outDir;
9778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    unsigned outStart;
9878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path_contains_rrect(reporter, path, &outDir, &outStart);
9978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    REPORTER_ASSERT(reporter, outDir == dir && outStart == start);
100da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
101da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
102da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_undetected_paths(skiatest::Reporter* reporter) {
10378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    // We use a dummy path to get the exact conic weight used by SkPath for a circular arc. This
10478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    // allows our local, hand-crafted, artisanal round rect paths below to exactly match the
10578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    // factory made corporate paths produced by SkPath.
10678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkPath dummyPath;
10778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    dummyPath.addCircle(0, 0, 10);
10878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkPath::RawIter iter(dummyPath);
10978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkPoint dummyPts[4];
11078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    SkPath::Verb v = iter.next(dummyPts);
11178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    REPORTER_ASSERT(reporter, SkPath::kMove_Verb == v);
11278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    v = iter.next(dummyPts);
11378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    REPORTER_ASSERT(reporter, SkPath::kConic_Verb == v);
11478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    const SkScalar weight = iter.conicWeight();
11578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
116da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    SkPath path;
117da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.moveTo(0, 62.5f);
118da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(0, 3.5f);
11978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(0, 0, 3.5f, 0, weight);
120da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(196.5f, 0);
12178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(200, 0, 200, 3.5f, weight);
122da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(200, 62.5f);
12378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(200, 66, 196.5f, 66, weight);
124da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(3.5f, 66);
12578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(0, 66, 0, 62.5, weight);
126da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.close();
12778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
128da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
129da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.reset();
130da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.moveTo(0, 81.5f);
131da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(0, 3.5f);
13278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(0, 0, 3.5f, 0, weight);
133da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(149.5, 0);
13478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(153, 0, 153, 3.5f, weight);
135da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(153, 81.5f);
13678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(153, 85, 149.5f, 85, weight);
137da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(3.5f, 85);
13878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(0, 85, 0, 81.5f, weight);
139da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.close();
14078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
141da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
142da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.reset();
143da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.moveTo(14, 1189);
144da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(14, 21);
14578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(14, 14, 21, 14, weight);
146da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(1363, 14);
14778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(1370, 14, 1370, 21, weight);
148da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(1370, 1189);
14978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(1370, 1196, 1363, 1196, weight);
150da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(21, 1196);
15178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(14, 1196, 14, 1189, weight);
152da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.close();
15378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
154da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
155da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.reset();
156da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.moveTo(14, 1743);
157da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(14, 21);
15878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(14, 14, 21, 14, weight);
159da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(1363, 14);
16078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(1370, 14, 1370, 21, weight);
161da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(1370, 1743);
16278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(1370, 1750, 1363, 1750, weight);
163da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.lineTo(21, 1750);
16478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    path.conicTo(14, 1750, 14, 1743, weight);
165da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    path.close();
16678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
167da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
168da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
169da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic const SkScalar kWidth = 100.0f;
170da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic const SkScalar kHeight = 100.0f;
171da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
172da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_tricky_radii(skiatest::Reporter* reporter) {
17378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
17478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
17578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            {
17678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                // crbug.com/458522
17778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                SkRRect rr;
17878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 };
17978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                const SkScalar rad = 12814;
18078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                const SkVector vec[] = { { rad, rad }, { 0, rad }, { rad, rad }, { 0, rad } };
18178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                rr.setRectRadii(bounds, vec);
18278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_check(reporter, rr, dir, start);
18378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            }
18478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
18578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            {
18678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                // crbug.com//463920
18778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                SkRect r = SkRect::MakeLTRB(0, 0, 1009, 33554432.0);
18878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                SkVector radii[4] = {
18978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                    { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554432.0 }, { 110.0f, 5.0f }
19078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                };
19178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                SkRRect rr;
19278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                rr.setRectRadii(r, radii);
19378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_nocheck(reporter, rr, dir, start);
19478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            }
19578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
196da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
197da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
198da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
199da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_empty_crbug_458524(skiatest::Reporter* reporter) {
20078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
20178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
20278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr;
20378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 };
20478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            const SkScalar rad = 40;
20578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.setRectXY(bounds, rad, rad);
20678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
20778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
20878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect other;
20978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkMatrix matrix;
21078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            matrix.setScale(0, 1);
21178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.transform(matrix, &other);
21278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
21378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
21478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    }
215da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
216da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
217da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_inset(skiatest::Reporter* reporter) {
21878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
21978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
22078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr, rr2;
22178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRect r = { 0, 0, 100, 100 };
22278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
22378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.setRect(r);
22478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.inset(-20, -20, &rr2);
22578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
22678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
22778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.inset(20, 20, &rr2);
22878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
22978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
23078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.inset(r.width()/2, r.height()/2, &rr2);
23178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
23278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
23378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.setRectXY(r, 20, 20);
23478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.inset(19, 19, &rr2);
23578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
23678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.inset(20, 20, &rr2);
23778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
23878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
23978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    }
240da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
241da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
242da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
243da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_9patch_rrect(skiatest::Reporter* reporter,
244da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark                              const SkRect& rect,
245da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark                              SkScalar l, SkScalar t, SkScalar r, SkScalar b,
246da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark                              bool checkRadii) {
24778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
24878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
24978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr;
25078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.setNinePatch(rect, l, t, r, b);
25178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            if (checkRadii) {
25278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_check(reporter, rr, dir, start);
25378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            } else {
25478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_nocheck(reporter, rr, dir, start);
25578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            }
25678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
25778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr2; // construct the same RR using the most general set function
25878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkVector radii[4] = { { l, t }, { r, t }, { r, b }, { l, b } };
25978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr2.setRectRadii(rect, radii);
26078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            if (checkRadii) {
26178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_check(reporter, rr, dir, start);
26278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            } else {
26378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_nocheck(reporter, rr, dir, start);
26478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            }
26578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
266da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
267da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
268da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
269da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark// Test out the basic API entry points
270da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_round_rect_basic(skiatest::Reporter* reporter) {
27178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
27278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
27378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
27478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
27578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
27678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr1;
27778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr1.setRect(rect);
27878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr1, dir, start);
27978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
28078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr1_2; // construct the same RR using the most general set function
28178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkVector rr1_2_radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
28278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr1_2.setRectRadii(rect, rr1_2_radii);
28378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr1_2, dir, start);
28478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr1_3;  // construct the same RR using the nine patch set function
28578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr1_3.setNinePatch(rect, 0, 0, 0, 0);
28678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr1_2, dir, start);
28778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
28878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
28978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkPoint halfPoint = { SkScalarHalf(kWidth), SkScalarHalf(kHeight) };
29078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr2;
29178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr2.setOval(rect);
29278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr2, dir, start);
29378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
29478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr2_2;  // construct the same RR using the most general set function
29578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkVector rr2_2_radii[4] = { { halfPoint.fX, halfPoint.fY },
29678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                        { halfPoint.fX, halfPoint.fY },
29778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                        { halfPoint.fX, halfPoint.fY },
29878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                        { halfPoint.fX, halfPoint.fY } };
29978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr2_2.setRectRadii(rect, rr2_2_radii);
30078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr2_2, dir, start);
30178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr2_3;  // construct the same RR using the nine patch set function
30278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr2_3.setNinePatch(rect, halfPoint.fX, halfPoint.fY, halfPoint.fX, halfPoint.fY);
30378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr2_3, dir, start);
30478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
30578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
30678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkPoint p = { 5, 5 };
30778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr3;
30878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr3.setRectXY(rect, p.fX, p.fY);
30978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr3, dir, start);
31078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
31178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr3_2; // construct the same RR using the most general set function
31278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkVector rr3_2_radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } };
31378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr3_2.setRectRadii(rect, rr3_2_radii);
31478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr3_2, dir, start);
31578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr3_3;  // construct the same RR using the nine patch set function
31678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr3_3.setNinePatch(rect, 5, 5, 5, 5);
31778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr3_3, dir, start);
31878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
31978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
32078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            test_9patch_rrect(reporter, rect, 10, 9, 8, 7, true);
32178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
32278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            {
32378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                // Test out the rrect from skia:3466
32478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                SkRect rect2 = SkRect::MakeLTRB(0.358211994f, 0.755430222f, 0.872866154f,
32578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                                0.806214333f);
32678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
32778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                test_9patch_rrect(reporter,
32878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                  rect2,
32978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                  0.926942348f, 0.642850280f, 0.529063463f, 0.587844372f,
33078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                                  false);
33178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            }
33278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
33378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
33478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkPoint radii2[4] = { { 0, 0 }, { 0, 0 }, { 50, 50 }, { 20, 50 } };
33578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
33678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr5;
33778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr5.setRectRadii(rect, radii2);
33878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr5, dir, start);
33978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
340da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
341da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
342da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
343da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark// Test out the cases when the RR degenerates to a rect
344da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_round_rect_rects(skiatest::Reporter* reporter) {
34578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
34678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
34778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
34878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
34978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr1;
35078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr1.setRectXY(rect, 0, 0);
351da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
35278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr1, dir, start);
353da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
35478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
35578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkPoint radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
356da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
35778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr2;
35878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr2.setRectRadii(rect, radii);
359da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
36078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr2, dir, start);
361da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
36278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
36378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkPoint radii2[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } };
364da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
36578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr3;
36678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr3.setRectRadii(rect, radii2);
36778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr3, dir, start);
36878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
36978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    }
370da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
371da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
372da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark// Test out the cases when the RR degenerates to an oval
373da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_round_rect_ovals(skiatest::Reporter* reporter) {
37478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
37578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
37678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
37778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
37878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr1;
37978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr1.setRectXY(rect, SkScalarHalf(kWidth), SkScalarHalf(kHeight));
38078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon
38178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr1, dir, start);
38278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
38378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    }
384da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
385da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
386da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark// Test out the non-degenerate RR cases
387da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_round_rect_general(skiatest::Reporter* reporter) {
38878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
38978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
39078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
39178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
39278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr1;
39378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr1.setRectXY(rect, 20, 20);
394da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
39578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr1, dir, start);
396da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
39778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            //----
39878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkPoint radii[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } };
399da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
40078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr2;
40178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr2.setRectRadii(rect, radii);
402da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
40378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr2, dir, start);
40478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
40578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    }
406da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
407da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
408da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) {
40978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
41078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
41178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
41278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 50 } };
41378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr1;
41478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr1.setRectRadii(rect, radii);
41578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_nocheck(reporter, rr1, dir, start);
41678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
41778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    }
418da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
419da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
420da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void set_radii(SkVector radii[4], int index, float rad) {
421da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    sk_bzero(radii, sizeof(SkVector) * 4);
422da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    radii[index].set(rad, rad);
423da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
424da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
425da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_skbug_3239(skiatest::Reporter* reporter) {
426da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    const float min = SkBits2Float(0xcb7f16c8); /* -16717512.000000 */
427da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    const float max = SkBits2Float(0x4b7f1c1d); /*  16718877.000000 */
428da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    const float big = SkBits2Float(0x4b7f1bd7); /*  16718807.000000 */
429da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
430da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    const float rad = 33436320;
431da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
432da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    const SkRect rectx = SkRect::MakeLTRB(min, min, max, big);
433da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    const SkRect recty = SkRect::MakeLTRB(min, min, big, max);
434da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
43578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
43678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
43778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkVector radii[4];
43878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            for (int i = 0; i < 4; ++i) {
43978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                set_radii(radii, i, rad);
44078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_check(reporter, rectx, radii, dir, start);
44178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon                path_contains_rrect_check(reporter, recty, radii, dir, start);
44278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            }
44378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
444da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    }
445da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
446da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
447da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkstatic void test_mix(skiatest::Reporter* reporter) {
44878d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
44978d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        for (int start = 0; start < 8; ++start) {
45078d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            // Test out mixed degenerate and non-degenerate geometry with Conics
45178d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } };
45278d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRect r = SkRect::MakeWH(100, 100);
45378d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            SkRRect rr;
45478d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            rr.setRectRadii(r, radii);
45578d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon            path_contains_rrect_check(reporter, rr, dir, start);
45678d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon        }
45778d58d1084f0390c1c0f9123ac6e48efcd226f39bsalomon    }
458da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
459da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark
460da707bf5635c70d4c3c284a0b05d92489b76788ecaryclarkDEF_TEST(RoundRectInPath, reporter) {
461da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_tricky_radii(reporter);
462da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_empty_crbug_458524(reporter);
463da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_inset(reporter);
464da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_round_rect_basic(reporter);
465da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_round_rect_rects(reporter);
466da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_round_rect_ovals(reporter);
467da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_round_rect_general(reporter);
468da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_undetected_paths(reporter);
469da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_round_rect_iffy_parameters(reporter);
470da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_skbug_3239(reporter);
471da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark    test_mix(reporter);
472da707bf5635c70d4c3c284a0b05d92489b76788ecaryclark}
473