Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
MidpointContourParser.h
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC.
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 skgpu_tessellate_MidpointContourParser_DEFINED
9#define skgpu_tessellate_MidpointContourParser_DEFINED
10
11#include "include/core/SkPath.h"
13#include "src/core/SkPathPriv.h"
14
15#include <cstdint>
16
17namespace skgpu::tess {
18
19// Parses out each contour in a path and tracks the midpoint. Example usage:
20//
21// MidpointContourParser parser;
22// while (parser.parseNextContour()) {
23// SkPoint midpoint = parser.currentMidpoint();
24// for (auto [verb, pts] : parser.currentContour()) {
25// ...
26// }
27// }
28//
30public:
32 : fPath(path)
33 , fVerbs(SkPathPriv::VerbData(fPath))
34 , fNumRemainingVerbs(fPath.countVerbs())
35 , fPoints(SkPathPriv::PointData(fPath))
36 , fWeights(SkPathPriv::ConicWeightData(fPath)) {}
37 // Advances the internal state to the next contour in the path. Returns false if there are no
38 // more contours.
40 bool hasGeometry = false;
41 for (; fVerbsIdx < fNumRemainingVerbs; ++fVerbsIdx) {
42 switch (fVerbs[fVerbsIdx]) {
44 if (!hasGeometry) {
45 fMidpoint = {0,0};
46 fMidpointWeight = 0;
47 this->advance(); // Resets fPtsIdx to 0 and advances fPoints.
48 fPtsIdx = 1; // Increment fPtsIdx past the kMove.
49 continue;
50 }
51 if (fPoints[0] != fPoints[fPtsIdx - 1]) {
52 // There's an implicit close at the end. Add the start point to our mean.
53 fMidpoint += fPoints[0];
54 ++fMidpointWeight;
55 }
56 return true;
57 default:
58 continue;
60 ++fPtsIdx;
61 break;
63 ++fWtsIdx;
64 [[fallthrough]];
66 fPtsIdx += 2;
67 break;
69 fPtsIdx += 3;
70 break;
71 }
72 fMidpoint += fPoints[fPtsIdx - 1];
73 ++fMidpointWeight;
74 hasGeometry = true;
75 }
76 if (hasGeometry && fPoints[0] != fPoints[fPtsIdx - 1]) {
77 // There's an implicit close at the end. Add the start point to our mean.
78 fMidpoint += fPoints[0];
79 ++fMidpointWeight;
80 }
81 return hasGeometry;
82 }
83
84 // Allows for iterating the current contour using a range-for loop.
86 return SkPathPriv::Iterate(fVerbs, fVerbs + fVerbsIdx, fPoints, fWeights);
87 }
88
89 SkPoint currentMidpoint() { return fMidpoint * (1.f / fMidpointWeight); }
90
91private:
92 void advance() {
93 fVerbs += fVerbsIdx;
94 fNumRemainingVerbs -= fVerbsIdx;
95 fVerbsIdx = 0;
96 fPoints += fPtsIdx;
97 fPtsIdx = 0;
98 fWeights += fWtsIdx;
99 fWtsIdx = 0;
100 }
101
102 const SkPath& fPath;
103
104 const uint8_t* fVerbs;
105 int fNumRemainingVerbs = 0;
106 int fVerbsIdx = 0;
107
108 const SkPoint* fPoints;
109 int fPtsIdx = 0;
110
111 const float* fWeights;
112 int fWtsIdx = 0;
113
114 SkPoint fMidpoint;
115 int fMidpointWeight;
116};
117
118} // namespace skgpu::tess
119
120#endif // skgpu_tessellate_MidpointContourParser_DEFINED
@ kMove_Verb
Definition SkPath.h:1458
@ kConic_Verb
Definition SkPath.h:1461
@ kCubic_Verb
Definition SkPath.h:1462
@ kQuad_Verb
Definition SkPath.h:1460
@ kLine_Verb
Definition SkPath.h:1459