Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4c1fb1c

Browse files
csmartdalton86Skia Commit-Bot
authored andcommitted
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>
1 parent 65fb101 commit 4c1fb1c

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

gn/tests.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ tests_sources = [
259259
"$_tests/SkGlyphTest.cpp",
260260
"$_tests/SkImageTest.cpp",
261261
"$_tests/SkNxTest.cpp",
262+
"$_tests/SkPathRangeIterTest.cpp",
262263
"$_tests/SkRasterPipelineTest.cpp",
263264
"$_tests/SkRemoteGlyphCacheTest.cpp",
264265
"$_tests/SkResourceCacheTest.cpp",

include/core/SkPath.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,7 @@ class SK_API SkPath {
15961596
case SkPathVerb::kQuad: return -1;
15971597
case SkPathVerb::kConic: return -1;
15981598
case SkPathVerb::kCubic: return -1;
1599-
case SkPathVerb::kClose: return 0;
1599+
case SkPathVerb::kClose: return -1;
16001600
}
16011601
SkUNREACHABLE;
16021602
}

tests/SkPathRangeIterTest.cpp

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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+
12+
SkPoint next_point(SkRandom& rand) { return {rand.nextF(), rand.nextF()}; }
13+
14+
DEF_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+
}

0 commit comments

Comments
 (0)