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 // 23 class GrMidpointContourParser { 24 public: GrMidpointContourParser(const SkPath & path)25 GrMidpointContourParser(const SkPath& path) 26 : fPath(path) 27 , fVerbs(SkPathPriv::VerbData(fPath)) 28 , fNumRemainingVerbs(fPath.countVerbs()) 29 , fPoints(SkPathPriv::PointData(fPath)) 30 , fWeights(SkPathPriv::ConicWeightData(fPath)) {} 31 // Advances the internal state to the next contour in the path. Returns false if there are no 32 // more contours. parseNextContour()33 bool parseNextContour() { 34 bool hasGeometry = false; 35 for (; fVerbsIdx < fNumRemainingVerbs; ++fVerbsIdx) { 36 switch (fVerbs[fVerbsIdx]) { 37 case SkPath::kMove_Verb: 38 if (!hasGeometry) { 39 fMidpoint = fPoints[fPtsIdx]; 40 fMidpointWeight = 1; 41 this->advance(); 42 ++fPtsIdx; 43 continue; 44 } 45 return true; 46 default: 47 continue; 48 case SkPath::kLine_Verb: 49 ++fPtsIdx; 50 break; 51 case SkPath::kConic_Verb: 52 ++fWtsIdx; 53 [[fallthrough]]; 54 case SkPath::kQuad_Verb: 55 fPtsIdx += 2; 56 break; 57 case SkPath::kCubic_Verb: 58 fPtsIdx += 3; 59 break; 60 } 61 fMidpoint += fPoints[fPtsIdx - 1]; 62 ++fMidpointWeight; 63 hasGeometry = true; 64 } 65 return hasGeometry; 66 } 67 68 // Allows for iterating the current contour using a range-for loop. currentContour()69 SkPathPriv::Iterate currentContour() { 70 return SkPathPriv::Iterate(fVerbs, fVerbs + fVerbsIdx, fPoints, fWeights); 71 } 72 currentMidpoint()73 SkPoint currentMidpoint() { return fMidpoint * (1.f / fMidpointWeight); } 74 75 private: advance()76 void advance() { 77 fVerbs += fVerbsIdx; 78 fNumRemainingVerbs -= fVerbsIdx; 79 fVerbsIdx = 0; 80 fPoints += fPtsIdx; 81 fPtsIdx = 0; 82 fWeights += fWtsIdx; 83 fWtsIdx = 0; 84 } 85 86 const SkPath& fPath; 87 88 const uint8_t* fVerbs; 89 int fNumRemainingVerbs = 0; 90 int fVerbsIdx = 0; 91 92 const SkPoint* fPoints; 93 int fPtsIdx = 0; 94 95 const float* fWeights; 96 int fWtsIdx = 0; 97 98 SkPoint fMidpoint; 99 int fMidpointWeight; 100 }; 101 102 #endif 103