blob: 1b2ad5bffbacd253167375f20f4a1196743f5476 [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/SkPathTypes.h"
#include "include/private/base/SkAssert.h"
#include "src/core/SkPathPriv.h"
#include "src/core/SkPathRaw.h"
const uint8_t gVerbToSegmentMask[] = {
0, // move
kLine_SkPathSegmentMask,
kQuad_SkPathSegmentMask,
kConic_SkPathSegmentMask,
kCubic_SkPathSegmentMask,
0, // close
};
uint8_t SkPathPriv::ComputeSegmentMask(SkSpan<const SkPathVerb> verbs) {
unsigned mask = 0;
for (auto v : verbs) {
unsigned i = static_cast<unsigned>(v);
SkASSERT(i < std::size(gVerbToSegmentMask));
mask |= gVerbToSegmentMask[i];
}
return SkTo<uint8_t>(mask);
}
////////
std::optional<SkPathRaw::IterRec> SkPathRaw::Iter::next() {
if (vIndex >= fVerbs.size()) {
return {};
}
size_t n = 0;
float w = -1;
SkPathVerb v;
switch (v = (SkPathVerb)fVerbs[vIndex++]) {
case SkPathVerb::kMove:
fPointStorage[1] = fPoints[pIndex++]; // remember for close
return IterRec{{&fPointStorage[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);
fPointStorage[0] = fPoints[pIndex-1]; // the last point we saw
return IterRec{fPointStorage, w, v};
}
SkASSERT(pIndex > 0);
auto start = pIndex - 1;
SkASSERT(n >= 1 && n <= 3);
pIndex += n;
return IterRec{{&fPoints[start], n+1}, w, v};
}
///////////////////////////////////////////////
SkPathRaw::ContourIter::ContourIter(const SkPathRaw& src) {
fPoints = src.fPoints;
fVerbs = src.fVerbs;
}
std::optional<SkPathRaw::ContourRec> SkPathRaw::ContourIter::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 ((SkPathVerb)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:
ContourRec 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;
}