blob: e8f38493813332ba06ad8fcd99d2ebe9bf924726 [file] [log] [blame]
/*
* 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;
}