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#ifndef GrMidpointContourParser_DEFINED
9#define GrMidpointContourParser_DEFINED
10
11#include "src/core/SkPathPriv.h"
12
13// Parses out each contour in a path and tracks the midpoint. Example usage:
14//
15// SkTPathContourParser parser;
16// while (parser.parseNextContour()) {
17// SkPoint midpoint = parser.currentMidpoint();
18// for (auto [verb, pts] : parser.currentContour()) {
19// ...
20// }
21// }
22//
23class GrMidpointContourParser {
24public:
25 GrMidpointContourParser(const SkPath& path)
26 : fPath(path)
27 , fVerbs(SkPathPriv::VerbData(fPath))
28 , fNumRemainingVerbs(fPath.countVerbs())
29 , fPoints(SkPathPriv::PointData(fPath)) {}
30 // Advances the internal state to the next contour in the path. Returns false if there are no
31 // more contours.
32 bool parseNextContour() {
33 bool hasGeometry = false;
34 for (; fVerbsIdx < fNumRemainingVerbs; ++fVerbsIdx) {
35 switch (fVerbs[fVerbsIdx]) {
36 case SkPath::kMove_Verb:
37 if (!hasGeometry) {
38 fMidpoint = fPoints[fPtsIdx];
39 fMidpointWeight = 1;
40 this->advance();
41 ++fPtsIdx;
42 continue;
43 }
44 return true;
45 default:
46 continue;
47 case SkPath::kLine_Verb:
48 ++fPtsIdx;
49 break;
50 case SkPath::kQuad_Verb:
51 case SkPath::kConic_Verb:
52 fPtsIdx += 2;
53 break;
54 case SkPath::kCubic_Verb:
55 fPtsIdx += 3;
56 break;
57 }
58 fMidpoint += fPoints[fPtsIdx - 1];
59 ++fMidpointWeight;
60 hasGeometry = true;
61 }
62 return hasGeometry;
63 }
64
65 // Allows for iterating the current contour using a range-for loop.
66 SkPathPriv::Iterate currentContour() {
67 return SkPathPriv::Iterate(fVerbs, fVerbs + fVerbsIdx, fPoints, nullptr);
68 }
69
70 SkPoint currentMidpoint() { return fMidpoint * (1.f / fMidpointWeight); }
71
72private:
73 void advance() {
74 fVerbs += fVerbsIdx;
75 fNumRemainingVerbs -= fVerbsIdx;
76 fVerbsIdx = 0;
77 fPoints += fPtsIdx;
78 fPtsIdx = 0;
79 }
80
81 const SkPath& fPath;
82
83 const uint8_t* fVerbs;
84 int fNumRemainingVerbs = 0;
85 int fVerbsIdx = 0;
86
87 const SkPoint* fPoints;
88 int fPtsIdx = 0;
89
90 SkPoint fMidpoint;
91 int fMidpointWeight;
92};
93
94#endif
95