Return the contour's final point from SkPath::RangeIter in kClose

This point is located at fPoints[-1]. We might as well provide it
since it's free, and the stroke iterators for indirect tessellation
will be able to use it.

Bug: skia:10419
Change-Id: If0161a18a9a5a0f3b118a99d7c090d79d424f9db
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/337637
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Chris Dalton 2020-11-23 11:33:22 -07:00 committed by Skia Commit-Bot
parent 65fb101861
commit 4c1fb1c27a
3 changed files with 139 additions and 1 deletions

View File

@ -259,6 +259,7 @@ tests_sources = [
"$_tests/SkGlyphTest.cpp",
"$_tests/SkImageTest.cpp",
"$_tests/SkNxTest.cpp",
"$_tests/SkPathRangeIterTest.cpp",
"$_tests/SkRasterPipelineTest.cpp",
"$_tests/SkRemoteGlyphCacheTest.cpp",
"$_tests/SkResourceCacheTest.cpp",

View File

@ -1596,7 +1596,7 @@ private:
case SkPathVerb::kQuad: return -1;
case SkPathVerb::kConic: return -1;
case SkPathVerb::kCubic: return -1;
case SkPathVerb::kClose: return 0;
case SkPathVerb::kClose: return -1;
}
SkUNREACHABLE;
}

View File

@ -0,0 +1,137 @@
/*
* 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());
}