Flutter Engine
The Flutter Engine
Classes | Macros | Functions | Variables
SkContourMeasure.cpp File Reference
#include "include/core/SkContourMeasure.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathTypes.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFloatingPoint.h"
#include "src/core/SkGeometry.h"
#include "src/core/SkPathMeasurePriv.h"
#include "src/core/SkPathPriv.h"
#include <algorithm>
#include <utility>

Go to the source code of this file.

Classes

class  SkContourMeasureIter::Impl
 

Macros

#define kMaxTValue   0x3FFFFFFF
 
#define CHEAP_DIST_LIMIT   (SK_Scalar1/2)
 

Functions

static constexpr SkScalar tValue2Scalar (int t)
 
void SkContourMeasure_segTo (const SkPoint pts[], unsigned segType, SkScalar startT, SkScalar stopT, SkPath *dst)
 
static int tspan_big_enough (int tspan)
 
static bool quad_too_curvy (const SkPoint pts[3], SkScalar tolerance)
 
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 cubic_too_curvy (const SkPoint pts[4], SkScalar tolerance)
 
static void compute_pos_tan (const SkPoint pts[], unsigned segType, SkScalar t, SkPoint *pos, SkVector *tangent)
 
template<typename T , typename K >
int SkTKSearch (const T base[], int count, const K &key)
 

Variables

constexpr int kMaxRecursionDepth = 8
 

Macro Definition Documentation

◆ CHEAP_DIST_LIMIT

#define CHEAP_DIST_LIMIT   (SK_Scalar1/2)

Definition at line 143 of file SkContourMeasure.cpp.

◆ kMaxTValue

#define kMaxTValue   0x3FFFFFFF

Definition at line 23 of file SkContourMeasure.cpp.

Function Documentation

◆ cheap_dist_exceeds_limit()

static bool cheap_dist_exceeds_limit ( const SkPoint pt,
SkScalar  x,
SkScalar  y,
SkScalar  tolerance 
)
static

Definition at line 166 of file SkContourMeasure.cpp.

167 {
168 SkScalar dist = std::max(SkScalarAbs(x - pt.fX), SkScalarAbs(y - pt.fY));
169 // just made up the 1/2
170 return dist > tolerance;
171}
#define SkScalarAbs(x)
Definition: SkScalar.h:39
float SkScalar
Definition: extension.cpp:12
static float max(float r, float g, float b)
Definition: hsl.cpp:49
double y
double x
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ compute_pos_tan()

static void compute_pos_tan ( const SkPoint  pts[],
unsigned  segType,
SkScalar  t,
SkPoint pos,
SkVector tangent 
)
static

Definition at line 461 of file SkContourMeasure.cpp.

462 {
463 switch (segType) {
464 case kLine_SegType:
465 if (pos) {
466 pos->set(SkScalarInterp(pts[0].fX, pts[1].fX, t),
467 SkScalarInterp(pts[0].fY, pts[1].fY, t));
468 }
469 if (tangent) {
470 tangent->setNormalize(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY);
471 }
472 break;
473 case kQuad_SegType:
474 SkEvalQuadAt(pts, t, pos, tangent);
475 if (tangent) {
476 tangent->normalize();
477 }
478 break;
479 case kConic_SegType: {
480 SkConic(pts[0], pts[2], pts[3], pts[1].fX).evalAt(t, pos, tangent);
481 if (tangent) {
482 tangent->normalize();
483 }
484 } break;
485 case kCubic_SegType:
486 SkEvalCubicAt(pts, t, pos, tangent, nullptr);
487 if (tangent) {
488 tangent->normalize();
489 }
490 break;
491 default:
492 SkDEBUGFAIL("unknown segType");
493 }
494}
SkPoint pos
#define SkDEBUGFAIL(message)
Definition: SkAssert.h:118
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint *loc, SkVector *tangent, SkVector *curvature)
Definition: SkGeometry.cpp:418
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint *pt, SkVector *tangent)
Definition: SkGeometry.cpp:132
@ kConic_SegType
@ kCubic_SegType
@ kLine_SegType
@ kQuad_SegType
static SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t)
Definition: SkScalar.h:131
void evalAt(SkScalar t, SkPoint *pos, SkVector *tangent=nullptr) const
bool setNormalize(float x, float y)
Definition: SkPoint.cpp:26
void set(float x, float y)
Definition: SkPoint_impl.h:200
bool normalize()
Definition: SkPoint.cpp:22

◆ conic_too_curvy()

static bool conic_too_curvy ( const SkPoint firstPt,
const SkPoint midTPt,
const SkPoint lastPt,
SkScalar  tolerance 
)
static

Definition at line 157 of file SkContourMeasure.cpp.

158 {
159 SkPoint midEnds = firstPt + lastPt;
160 midEnds *= 0.5f;
161 SkVector dxy = midTPt - midEnds;
162 SkScalar dist = std::max(SkScalarAbs(dxy.fX), SkScalarAbs(dxy.fY));
163 return dist > tolerance;
164}

◆ cubic_too_curvy()

static bool cubic_too_curvy ( const SkPoint  pts[4],
SkScalar  tolerance 
)
static

Definition at line 173 of file SkContourMeasure.cpp.

173 {
174 return cheap_dist_exceeds_limit(pts[1],
175 SkScalarInterp(pts[0].fX, pts[3].fX, SK_Scalar1/3),
176 SkScalarInterp(pts[0].fY, pts[3].fY, SK_Scalar1/3), tolerance)
177 ||
179 SkScalarInterp(pts[0].fX, pts[3].fX, SK_Scalar1*2/3),
180 SkScalarInterp(pts[0].fY, pts[3].fY, SK_Scalar1*2/3), tolerance);
181}
static bool cheap_dist_exceeds_limit(const SkPoint &pt, SkScalar x, SkScalar y, SkScalar tolerance)
#define SK_Scalar1
Definition: SkScalar.h:18

◆ quad_too_curvy()

static bool quad_too_curvy ( const SkPoint  pts[3],
SkScalar  tolerance 
)
static

Definition at line 145 of file SkContourMeasure.cpp.

145 {
146 // diff = (a/4 + b/2 + c/4) - (a/2 + c/2)
147 // diff = -a/4 + b/2 - c/4
148 SkScalar dx = SkScalarHalf(pts[1].fX) -
149 SkScalarHalf(SkScalarHalf(pts[0].fX + pts[2].fX));
150 SkScalar dy = SkScalarHalf(pts[1].fY) -
151 SkScalarHalf(SkScalarHalf(pts[0].fY + pts[2].fY));
152
154 return dist > tolerance;
155}
#define SkScalarHalf(a)
Definition: SkScalar.h:75
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208

◆ SkContourMeasure_segTo()

void SkContourMeasure_segTo ( const SkPoint  pts[],
unsigned  segType,
SkScalar  startT,
SkScalar  stopT,
SkPath dst 
)

Definition at line 39 of file SkContourMeasure.cpp.

40 {
41 SkASSERT(startT >= 0 && startT <= SK_Scalar1);
42 SkASSERT(stopT >= 0 && stopT <= SK_Scalar1);
43 SkASSERT(startT <= stopT);
44
45 if (startT == stopT) {
46 if (!dst->isEmpty()) {
47 /* if the dash as a zero-length on segment, add a corresponding zero-length line.
48 The stroke code will add end caps to zero length lines as appropriate */
49 SkPoint lastPt;
50 SkAssertResult(dst->getLastPt(&lastPt));
51 dst->lineTo(lastPt);
52 }
53 return;
54 }
55
56 SkPoint tmp0[7], tmp1[7];
57
58 switch (segType) {
59 case kLine_SegType:
60 if (SK_Scalar1 == stopT) {
61 dst->lineTo(pts[1]);
62 } else {
63 dst->lineTo(SkScalarInterp(pts[0].fX, pts[1].fX, stopT),
64 SkScalarInterp(pts[0].fY, pts[1].fY, stopT));
65 }
66 break;
67 case kQuad_SegType:
68 if (0 == startT) {
69 if (SK_Scalar1 == stopT) {
70 dst->quadTo(pts[1], pts[2]);
71 } else {
72 SkChopQuadAt(pts, tmp0, stopT);
73 dst->quadTo(tmp0[1], tmp0[2]);
74 }
75 } else {
76 SkChopQuadAt(pts, tmp0, startT);
77 if (SK_Scalar1 == stopT) {
78 dst->quadTo(tmp0[3], tmp0[4]);
79 } else {
80 SkChopQuadAt(&tmp0[2], tmp1, (stopT - startT) / (1 - startT));
81 dst->quadTo(tmp1[1], tmp1[2]);
82 }
83 }
84 break;
85 case kConic_SegType: {
86 SkConic conic(pts[0], pts[2], pts[3], pts[1].fX);
87
88 if (0 == startT) {
89 if (SK_Scalar1 == stopT) {
90 dst->conicTo(conic.fPts[1], conic.fPts[2], conic.fW);
91 } else {
92 SkConic tmp[2];
93 if (conic.chopAt(stopT, tmp)) {
94 dst->conicTo(tmp[0].fPts[1], tmp[0].fPts[2], tmp[0].fW);
95 }
96 }
97 } else {
98 if (SK_Scalar1 == stopT) {
99 SkConic tmp[2];
100 if (conic.chopAt(startT, tmp)) {
101 dst->conicTo(tmp[1].fPts[1], tmp[1].fPts[2], tmp[1].fW);
102 }
103 } else {
104 SkConic tmp;
105 conic.chopAt(startT, stopT, &tmp);
106 dst->conicTo(tmp.fPts[1], tmp.fPts[2], tmp.fW);
107 }
108 }
109 } break;
110 case kCubic_SegType:
111 if (0 == startT) {
112 if (SK_Scalar1 == stopT) {
113 dst->cubicTo(pts[1], pts[2], pts[3]);
114 } else {
115 SkChopCubicAt(pts, tmp0, stopT);
116 dst->cubicTo(tmp0[1], tmp0[2], tmp0[3]);
117 }
118 } else {
119 SkChopCubicAt(pts, tmp0, startT);
120 if (SK_Scalar1 == stopT) {
121 dst->cubicTo(tmp0[4], tmp0[5], tmp0[6]);
122 } else {
123 SkChopCubicAt(&tmp0[3], tmp1, (stopT - startT) / (1 - startT));
124 dst->cubicTo(tmp1[1], tmp1[2], tmp1[3]);
125 }
126 }
127 break;
128 default:
129 SK_ABORT("unknown segType");
130 }
131}
SkPoint fPts[2]
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t)
Definition: SkGeometry.cpp:175
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t)
Definition: SkGeometry.cpp:473
dst
Definition: cp.py:12
AI float conic(float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:287
SkScalar fW
Definition: SkGeometry.h:337
SkPoint fPts[3]
Definition: SkGeometry.h:336

◆ SkTKSearch()

template<typename T , typename K >
int SkTKSearch ( const T  base[],
int  count,
const K key 
)

Definition at line 546 of file SkContourMeasure.cpp.

546 {
547 SkASSERT(count >= 0);
548 if (count <= 0) {
549 return ~0;
550 }
551
552 SkASSERT(base != nullptr); // base may be nullptr if count is zero
553
554 unsigned lo = 0;
555 unsigned hi = count - 1;
556
557 while (lo < hi) {
558 unsigned mid = (hi + lo) >> 1;
559 if (base[mid].fDistance < key) {
560 lo = mid + 1;
561 } else {
562 hi = mid;
563 }
564 }
565
566 if (base[hi].fDistance < key) {
567 hi += 1;
568 hi = ~hi;
569 } else if (key < base[hi].fDistance) {
570 hi = ~hi;
571 }
572 return hi;
573}
int count
Definition: FontMgrTest.cpp:50

◆ tspan_big_enough()

static int tspan_big_enough ( int  tspan)
inlinestatic

Definition at line 135 of file SkContourMeasure.cpp.

135 {
136 SkASSERT((unsigned)tspan <= kMaxTValue);
137 return tspan >> 10;
138}
#define kMaxTValue

◆ tValue2Scalar()

static constexpr SkScalar tValue2Scalar ( int  t)
inlinestaticconstexpr

Definition at line 25 of file SkContourMeasure.cpp.

25 {
26 SkASSERT((unsigned)t <= kMaxTValue);
27 // 1/kMaxTValue can't be represented as a float, but it's close and the limits work fine.
28 const SkScalar kMaxTReciprocal = 1.0f / (SkScalar)kMaxTValue;
29 return t * kMaxTReciprocal;
30}

Variable Documentation

◆ kMaxRecursionDepth

constexpr int kMaxRecursionDepth = 8
constexpr

Definition at line 185 of file SkContourMeasure.cpp.