2 * Copyright 2022 Google LLC.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef skgpu_tessellate_MidpointContourParser_DEFINED
9 #define skgpu_tessellate_MidpointContourParser_DEFINED
11 #include "include/core/SkPath.h"
12 #include "src/core/SkPathPriv.h"
14 namespace skgpu::tess {
16 // Parses out each contour in a path and tracks the midpoint. Example usage:
18 // MidpointContourParser parser;
19 // while (parser.parseNextContour()) {
20 // SkPoint midpoint = parser.currentMidpoint();
21 // for (auto [verb, pts] : parser.currentContour()) {
26 class MidpointContourParser {
28 MidpointContourParser(const SkPath& path)
30 , fVerbs(SkPathPriv::VerbData(fPath))
31 , fNumRemainingVerbs(fPath.countVerbs())
32 , fPoints(SkPathPriv::PointData(fPath))
33 , fWeights(SkPathPriv::ConicWeightData(fPath)) {}
34 // Advances the internal state to the next contour in the path. Returns false if there are no
36 bool parseNextContour() {
37 bool hasGeometry = false;
38 for (; fVerbsIdx < fNumRemainingVerbs; ++fVerbsIdx) {
39 switch (fVerbs[fVerbsIdx]) {
40 case SkPath::kMove_Verb:
44 this->advance(); // Resets fPtsIdx to 0 and advances fPoints.
45 fPtsIdx = 1; // Increment fPtsIdx past the kMove.
48 if (fPoints[0] != fPoints[fPtsIdx - 1]) {
49 // There's an implicit close at the end. Add the start point to our mean.
50 fMidpoint += fPoints[0];
56 case SkPath::kLine_Verb:
59 case SkPath::kConic_Verb:
62 case SkPath::kQuad_Verb:
65 case SkPath::kCubic_Verb:
69 fMidpoint += fPoints[fPtsIdx - 1];
73 if (hasGeometry && fPoints[0] != fPoints[fPtsIdx - 1]) {
74 // There's an implicit close at the end. Add the start point to our mean.
75 fMidpoint += fPoints[0];
81 // Allows for iterating the current contour using a range-for loop.
82 SkPathPriv::Iterate currentContour() {
83 return SkPathPriv::Iterate(fVerbs, fVerbs + fVerbsIdx, fPoints, fWeights);
86 SkPoint currentMidpoint() { return fMidpoint * (1.f / fMidpointWeight); }
91 fNumRemainingVerbs -= fVerbsIdx;
101 const uint8_t* fVerbs;
102 int fNumRemainingVerbs = 0;
105 const SkPoint* fPoints;
108 const float* fWeights;
115 } // namespace skgpu::tess
117 #endif // skgpu_tessellate_MidpointContourParser_DEFINED