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