Flutter Engine
The Flutter Engine
Classes | Macros | Enumerations | Functions | Variables
SkStroke.cpp File Reference
#include "src/core/SkStroke.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkMacros.h"
#include "include/private/base/SkTo.h"
#include "src/core/SkGeometry.h"
#include "src/core/SkPathEnums.h"
#include "src/core/SkPathPriv.h"
#include "src/core/SkPointPriv.h"
#include "src/core/SkStrokerPriv.h"
#include <algorithm>
#include <array>
#include "src/core/SkPaintDefaults.h"

Go to the source code of this file.

Classes

struct  SkQuadConstruct
 
class  SkPathStroker
 
class  AutoTmpPath
 

Macros

#define DEBUG_QUAD_STROKER   0
 
#define STROKER_RESULT(resultType, depth, quadPts, format, ...)    resultType
 
#define STROKER_DEBUG_PARAMS(...)
 
#define DEBUG_CUBIC_RECURSION_DEPTHS   0
 
#define DEBUG_CUBIC_RECURSION_TRACK_DEPTH(depth)   (void)(depth)
 

Enumerations

enum  { kTangent_RecursiveLimit , kCubic_RecursiveLimit , kConic_RecursiveLimit , kQuad_RecursiveLimit }
 

Functions

static bool degenerate_vector (const SkVector &v)
 
static bool set_normal_unitnormal (const SkPoint &before, const SkPoint &after, SkScalar scale, SkScalar radius, SkVector *normal, SkVector *unitNormal)
 
static bool set_normal_unitnormal (const SkVector &vec, SkScalar radius, SkVector *normal, SkVector *unitNormal)
 
static bool has_valid_tangent (const SkPath::Iter *iter)
 
static SkScalar pt_to_line (const SkPoint &pt, const SkPoint &lineStart, const SkPoint &lineEnd)
 
static bool cubic_in_line (const SkPoint cubic[4])
 
static bool quad_in_line (const SkPoint quad[3])
 
static bool conic_in_line (const SkConic &conic)
 
static int intersect_quad_ray (const SkPoint line[2], const SkPoint quad[3], SkScalar roots[2])
 
static bool points_within_dist (const SkPoint &nearPt, const SkPoint &farPt, SkScalar limit)
 
static bool sharp_angle (const SkPoint quad[3])
 
static SkPathDirection reverse_direction (SkPathDirection dir)
 
static void addBevel (SkPath *path, const SkRect &r, const SkRect &outer, SkPathDirection dir)
 

Variables

static const int kRecursiveLimits [] = { 5*3, 24, 11*3, 11*3 }
 

Macro Definition Documentation

◆ DEBUG_CUBIC_RECURSION_DEPTHS

#define DEBUG_CUBIC_RECURSION_DEPTHS   0

Definition at line 69 of file SkStroke.cpp.

◆ DEBUG_CUBIC_RECURSION_TRACK_DEPTH

#define DEBUG_CUBIC_RECURSION_TRACK_DEPTH (   depth)    (void)(depth)

Definition at line 94 of file SkStroke.cpp.

◆ DEBUG_QUAD_STROKER

#define DEBUG_QUAD_STROKER   0

Definition at line 51 of file SkStroke.cpp.

◆ STROKER_DEBUG_PARAMS

#define STROKER_DEBUG_PARAMS (   ...)

Definition at line 65 of file SkStroke.cpp.

◆ STROKER_RESULT

#define STROKER_RESULT (   resultType,
  depth,
  quadPts,
  format,
  ... 
)     resultType

Definition at line 63 of file SkStroke.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
kTangent_RecursiveLimit 
kCubic_RecursiveLimit 
kConic_RecursiveLimit 
kQuad_RecursiveLimit 

Definition at line 26 of file SkStroke.cpp.

26 {
31};
@ kCubic_RecursiveLimit
Definition: SkStroke.cpp:28
@ kTangent_RecursiveLimit
Definition: SkStroke.cpp:27
@ kConic_RecursiveLimit
Definition: SkStroke.cpp:29
@ kQuad_RecursiveLimit
Definition: SkStroke.cpp:30

Function Documentation

◆ addBevel()

static void addBevel ( SkPath path,
const SkRect r,
const SkRect outer,
SkPathDirection  dir 
)
static

Definition at line 1559 of file SkStroke.cpp.

1559 {
1560 SkPoint pts[8];
1561
1562 if (SkPathDirection::kCW == dir) {
1563 pts[0].set(r.fLeft, outer.fTop);
1564 pts[1].set(r.fRight, outer.fTop);
1565 pts[2].set(outer.fRight, r.fTop);
1566 pts[3].set(outer.fRight, r.fBottom);
1567 pts[4].set(r.fRight, outer.fBottom);
1568 pts[5].set(r.fLeft, outer.fBottom);
1569 pts[6].set(outer.fLeft, r.fBottom);
1570 pts[7].set(outer.fLeft, r.fTop);
1571 } else {
1572 pts[7].set(r.fLeft, outer.fTop);
1573 pts[6].set(r.fRight, outer.fTop);
1574 pts[5].set(outer.fRight, r.fTop);
1575 pts[4].set(outer.fRight, r.fBottom);
1576 pts[3].set(r.fRight, outer.fBottom);
1577 pts[2].set(r.fLeft, outer.fBottom);
1578 pts[1].set(outer.fLeft, r.fBottom);
1579 pts[0].set(outer.fLeft, r.fTop);
1580 }
1581 path->addPoly(pts, 8, true);
1582}
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
Definition: switches.h:57
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition: switches.h:145
void set(float x, float y)
Definition: SkPoint_impl.h:200
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15

◆ conic_in_line()

static bool conic_in_line ( const SkConic conic)
static

Definition at line 641 of file SkStroke.cpp.

641 {
642 return quad_in_line(conic.fPts);
643}
static bool quad_in_line(const SkPoint quad[3])
Definition: SkStroke.cpp:617
AI float conic(float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:287

◆ cubic_in_line()

static bool cubic_in_line ( const SkPoint  cubic[4])
static

Definition at line 580 of file SkStroke.cpp.

580 {
581 SkScalar ptMax = -1;
582 int outer1 SK_INIT_TO_AVOID_WARNING;
583 int outer2 SK_INIT_TO_AVOID_WARNING;
584 for (int index = 0; index < 3; ++index) {
585 for (int inner = index + 1; inner < 4; ++inner) {
586 SkVector testDiff = cubic[inner] - cubic[index];
587 SkScalar testMax = std::max(SkScalarAbs(testDiff.fX), SkScalarAbs(testDiff.fY));
588 if (ptMax < testMax) {
589 outer1 = index;
590 outer2 = inner;
591 ptMax = testMax;
592 }
593 }
594 }
595 SkASSERT(outer1 >= 0 && outer1 <= 2);
596 SkASSERT(outer2 >= 1 && outer2 <= 3);
597 SkASSERT(outer1 < outer2);
598 int mid1 = (1 + (2 >> outer2)) >> outer1;
599 SkASSERT(mid1 >= 0 && mid1 <= 2);
600 SkASSERT(outer1 != mid1 && outer2 != mid1);
601 int mid2 = outer1 ^ outer2 ^ mid1;
602 SkASSERT(mid2 >= 1 && mid2 <= 3);
603 SkASSERT(mid2 != outer1 && mid2 != outer2 && mid2 != mid1);
604 SkASSERT(((1 << outer1) | (1 << outer2) | (1 << mid1) | (1 << mid2)) == 0x0f);
605 SkScalar lineSlop = ptMax * ptMax * 0.00001f; // this multiplier is pulled out of the air
606 return pt_to_line(cubic[mid1], cubic[outer1], cubic[outer2]) <= lineSlop
607 && pt_to_line(cubic[mid2], cubic[outer1], cubic[outer2]) <= lineSlop;
608}
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SK_INIT_TO_AVOID_WARNING
Definition: SkMacros.h:58
#define SkScalarAbs(x)
Definition: SkScalar.h:39
static SkScalar pt_to_line(const SkPoint &pt, const SkPoint &lineStart, const SkPoint &lineEnd)
Definition: SkStroke.cpp:541
float SkScalar
Definition: extension.cpp:12
static float max(float r, float g, float b)
Definition: hsl.cpp:49
AI float cubic(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:195
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ degenerate_vector()

static bool degenerate_vector ( const SkVector v)
inlinestatic

Definition at line 97 of file SkStroke.cpp.

97 {
98 return !SkPointPriv::CanNormalize(v.fX, v.fY);
99}
static bool CanNormalize(SkScalar dx, SkScalar dy)
Definition: SkPointPriv.h:28

◆ has_valid_tangent()

static bool has_valid_tangent ( const SkPath::Iter iter)
static

Definition at line 442 of file SkStroke.cpp.

442 {
443 SkPath::Iter copy = *iter;
444 SkPath::Verb verb;
445 SkPoint pts[4];
446 while ((verb = copy.next(pts))) {
447 switch (verb) {
449 return false;
451 if (pts[0] == pts[1]) {
452 continue;
453 }
454 return true;
457 if (pts[0] == pts[1] && pts[0] == pts[2]) {
458 continue;
459 }
460 return true;
462 if (pts[0] == pts[1] && pts[0] == pts[2] && pts[0] == pts[3]) {
463 continue;
464 }
465 return true;
468 return false;
469 }
470 }
471 return false;
472}
@ kClose_Verb
Definition: SkPath.h:1471
@ kMove_Verb
Definition: SkPath.h:1466
@ kConic_Verb
Definition: SkPath.h:1469
@ kDone_Verb
Definition: SkPath.h:1472
@ kCubic_Verb
Definition: SkPath.h:1470
@ kQuad_Verb
Definition: SkPath.h:1468
@ kLine_Verb
Definition: SkPath.h:1467
Definition: copy.py:1

◆ intersect_quad_ray()

static int intersect_quad_ray ( const SkPoint  line[2],
const SkPoint  quad[3],
SkScalar  roots[2] 
)
static

Definition at line 977 of file SkStroke.cpp.

977 {
978 SkVector vec = line[1] - line[0];
979 SkScalar r[3];
980 for (int n = 0; n < 3; ++n) {
981 r[n] = (quad[n].fY - line[0].fY) * vec.fX - (quad[n].fX - line[0].fX) * vec.fY;
982 }
983 SkScalar A = r[2];
984 SkScalar B = r[1];
985 SkScalar C = r[0];
986 A += C - 2 * B; // A = a - 2*b + c
987 B -= C; // B = -(b - c)
988 return SkFindUnitQuadRoots(A, 2 * B, C, roots);
989}
int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2])
Definition: SkGeometry.cpp:95
#define C(TEST_CATEGORY)
Definition: colrv1.cpp:248
#define B

◆ points_within_dist()

static bool points_within_dist ( const SkPoint nearPt,
const SkPoint farPt,
SkScalar  limit 
)
static

Definition at line 1012 of file SkStroke.cpp.

1012 {
1013 return SkPointPriv::DistanceToSqd(nearPt, farPt) <= limit * limit;
1014}
static SkScalar DistanceToSqd(const SkPoint &pt, const SkPoint &a)
Definition: SkPointPriv.h:48

◆ pt_to_line()

static SkScalar pt_to_line ( const SkPoint pt,
const SkPoint lineStart,
const SkPoint lineEnd 
)
static

Definition at line 541 of file SkStroke.cpp.

541 {
542 SkVector dxy = lineEnd - lineStart;
543 SkVector ab0 = pt - lineStart;
544 SkScalar numer = dxy.dot(ab0);
545 SkScalar denom = dxy.dot(dxy);
546 SkScalar t = sk_ieee_float_divide(numer, denom);
547 if (t >= 0 && t <= 1) {
548 SkPoint hit;
549 hit.fX = lineStart.fX * (1 - t) + lineEnd.fX * t;
550 hit.fY = lineStart.fY * (1 - t) + lineEnd.fY * t;
551 return SkPointPriv::DistanceToSqd(hit, pt);
552 } else {
553 return SkPointPriv::DistanceToSqd(pt, lineStart);
554 }
555}
static constexpr float sk_ieee_float_divide(float numer, float denom)
float dot(const SkVector &vec) const
Definition: SkPoint_impl.h:554

◆ quad_in_line()

static bool quad_in_line ( const SkPoint  quad[3])
static

Definition at line 617 of file SkStroke.cpp.

617 {
618 SkScalar ptMax = -1;
619 int outer1 SK_INIT_TO_AVOID_WARNING;
620 int outer2 SK_INIT_TO_AVOID_WARNING;
621 for (int index = 0; index < 2; ++index) {
622 for (int inner = index + 1; inner < 3; ++inner) {
623 SkVector testDiff = quad[inner] - quad[index];
624 SkScalar testMax = std::max(SkScalarAbs(testDiff.fX), SkScalarAbs(testDiff.fY));
625 if (ptMax < testMax) {
626 outer1 = index;
627 outer2 = inner;
628 ptMax = testMax;
629 }
630 }
631 }
632 SkASSERT(outer1 >= 0 && outer1 <= 1);
633 SkASSERT(outer2 >= 1 && outer2 <= 2);
634 SkASSERT(outer1 < outer2);
635 int mid = outer1 ^ outer2 ^ 3;
636 const float kCurvatureSlop = 0.000005f; // this multiplier is pulled out of the air
637 SkScalar lineSlop = ptMax * ptMax * kCurvatureSlop;
638 return pt_to_line(quad[mid], quad[outer1], quad[outer2]) <= lineSlop;
639}

◆ reverse_direction()

static SkPathDirection reverse_direction ( SkPathDirection  dir)
static

Definition at line 1554 of file SkStroke.cpp.

1554 {
1555 static const SkPathDirection gOpposite[] = { SkPathDirection::kCCW, SkPathDirection::kCW };
1556 return gOpposite[(int)dir];
1557}
SkPathDirection
Definition: SkPathTypes.h:34

◆ set_normal_unitnormal() [1/2]

static bool set_normal_unitnormal ( const SkPoint before,
const SkPoint after,
SkScalar  scale,
SkScalar  radius,
SkVector normal,
SkVector unitNormal 
)
static

Definition at line 101 of file SkStroke.cpp.

103 {
104 if (!unitNormal->setNormalize((after.fX - before.fX) * scale,
105 (after.fY - before.fY) * scale)) {
106 return false;
107 }
108 SkPointPriv::RotateCCW(unitNormal);
109 unitNormal->scale(radius, normal);
110 return true;
111}
static void RotateCCW(const SkPoint &src, SkPoint *dst)
Definition: SkPointPriv.h:72
const Scalar scale
bool setNormalize(float x, float y)
Definition: SkPoint.cpp:26
void scale(float scale, SkPoint *dst) const
Definition: SkPoint.cpp:17

◆ set_normal_unitnormal() [2/2]

static bool set_normal_unitnormal ( const SkVector vec,
SkScalar  radius,
SkVector normal,
SkVector unitNormal 
)
static

Definition at line 113 of file SkStroke.cpp.

115 {
116 if (!unitNormal->setNormalize(vec.fX, vec.fY)) {
117 return false;
118 }
119 SkPointPriv::RotateCCW(unitNormal);
120 unitNormal->scale(radius, normal);
121 return true;
122}

◆ sharp_angle()

static bool sharp_angle ( const SkPoint  quad[3])
static

Definition at line 1016 of file SkStroke.cpp.

1016 {
1017 SkVector smaller = quad[1] - quad[0];
1018 SkVector larger = quad[1] - quad[2];
1019 SkScalar smallerLen = SkPointPriv::LengthSqd(smaller);
1020 SkScalar largerLen = SkPointPriv::LengthSqd(larger);
1021 if (smallerLen > largerLen) {
1022 using std::swap;
1023 swap(smaller, larger);
1024 largerLen = smallerLen;
1025 }
1026 if (!smaller.setLength(largerLen)) {
1027 return false;
1028 }
1029 SkScalar dot = smaller.dot(larger);
1030 return dot > 0;
1031}
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
static SkScalar LengthSqd(const SkPoint &pt)
Definition: SkPointPriv.h:63
SINT T dot(const Vec< N, T > &a, const Vec< N, T > &b)
Definition: SkVx.h:964
bool setLength(float length)
Definition: SkPoint.cpp:30

Variable Documentation

◆ kRecursiveLimits

const int kRecursiveLimits[] = { 5*3, 24, 11*3, 11*3 }
static

Definition at line 40 of file SkStroke.cpp.