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