23#define kMaxTValue 0x3FFFFFFF
29 return t * kMaxTReciprocal;
32static_assert(0.0f ==
tValue2Scalar( 0),
"Lower limit should be exact.");
35SkScalar SkContourMeasure::Segment::getScalarT()
const {
45 if (startT == stopT) {
46 if (!
dst->isEmpty()) {
70 dst->quadTo(pts[1], pts[2]);
73 dst->quadTo(tmp0[1], tmp0[2]);
78 dst->quadTo(tmp0[3], tmp0[4]);
80 SkChopQuadAt(&tmp0[2], tmp1, (stopT - startT) / (1 - startT));
81 dst->quadTo(tmp1[1], tmp1[2]);
93 if (
conic.chopAt(stopT, tmp)) {
94 dst->conicTo(tmp[0].
fPts[1], tmp[0].
fPts[2], tmp[0].fW);
100 if (
conic.chopAt(startT, tmp)) {
101 dst->conicTo(tmp[1].
fPts[1], tmp[1].
fPts[2], tmp[1].fW);
105 conic.chopAt(startT, stopT, &tmp);
113 dst->cubicTo(pts[1], pts[2], pts[3]);
116 dst->cubicTo(tmp0[1], tmp0[2], tmp0[3]);
121 dst->cubicTo(tmp0[4], tmp0[5], tmp0[6]);
123 SkChopCubicAt(&tmp0[3], tmp1, (stopT - startT) / (1 - startT));
124 dst->cubicTo(tmp1[1], tmp1[2], tmp1[3]);
143#define CHEAP_DIST_LIMIT (SK_Scalar1/2)
154 return dist > tolerance;
159 SkPoint midEnds = firstPt + lastPt;
163 return dist > tolerance;
170 return dist > tolerance;
193 , fForceClosed(forceClosed) {}
208 SkDEBUGCODE(
void validate()
const;)
211 int mint,
int maxt,
unsigned ptIndex,
int recursionDepth = 0);
213 int mint,
const SkPoint& minPt,
214 int maxt,
const SkPoint& maxPt,
215 unsigned ptIndex,
int recursionDepth = 0);
217 int mint,
int maxt,
unsigned ptIndex,
int recursionDepth = 0);
221 int mint,
int maxt,
unsigned ptIndex,
222 int recursionDepth) {
226 int halft = (mint + maxt) >> 1;
230 distance = this->compute_quad_segs(tmp, distance, mint, halft, ptIndex, recursionDepth);
231 distance = this->compute_quad_segs(&tmp[2], distance, halft, maxt, ptIndex, recursionDepth);
236 if (distance > prevD) {
238 SkContourMeasure::Segment* seg = fSegments.
append();
240 seg->fPtIndex = ptIndex;
249 int mint,
const SkPoint& minPt,
250 int maxt,
const SkPoint& maxPt,
251 unsigned ptIndex,
int recursionDepth) {
252 int halft = (mint + maxt) >> 1;
262 ptIndex, recursionDepth);
264 ptIndex, recursionDepth);
271 SkContourMeasure::Segment* seg = fSegments.
append();
273 seg->fPtIndex = ptIndex;
282 int mint,
int maxt,
unsigned ptIndex,
283 int recursionDepth) {
288 int halft = (mint + maxt) >> 1;
293 ptIndex, recursionDepth);
295 ptIndex, recursionDepth);
302 SkContourMeasure::Segment* seg = fSegments.
append();
304 seg->fPtIndex = ptIndex;
320 SkContourMeasure::Segment* seg = fSegments.
append();
322 seg->fPtIndex = ptIndex;
330void SkContourMeasureIter::Impl::validate()
const {
331 const SkContourMeasure::Segment* seg = fSegments.
begin();
332 const SkContourMeasure::Segment* stop = fSegments.
end();
333 unsigned ptIndex = 0;
336 int maxChecks = 10000000;
342 const SkContourMeasure::Segment*
s = seg;
343 while (
s < stop - 1 &&
s[0].fPtIndex ==
s[1].fPtIndex && --maxChecks > 0) {
350 ptIndex = seg->fPtIndex;
359 bool haveSeenClose = fForceClosed;
360 bool haveSeenMoveTo =
false;
375 auto [verb, pts,
w] = *
fIter;
384 haveSeenMoveTo =
true;
392 fPts.append(1, pts + 1);
402 fPts.append(2, pts + 1);
418 fPts.append(2, pts + 1);
428 fPts.append(3, pts + 1);
434 haveSeenClose =
true;
443 if (fSegments.
empty()) {
452 *
fPts.append() = firstPt;
470 tangent->
setNormalize(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY);
505 this->
reset(path, forceClosed, resScale);
516 if (
path.isFinite()) {
517 fImpl = std::make_unique<Impl>(
path, forceClosed, resScale);
527 while (fImpl->hasNextSegments()) {
528 auto cm = fImpl->buildSegments();
539 : fSegments(
std::move(segs))
542 , fIsClosed(isClosed)
545template <
typename T,
typename K>
555 unsigned hi =
count - 1;
558 unsigned mid = (hi + lo) >> 1;
559 if (
base[mid].fDistance <
key) {
566 if (
base[hi].fDistance <
key) {
569 }
else if (
key <
base[hi].fDistance) {
575const SkContourMeasure::Segment* SkContourMeasure::distanceToSegment(
SkScalar distance,
580 const Segment* seg = fSegments.
begin();
585 index ^= (index >> 31);
592 startD = seg[-1].fDistance;
593 if (seg[-1].fPtIndex == seg->fPtIndex) {
594 SkASSERT(seg[-1].fType == seg->fType);
595 startT = seg[-1].getScalarT();
599 SkASSERT(seg->getScalarT() > startT);
603 *t = startT + (seg->getScalarT() - startT) * (
distance - startD) / (seg->fDistance - startD);
623 const Segment* seg = this->distanceToSegment(
distance, &t);
628 SkASSERT((
unsigned)seg->fPtIndex < (
unsigned)
fPts.size());
637 if (this->
getPosTan(distance, &position, &tangent)) {
640 matrix->setSinCos(tangent.
fY, tangent.
fX, 0, 0);
645 matrix->postTranslate(position.
fX, position.
fY);
654 bool startWithMoveTo)
const {
665 if (!(startD <= stopD)) {
668 if (fSegments.
empty()) {
674 const Segment* seg = this->distanceToSegment(startD, &startT);
678 const Segment* stopSeg = this->distanceToSegment(stopD, &stopT);
683 if (startWithMoveTo) {
688 if (seg->fPtIndex == stopSeg->fPtIndex) {
693 seg = SkContourMeasure::Segment::Next(seg);
695 }
while (seg->fPtIndex < stopSeg->fPtIndex);
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
std::unique_ptr< SkLatticeIter > fIter
#define SkDEBUGFAIL(message)
#define SK_ABORT(message,...)
static int tspan_big_enough(int tspan)
constexpr int kMaxRecursionDepth
static bool cubic_too_curvy(const SkPoint pts[4], SkScalar tolerance)
void SkContourMeasure_segTo(const SkPoint pts[], unsigned segType, SkScalar startT, SkScalar stopT, SkPath *dst)
int SkTKSearch(const T base[], int count, const K &key)
static constexpr SkScalar tValue2Scalar(int t)
static bool conic_too_curvy(const SkPoint &firstPt, const SkPoint &midTPt, const SkPoint &lastPt, SkScalar tolerance)
static bool cheap_dist_exceeds_limit(const SkPoint &pt, SkScalar x, SkScalar y, SkScalar tolerance)
static bool quad_too_curvy(const SkPoint pts[3], SkScalar tolerance)
static void compute_pos_tan(const SkPoint pts[], unsigned segType, SkScalar t, SkPoint *pos, SkVector *tangent)
static constexpr bool SkIsNaN(T x)
static bool SkIsFinite(T x, Pack... values)
static constexpr float sk_ieee_float_divide(float numer, float denom)
void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t)
void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7])
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t)
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint *loc, SkVector *tangent, SkVector *curvature)
void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5])
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint *pt, SkVector *tangent)
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
static SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t)
static int compute_cubic_segs(const SkPoint pts[4])
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
Impl(const SkPath &path, bool forceClosed, SkScalar resScale)
SkContourMeasure * buildSegments()
bool hasNextSegments() const
void reset(const SkPath &path, bool forceClosed, SkScalar resScale=1)
SkContourMeasureIter & operator=(SkContourMeasureIter &&)
sk_sp< SkContourMeasure > next()
bool getMatrix(SkScalar distance, SkMatrix *matrix, MatrixFlags flags=kGetPosAndTan_MatrixFlag) const
bool getSegment(SkScalar startD, SkScalar stopD, SkPath *dst, bool startWithMoveTo) const
bool getPosTan(SkScalar distance, SkPoint *position, SkVector *tangent) const
@ kGetPosition_MatrixFlag
SkPath::RangeIter RangeIter
static const char * begin(const StringSlice &s)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
FlutterSemanticsFlag flags
static float max(float r, float g, float b)
unsigned useCenter Optional< SkMatrix > matrix
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
void evalAt(SkScalar t, SkPoint *pos, SkVector *tangent=nullptr) const
bool setNormalize(float x, float y)
void set(float x, float y)
static float Distance(const SkPoint &a, const SkPoint &b)