| /* |
| * Copyright 2025 Google LLC. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "include/core/SkPathIter.h" |
| |
| /* |
| * Close is funny -- it has no explicit point data, but we return 2 points, |
| * the logical 2 points that would make up the line connecting the end of |
| * the contour, and its beginning. |
| * |
| * To do this, we have local storage (fClosePointStorage) |
| */ |
| std::optional<SkPathIter::Rec> SkPathIter::next() { |
| if (vIndex >= fVerbs.size()) { |
| return {}; |
| } |
| |
| size_t n = 0; |
| |
| float w = -1; |
| SkPathVerb v; |
| switch (v = fVerbs[vIndex++]) { |
| case SkPathVerb::kMove: |
| fClosePointStorage[1] = fPoints[pIndex++]; // remember for close |
| return Rec{{&fClosePointStorage[1], 1}, w, v}; |
| case SkPathVerb::kLine: n = 1; break; |
| case SkPathVerb::kQuad: n = 2; break; |
| case SkPathVerb::kConic: n = 2; w = fConics[cIndex++]; break; |
| case SkPathVerb::kCubic: n = 3; break; |
| case SkPathVerb::kClose: |
| SkASSERT(pIndex > 0); |
| fClosePointStorage[0] = fPoints[pIndex-1]; // the last point we saw |
| return Rec{fClosePointStorage, w, v}; |
| } |
| |
| SkASSERT(pIndex > 0); |
| auto start = pIndex - 1; |
| SkASSERT(n >= 1 && n <= 3); |
| pIndex += n; |
| return Rec{{&fPoints[start], n+1}, w, v}; |
| |
| } |
| |
| /////////////////////////////////////////////// |
| |
| std::optional<SkPathContourIter::Rec> SkPathContourIter::next() { |
| if (fVerbs.empty()) { |
| return {}; |
| } |
| |
| SkASSERT(fVerbs[0] == SkPathVerb::kMove); |
| size_t npts = 1, nvbs = 1, nws = 0; |
| |
| for (size_t i = 1; i < fVerbs.size(); ++i) { |
| switch (fVerbs[i]) { |
| case SkPathVerb::kMove: goto DONE; |
| case SkPathVerb::kLine: npts += 1; break; |
| case SkPathVerb::kQuad: npts += 2; break; |
| case SkPathVerb::kConic: npts += 2; nws += 1; break; |
| case SkPathVerb::kCubic: npts += 3; break; |
| case SkPathVerb::kClose: nvbs += 1; goto DONE; |
| } |
| nvbs += 1; |
| } |
| DONE: |
| Rec rec = { |
| fPoints.subspan(0, npts), |
| fVerbs.subspan(0, nvbs), |
| fConics.subspan(0, nws), |
| }; |
| fPoints = fPoints.last(fPoints.size() - npts); |
| fVerbs = fVerbs.last( fVerbs.size() - nvbs); |
| fConics = fConics.last(fConics.size() - nws); |
| return rec; |
| } |