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/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} 138