138 lines
4.2 KiB
C++
138 lines
4.2 KiB
C++
|
/*
|
||
|
* Copyright 2020 Google Inc.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license that can be
|
||
|
* found in the LICENSE file.
|
||
|
*/
|
||
|
|
||
|
#include "include/utils/SkRandom.h"
|
||
|
#include "src/core/SkPathPriv.h"
|
||
|
#include "tests/Test.h"
|
||
|
|
||
|
SkPoint next_point(SkRandom& rand) { return {rand.nextF(), rand.nextF()}; }
|
||
|
|
||
|
DEF_TEST(SkPath_RangeIter, r) {
|
||
|
enum class Verb {
|
||
|
kMove = (int)SkPathVerb::kMove,
|
||
|
kLine = (int)SkPathVerb::kLine,
|
||
|
kQuad = (int)SkPathVerb::kQuad,
|
||
|
kConic = (int)SkPathVerb::kConic,
|
||
|
kCubic = (int)SkPathVerb::kCubic,
|
||
|
kClose = (int)SkPathVerb::kClose,
|
||
|
kImplicitMove
|
||
|
};
|
||
|
|
||
|
Verb verbs[] = {
|
||
|
Verb::kImplicitMove,
|
||
|
Verb::kLine,
|
||
|
Verb::kConic,
|
||
|
Verb::kClose,
|
||
|
Verb::kImplicitMove,
|
||
|
Verb::kCubic,
|
||
|
Verb::kMove,
|
||
|
Verb::kConic,
|
||
|
Verb::kLine,
|
||
|
Verb::kClose,
|
||
|
Verb::kMove,
|
||
|
Verb::kMove
|
||
|
};
|
||
|
|
||
|
class : SkRandom {
|
||
|
public:
|
||
|
SkPoint p() { return {this->SkRandom::nextF(), this->SkRandom::nextF()}; }
|
||
|
float w() { return this->SkRandom::nextF(); }
|
||
|
} genData, testData;
|
||
|
|
||
|
for (int i = 0; i < 10; ++i) {
|
||
|
if (genData.p() != testData.p() || genData.w() != testData.w()) {
|
||
|
ERRORF(r, "genData and testData not in sync.");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Build the path.
|
||
|
SkPath path;
|
||
|
for (Verb verb : verbs) {
|
||
|
switch (verb) {
|
||
|
case Verb::kImplicitMove:
|
||
|
break;
|
||
|
case Verb::kMove:
|
||
|
path.moveTo(genData.p());
|
||
|
break;
|
||
|
case Verb::kLine:
|
||
|
path.lineTo(genData.p());
|
||
|
break;
|
||
|
case Verb::kQuad: {
|
||
|
auto a = genData.p();
|
||
|
auto b = genData.p();
|
||
|
path.quadTo(a, b);
|
||
|
break;
|
||
|
}
|
||
|
case Verb::kCubic: {
|
||
|
auto a = genData.p();
|
||
|
auto b = genData.p();
|
||
|
auto c = genData.p();
|
||
|
path.cubicTo(a, b, c);
|
||
|
break;
|
||
|
}
|
||
|
case Verb::kConic: {
|
||
|
auto a = genData.p();
|
||
|
auto b = genData.p();
|
||
|
path.conicTo(a, b, genData.w());
|
||
|
break;
|
||
|
}
|
||
|
case Verb::kClose:
|
||
|
path.close();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Verify sure the RangeIter works as expected.
|
||
|
SkPathPriv::Iterate iterate(path);
|
||
|
auto iter = iterate.begin();
|
||
|
SkPoint startPt = {0,0};
|
||
|
SkPoint lastPt = {0,0};
|
||
|
for (Verb verb : verbs) {
|
||
|
auto [pathVerb, pathPts, pathWt] = *iter++;
|
||
|
switch (verb) {
|
||
|
case Verb::kImplicitMove:
|
||
|
REPORTER_ASSERT(r, pathPts[0] == startPt);
|
||
|
lastPt = pathPts[0];
|
||
|
break;
|
||
|
case Verb::kMove:
|
||
|
REPORTER_ASSERT(r, pathPts[0] == testData.p());
|
||
|
startPt = lastPt = pathPts[0];
|
||
|
break;
|
||
|
case Verb::kLine:
|
||
|
REPORTER_ASSERT(r, pathPts[0] == lastPt);
|
||
|
REPORTER_ASSERT(r, pathPts[1] == testData.p());
|
||
|
lastPt = pathPts[1];
|
||
|
break;
|
||
|
case Verb::kQuad:
|
||
|
REPORTER_ASSERT(r, pathPts[0] == lastPt);
|
||
|
REPORTER_ASSERT(r, pathPts[1] == testData.p());
|
||
|
REPORTER_ASSERT(r, pathPts[2] == testData.p());
|
||
|
lastPt = pathPts[2];
|
||
|
break;
|
||
|
case Verb::kCubic:
|
||
|
REPORTER_ASSERT(r, pathPts[0] == lastPt);
|
||
|
REPORTER_ASSERT(r, pathPts[1] == testData.p());
|
||
|
REPORTER_ASSERT(r, pathPts[2] == testData.p());
|
||
|
REPORTER_ASSERT(r, pathPts[3] == testData.p());
|
||
|
lastPt = pathPts[3];
|
||
|
break;
|
||
|
case Verb::kConic:
|
||
|
REPORTER_ASSERT(r, pathPts[0] == lastPt);
|
||
|
REPORTER_ASSERT(r, pathPts[1] == testData.p());
|
||
|
REPORTER_ASSERT(r, pathPts[2] == testData.p());
|
||
|
REPORTER_ASSERT(r, *pathWt == testData.w());
|
||
|
lastPt = pathPts[2];
|
||
|
break;
|
||
|
case Verb::kClose:
|
||
|
REPORTER_ASSERT(r, pathPts[0] == lastPt);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
REPORTER_ASSERT(r, iter == iterate.end());
|
||
|
}
|