1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2020 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h"
9cb93a386Sopenharmony_ci#include "src/core/SkPathPriv.h"
10cb93a386Sopenharmony_ci#include "tests/Test.h"
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ciSkPoint next_point(SkRandom& rand) { return {rand.nextF(), rand.nextF()}; }
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ciDEF_TEST(SkPath_RangeIter, r) {
15cb93a386Sopenharmony_ci    enum class Verb {
16cb93a386Sopenharmony_ci        kMove = (int)SkPathVerb::kMove,
17cb93a386Sopenharmony_ci        kLine = (int)SkPathVerb::kLine,
18cb93a386Sopenharmony_ci        kQuad = (int)SkPathVerb::kQuad,
19cb93a386Sopenharmony_ci        kConic = (int)SkPathVerb::kConic,
20cb93a386Sopenharmony_ci        kCubic = (int)SkPathVerb::kCubic,
21cb93a386Sopenharmony_ci        kClose = (int)SkPathVerb::kClose,
22cb93a386Sopenharmony_ci        kImplicitMove
23cb93a386Sopenharmony_ci    };
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ci    Verb verbs[] = {
26cb93a386Sopenharmony_ci        Verb::kImplicitMove,
27cb93a386Sopenharmony_ci        Verb::kLine,
28cb93a386Sopenharmony_ci        Verb::kConic,
29cb93a386Sopenharmony_ci        Verb::kClose,
30cb93a386Sopenharmony_ci        Verb::kImplicitMove,
31cb93a386Sopenharmony_ci        Verb::kCubic,
32cb93a386Sopenharmony_ci        Verb::kMove,
33cb93a386Sopenharmony_ci        Verb::kConic,
34cb93a386Sopenharmony_ci        Verb::kLine,
35cb93a386Sopenharmony_ci        Verb::kClose,
36cb93a386Sopenharmony_ci        Verb::kMove,
37cb93a386Sopenharmony_ci        Verb::kMove
38cb93a386Sopenharmony_ci    };
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci    class : SkRandom {
41cb93a386Sopenharmony_ci    public:
42cb93a386Sopenharmony_ci        SkPoint p() { return {this->SkRandom::nextF(), this->SkRandom::nextF()}; }
43cb93a386Sopenharmony_ci        float w() { return this->SkRandom::nextF(); }
44cb93a386Sopenharmony_ci    } genData, testData;
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ci    for (int i = 0; i < 10; ++i) {
47cb93a386Sopenharmony_ci        if (genData.p() != testData.p() || genData.w() != testData.w()) {
48cb93a386Sopenharmony_ci            ERRORF(r, "genData and testData not in sync.");
49cb93a386Sopenharmony_ci            return;
50cb93a386Sopenharmony_ci        }
51cb93a386Sopenharmony_ci    }
52cb93a386Sopenharmony_ci
53cb93a386Sopenharmony_ci    // Build the path.
54cb93a386Sopenharmony_ci    SkPath path;
55cb93a386Sopenharmony_ci    for (Verb verb : verbs) {
56cb93a386Sopenharmony_ci        switch (verb) {
57cb93a386Sopenharmony_ci            case Verb::kImplicitMove:
58cb93a386Sopenharmony_ci                break;
59cb93a386Sopenharmony_ci            case Verb::kMove:
60cb93a386Sopenharmony_ci                path.moveTo(genData.p());
61cb93a386Sopenharmony_ci                break;
62cb93a386Sopenharmony_ci            case Verb::kLine:
63cb93a386Sopenharmony_ci                path.lineTo(genData.p());
64cb93a386Sopenharmony_ci                break;
65cb93a386Sopenharmony_ci            case Verb::kQuad: {
66cb93a386Sopenharmony_ci                auto a = genData.p();
67cb93a386Sopenharmony_ci                auto b = genData.p();
68cb93a386Sopenharmony_ci                path.quadTo(a, b);
69cb93a386Sopenharmony_ci                break;
70cb93a386Sopenharmony_ci            }
71cb93a386Sopenharmony_ci            case Verb::kCubic: {
72cb93a386Sopenharmony_ci                auto a = genData.p();
73cb93a386Sopenharmony_ci                auto b = genData.p();
74cb93a386Sopenharmony_ci                auto c = genData.p();
75cb93a386Sopenharmony_ci                path.cubicTo(a, b, c);
76cb93a386Sopenharmony_ci                break;
77cb93a386Sopenharmony_ci            }
78cb93a386Sopenharmony_ci            case Verb::kConic: {
79cb93a386Sopenharmony_ci                auto a = genData.p();
80cb93a386Sopenharmony_ci                auto b = genData.p();
81cb93a386Sopenharmony_ci                path.conicTo(a, b, genData.w());
82cb93a386Sopenharmony_ci                break;
83cb93a386Sopenharmony_ci            }
84cb93a386Sopenharmony_ci            case Verb::kClose:
85cb93a386Sopenharmony_ci                path.close();
86cb93a386Sopenharmony_ci                break;
87cb93a386Sopenharmony_ci        }
88cb93a386Sopenharmony_ci    }
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci    // Verify sure the RangeIter works as expected.
91cb93a386Sopenharmony_ci    SkPathPriv::Iterate iterate(path);
92cb93a386Sopenharmony_ci    auto iter = iterate.begin();
93cb93a386Sopenharmony_ci    SkPoint startPt = {0,0};
94cb93a386Sopenharmony_ci    SkPoint lastPt = {0,0};
95cb93a386Sopenharmony_ci    for (Verb verb : verbs) {
96cb93a386Sopenharmony_ci        auto [pathVerb, pathPts, pathWt] = *iter++;
97cb93a386Sopenharmony_ci        switch (verb) {
98cb93a386Sopenharmony_ci            case Verb::kImplicitMove:
99cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[0] == startPt);
100cb93a386Sopenharmony_ci                lastPt = pathPts[0];
101cb93a386Sopenharmony_ci                break;
102cb93a386Sopenharmony_ci            case Verb::kMove:
103cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[0] == testData.p());
104cb93a386Sopenharmony_ci                startPt = lastPt = pathPts[0];
105cb93a386Sopenharmony_ci                break;
106cb93a386Sopenharmony_ci            case Verb::kLine:
107cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[0] == lastPt);
108cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[1] == testData.p());
109cb93a386Sopenharmony_ci                lastPt = pathPts[1];
110cb93a386Sopenharmony_ci                break;
111cb93a386Sopenharmony_ci            case Verb::kQuad:
112cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[0] == lastPt);
113cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[1] == testData.p());
114cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[2] == testData.p());
115cb93a386Sopenharmony_ci                lastPt = pathPts[2];
116cb93a386Sopenharmony_ci                break;
117cb93a386Sopenharmony_ci            case Verb::kCubic:
118cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[0] == lastPt);
119cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[1] == testData.p());
120cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[2] == testData.p());
121cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[3] == testData.p());
122cb93a386Sopenharmony_ci                lastPt = pathPts[3];
123cb93a386Sopenharmony_ci                break;
124cb93a386Sopenharmony_ci            case Verb::kConic:
125cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[0] == lastPt);
126cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[1] == testData.p());
127cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[2] == testData.p());
128cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, *pathWt == testData.w());
129cb93a386Sopenharmony_ci                lastPt = pathPts[2];
130cb93a386Sopenharmony_ci                break;
131cb93a386Sopenharmony_ci            case Verb::kClose:
132cb93a386Sopenharmony_ci                REPORTER_ASSERT(r, pathPts[0] == lastPt);
133cb93a386Sopenharmony_ci                break;
134cb93a386Sopenharmony_ci        }
135cb93a386Sopenharmony_ci    }
136cb93a386Sopenharmony_ci    REPORTER_ASSERT(r, iter == iterate.end());
137cb93a386Sopenharmony_ci}
138