Flutter Engine
The Flutter Engine
Macros | Typedefs | Functions
GrTriangulator.cpp File Reference
#include "src/gpu/ganesh/geometry/GrTriangulator.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkRect.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkMath.h"
#include "include/private/base/SkTPin.h"
#include "src/base/SkVx.h"
#include "src/core/SkGeometry.h"
#include "src/core/SkPointPriv.h"
#include "src/gpu/BufferWriter.h"
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/GrEagerVertexAllocator.h"
#include "src/gpu/ganesh/geometry/GrPathUtils.h"
#include <algorithm>
#include <cstddef>
#include <limits>
#include <memory>
#include <tuple>
#include <utility>

Go to the source code of this file.

Macros

#define TESS_LOG(...)
 
#define DUMP_MESH(M)
 

Typedefs

using EdgeType = GrTriangulator::EdgeType
 
using Vertex = GrTriangulator::Vertex
 
using VertexList = GrTriangulator::VertexList
 
using Line = GrTriangulator::Line
 
using Edge = GrTriangulator::Edge
 
using EdgeList = GrTriangulator::EdgeList
 
using Poly = GrTriangulator::Poly
 
using MonotonePoly = GrTriangulator::MonotonePoly
 
using Comparator = GrTriangulator::Comparator
 
typedef bool(* CompareFunc) (const SkPoint &a, const SkPoint &b)
 

Functions

template<class T , T *T::* Prev, T *T::* Next>
static void list_insert (T *t, T *prev, T *next, T **head, T **tail)
 
template<class T , T *T::* Prev, T *T::* Next>
static void list_remove (T *t, T **head, T **tail)
 
static bool sweep_lt_horiz (const SkPoint &a, const SkPoint &b)
 
static bool sweep_lt_vert (const SkPoint &a, const SkPoint &b)
 
static skgpu::VertexWriter emit_vertex (Vertex *v, bool emitCoverage, skgpu::VertexWriter data)
 
static skgpu::VertexWriter emit_triangle (Vertex *v0, Vertex *v1, Vertex *v2, bool emitCoverage, skgpu::VertexWriter data)
 
static void round (SkPoint *p)
 
static SkScalar double_to_clamped_scalar (double d)
 
static bool edge_line_needs_recursion (const SkPoint &p0, const SkPoint &p1)
 
static bool recursive_edge_intersect (const Line &u, SkPoint u0, SkPoint u1, const Line &v, SkPoint v0, SkPoint v1, SkPoint *p, double *s, double *t)
 
static bool coincident (const SkPoint &a, const SkPoint &b)
 
static SkScalar quad_error_at (const SkPoint pts[3], SkScalar t, SkScalar u)
 
static bool apply_fill_type (SkPathFillType fillType, int winding)
 
static bool apply_fill_type (SkPathFillType fillType, Poly *poly)
 
static void remove_edge_above (Edge *edge)
 
static void remove_edge_below (Edge *edge)
 
static bool rewind (EdgeList *activeEdges, Vertex **current, Vertex *dst, const Comparator &c)
 
static bool rewind_if_necessary (Edge *edge, EdgeList *activeEdges, Vertex **current, const Comparator &c)
 
static bool top_collinear (Edge *left, Edge *right)
 
static bool bottom_collinear (Edge *left, Edge *right)
 
static SkPoint clamp (SkPoint p, SkPoint min, SkPoint max, const Comparator &c)
 
template<CompareFunc sweep_lt>
static void sorted_merge (VertexList *front, VertexList *back, VertexList *result)
 
template<CompareFunc sweep_lt>
static void merge_sort (VertexList *vertices)
 
static int get_contour_count (const SkPath &path, SkScalar tolerance)
 

Macro Definition Documentation

◆ DUMP_MESH

#define DUMP_MESH (   M)

Definition at line 38 of file GrTriangulator.cpp.

◆ TESS_LOG

#define TESS_LOG (   ...)

Definition at line 37 of file GrTriangulator.cpp.

Typedef Documentation

◆ Comparator

Definition at line 49 of file GrTriangulator.cpp.

◆ CompareFunc

typedef bool(* CompareFunc) (const SkPoint &a, const SkPoint &b)

Definition at line 82 of file GrTriangulator.cpp.

◆ Edge

Definition at line 45 of file GrTriangulator.cpp.

◆ EdgeList

Definition at line 46 of file GrTriangulator.cpp.

◆ EdgeType

Definition at line 41 of file GrTriangulator.cpp.

◆ Line

Definition at line 44 of file GrTriangulator.cpp.

◆ MonotonePoly

Definition at line 48 of file GrTriangulator.cpp.

◆ Poly

Definition at line 47 of file GrTriangulator.cpp.

◆ Vertex

Definition at line 42 of file GrTriangulator.cpp.

◆ VertexList

Definition at line 43 of file GrTriangulator.cpp.

Function Documentation

◆ apply_fill_type() [1/2]

static bool apply_fill_type ( SkPathFillType  fillType,
int  winding 
)
inlinestatic

Definition at line 614 of file GrTriangulator.cpp.

614 {
615 switch (fillType) {
617 return winding != 0;
619 return (winding & 1) != 0;
621 return winding == 1;
623 return (winding & 1) == 1;
624 default:
625 SkASSERT(false);
626 return false;
627 }
628}
#define SkASSERT(cond)
Definition: SkAssert.h:116

◆ apply_fill_type() [2/2]

static bool apply_fill_type ( SkPathFillType  fillType,
Poly poly 
)
inlinestatic

Definition at line 634 of file GrTriangulator.cpp.

634 {
635 return poly && apply_fill_type(fillType, poly->fWinding);
636}
static bool apply_fill_type(SkPathFillType fillType, int winding)

◆ bottom_collinear()

static bool bottom_collinear ( Edge left,
Edge right 
)
static

Definition at line 949 of file GrTriangulator.cpp.

949 {
950 if (!left || !right) {
951 return false;
952 }
953 return left->fBottom->fPoint == right->fBottom->fPoint ||
954 !left->isLeftOf(*right->fBottom) || !right->isRightOf(*left->fBottom);
955}
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)

◆ clamp()

static SkPoint clamp ( SkPoint  p,
SkPoint  min,
SkPoint  max,
const Comparator c 
)
static

Definition at line 1152 of file GrTriangulator.cpp.

1152 {
1154 // With horizontal sorting, we know min.x <= max.x, but there's no relation between
1155 // Y components unless min.x == max.x.
1156 return {SkTPin(p.fX, min.fX, max.fX),
1157 min.fY < max.fY ? SkTPin(p.fY, min.fY, max.fY)
1158 : SkTPin(p.fY, max.fY, min.fY)};
1159 } else {
1160 // And with vertical sorting, we know Y's relation but not necessarily X's.
1161 return {min.fX < max.fX ? SkTPin(p.fX, min.fX, max.fX)
1162 : SkTPin(p.fX, max.fX, min.fX),
1163 SkTPin(p.fY, min.fY, max.fY)};
1164 }
1165}
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48

◆ coincident()

static bool coincident ( const SkPoint a,
const SkPoint b 
)
static

Definition at line 464 of file GrTriangulator.cpp.

464 {
465 return a == b;
466}
static bool b
struct MyStruct a[10]

◆ double_to_clamped_scalar()

static SkScalar double_to_clamped_scalar ( double  d)
inlinestatic

Definition at line 143 of file GrTriangulator.cpp.

143 {
144 // Clamps large values to what's finitely representable when cast back to a float.
145 static const double kMaxLimit = (double) SK_ScalarMax;
146 // It's not perfect, but a using a value larger than float_min helps protect from denormalized
147 // values and ill-conditions in intermediate calculations on coordinates.
148 static const double kNearZeroLimit = 16 * (double) std::numeric_limits<float>::min();
149 if (std::abs(d) < kNearZeroLimit) {
150 d = 0.f;
151 }
152 return SkDoubleToScalar(std::max(-kMaxLimit, std::min(d, kMaxLimit)));
153}
#define SK_ScalarMax
Definition: SkScalar.h:24
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707

◆ edge_line_needs_recursion()

static bool edge_line_needs_recursion ( const SkPoint p0,
const SkPoint p1 
)
static

Definition at line 170 of file GrTriangulator.cpp.

170 {
171 // ilogbf(0) returns an implementation-defined constant, but we are choosing to saturate
172 // negative exponents to 0 for comparisons sake. We're only trying to recurse on lines with
173 // very large coordinates.
174 int expDiffX = std::abs((std::abs(p0.fX) < 1.f ? 0 : std::ilogbf(p0.fX)) -
175 (std::abs(p1.fX) < 1.f ? 0 : std::ilogbf(p1.fX)));
176 int expDiffY = std::abs((std::abs(p0.fY) < 1.f ? 0 : std::ilogbf(p0.fY)) -
177 (std::abs(p1.fY) < 1.f ? 0 : std::ilogbf(p1.fY)));
178 // Differ by more than 2^20, or roughly a factor of one million.
179 return expDiffX > 20 || expDiffY > 20;
180}
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ emit_triangle()

static skgpu::VertexWriter emit_triangle ( Vertex v0,
Vertex v1,
Vertex v2,
bool  emitCoverage,
skgpu::VertexWriter  data 
)
static

Definition at line 108 of file GrTriangulator.cpp.

109 {
110 TESS_LOG("emit_triangle %g (%g, %g) %d\n", v0->fID, v0->fPoint.fX, v0->fPoint.fY, v0->fAlpha);
111 TESS_LOG(" %g (%g, %g) %d\n", v1->fID, v1->fPoint.fX, v1->fPoint.fY, v1->fAlpha);
112 TESS_LOG(" %g (%g, %g) %d\n", v2->fID, v2->fPoint.fX, v2->fPoint.fY, v2->fAlpha);
113#if TRIANGULATOR_WIREFRAME
114 data = emit_vertex(v0, emitCoverage, std::move(data));
115 data = emit_vertex(v1, emitCoverage, std::move(data));
116 data = emit_vertex(v1, emitCoverage, std::move(data));
117 data = emit_vertex(v2, emitCoverage, std::move(data));
118 data = emit_vertex(v2, emitCoverage, std::move(data));
119 data = emit_vertex(v0, emitCoverage, std::move(data));
120#else
121 data = emit_vertex(v0, emitCoverage, std::move(data));
122 data = emit_vertex(v1, emitCoverage, std::move(data));
123 data = emit_vertex(v2, emitCoverage, std::move(data));
124#endif
125 return data;
126}
static skgpu::VertexWriter emit_vertex(Vertex *v, bool emitCoverage, skgpu::VertexWriter data)
#define TESS_LOG(...)
Vec2Value v2
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ emit_vertex()

static skgpu::VertexWriter emit_vertex ( Vertex v,
bool  emitCoverage,
skgpu::VertexWriter  data 
)
inlinestatic

Definition at line 96 of file GrTriangulator.cpp.

98 {
99 data << v->fPoint;
100
101 if (emitCoverage) {
102 data << GrNormalizeByteToFloat(v->fAlpha);
103 }
104
105 return data;
106}
static float GrNormalizeByteToFloat(uint8_t value)
Definition: GrColor.h:71

◆ get_contour_count()

static int get_contour_count ( const SkPath path,
SkScalar  tolerance 
)
static

Definition at line 1718 of file GrTriangulator.cpp.

1718 {
1719 // We could theoretically be more aggressive about not counting empty contours, but we need to
1720 // actually match the exact number of contour linked lists the tessellator will create later on.
1721 int contourCnt = 1;
1722 bool hasPoints = false;
1723
1724 SkPath::Iter iter(path, false);
1725 SkPath::Verb verb;
1726 SkPoint pts[4];
1727 bool first = true;
1728 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
1729 switch (verb) {
1730 case SkPath::kMove_Verb:
1731 if (!first) {
1732 ++contourCnt;
1733 }
1734 [[fallthrough]];
1735 case SkPath::kLine_Verb:
1737 case SkPath::kQuad_Verb:
1739 hasPoints = true;
1740 break;
1741 default:
1742 break;
1743 }
1744 first = false;
1745 }
1746 if (!hasPoints) {
1747 return 0;
1748 }
1749 return contourCnt;
1750}
@ 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
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

◆ list_insert()

template<class T , T *T::* Prev, T *T::* Next>
static void list_insert ( T t,
T prev,
T next,
T **  head,
T **  tail 
)
static

Definition at line 52 of file GrTriangulator.cpp.

52 {
53 t->*Prev = prev;
54 t->*Next = next;
55 if (prev) {
56 prev->*Next = t;
57 } else if (head) {
58 *head = t;
59 }
60 if (next) {
61 next->*Prev = t;
62 } else if (tail) {
63 *tail = t;
64 }
65}
static float next(float f)
static float prev(float f)

◆ list_remove()

template<class T , T *T::* Prev, T *T::* Next>
static void list_remove ( T t,
T **  head,
T **  tail 
)
static

Definition at line 68 of file GrTriangulator.cpp.

68 {
69 if (t->*Prev) {
70 t->*Prev->*Next = t->*Next;
71 } else if (head) {
72 *head = t->*Next;
73 }
74 if (t->*Next) {
75 t->*Next->*Prev = t->*Prev;
76 } else if (tail) {
77 *tail = t->*Prev;
78 }
79 t->*Prev = t->*Next = nullptr;
80}

◆ merge_sort()

template<CompareFunc sweep_lt>
static void merge_sort ( VertexList vertices)
static

Definition at line 1354 of file GrTriangulator.cpp.

1354 {
1355 Vertex* slow = vertices->fHead;
1356 if (!slow) {
1357 return;
1358 }
1359 Vertex* fast = slow->fNext;
1360 if (!fast) {
1361 return;
1362 }
1363 do {
1364 fast = fast->fNext;
1365 if (fast) {
1366 fast = fast->fNext;
1367 slow = slow->fNext;
1368 }
1369 } while (fast);
1370 VertexList front(vertices->fHead, slow);
1371 VertexList back(slow->fNext, vertices->fTail);
1372 front.fTail->fNext = back.fHead->fPrev = nullptr;
1373
1374 merge_sort<sweep_lt>(&front);
1375 merge_sort<sweep_lt>(&back);
1376
1377 vertices->fHead = vertices->fTail = nullptr;
1378 sorted_merge<sweep_lt>(&front, &back, vertices);
1379}

◆ quad_error_at()

static SkScalar quad_error_at ( const SkPoint  pts[3],
SkScalar  t,
SkScalar  u 
)
static

Definition at line 484 of file GrTriangulator.cpp.

484 {
485 SkQuadCoeff quad(pts);
486 SkPoint p0 = to_point(quad.eval(t - 0.5f * u));
487 SkPoint mid = to_point(quad.eval(t));
488 SkPoint p1 = to_point(quad.eval(t + 0.5f * u));
489 if (!p0.isFinite() || !mid.isFinite() || !p1.isFinite()) {
490 return 0;
491 }
493}
static SkScalar DistanceToLineSegmentBetweenSqd(const SkPoint &pt, const SkPoint &a, const SkPoint &b)
Definition: SkPoint.cpp:126
static SkPoint to_point(SkIPoint p)
Definition: editor.cpp:75
bool isFinite() const
Definition: SkPoint_impl.h:412

◆ recursive_edge_intersect()

static bool recursive_edge_intersect ( const Line u,
SkPoint  u0,
SkPoint  u1,
const Line v,
SkPoint  v0,
SkPoint  v1,
SkPoint p,
double *  s,
double *  t 
)
static

Definition at line 182 of file GrTriangulator.cpp.

184 {
185 // First check if the bounding boxes of [u0,u1] intersects [v0,v1]. If they do not, then the
186 // two line segments cannot intersect in their domain (even if the lines themselves might).
187 // - don't use SkRect::intersect since the vertices aren't sorted and horiz/vertical lines
188 // appear as empty rects, which then never "intersect" according to SkRect.
189 if (std::min(u0.fX, u1.fX) > std::max(v0.fX, v1.fX) ||
190 std::max(u0.fX, u1.fX) < std::min(v0.fX, v1.fX) ||
191 std::min(u0.fY, u1.fY) > std::max(v0.fY, v1.fY) ||
192 std::max(u0.fY, u1.fY) < std::min(v0.fY, v1.fY)) {
193 return false;
194 }
195
196 // Compute intersection based on current segment vertices; if an intersection is found but the
197 // vertices differ too much in magnitude, we recurse using the midpoint of the segment to
198 // reject false positives. We don't currently try to avoid false negatives (e.g. large magnitude
199 // line reports no intersection but there is one).
200 double denom = u.fA * v.fB - u.fB * v.fA;
201 if (denom == 0.0) {
202 return false;
203 }
204 double dx = static_cast<double>(v0.fX) - u0.fX;
205 double dy = static_cast<double>(v0.fY) - u0.fY;
206 double sNumer = dy * v.fB + dx * v.fA;
207 double tNumer = dy * u.fB + dx * u.fA;
208 // If (sNumer / denom) or (tNumer / denom) is not in [0..1], exit early.
209 // This saves us doing the divide below unless absolutely necessary.
210 if (denom > 0.0 ? (sNumer < 0.0 || sNumer > denom || tNumer < 0.0 || tNumer > denom)
211 : (sNumer > 0.0 || sNumer < denom || tNumer > 0.0 || tNumer < denom)) {
212 return false;
213 }
214
215 *s = sNumer / denom;
216 *t = tNumer / denom;
217 SkASSERT(*s >= 0.0 && *s <= 1.0 && *t >= 0.0 && *t <= 1.0);
218
219 const bool uNeedsSplit = edge_line_needs_recursion(u0, u1);
220 const bool vNeedsSplit = edge_line_needs_recursion(v0, v1);
221 if (!uNeedsSplit && !vNeedsSplit) {
222 p->fX = double_to_clamped_scalar(u0.fX - (*s) * u.fB);
223 p->fY = double_to_clamped_scalar(u0.fY + (*s) * u.fA);
224 return true;
225 } else {
226 double sScale = 1.0, sShift = 0.0;
227 double tScale = 1.0, tShift = 0.0;
228
229 if (uNeedsSplit) {
230 SkPoint uM = {(float) (0.5 * u0.fX + 0.5 * u1.fX),
231 (float) (0.5 * u0.fY + 0.5 * u1.fY)};
232 sScale = 0.5;
233 if (*s >= 0.5) {
234 u0 = uM;
235 sShift = 0.5;
236 } else {
237 u1 = uM;
238 }
239 }
240 if (vNeedsSplit) {
241 SkPoint vM = {(float) (0.5 * v0.fX + 0.5 * v1.fX),
242 (float) (0.5 * v0.fY + 0.5 * v1.fY)};
243 tScale = 0.5;
244 if (*t >= 0.5) {
245 v0 = vM;
246 tShift = 0.5;
247 } else {
248 v1 = vM;
249 }
250 }
251
252 // Just recompute both lines, even if only one was split; we're already in a slow path.
253 if (recursive_edge_intersect(Line(u0, u1), u0, u1, Line(v0, v1), v0, v1, p, s, t)) {
254 // Adjust s and t back to full range
255 *s = sScale * (*s) + sShift;
256 *t = tScale * (*t) + tShift;
257 return true;
258 } else {
259 // False positive
260 return false;
261 }
262 }
263}
static bool recursive_edge_intersect(const Line &u, SkPoint u0, SkPoint u1, const Line &v, SkPoint v0, SkPoint v1, SkPoint *p, double *s, double *t)
static bool edge_line_needs_recursion(const SkPoint &p0, const SkPoint &p1)
GrTriangulator::Line Line
static SkScalar double_to_clamped_scalar(double d)
struct MyStruct s
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208

◆ remove_edge_above()

static void remove_edge_above ( Edge edge)
static

Definition at line 724 of file GrTriangulator.cpp.

724 {
725 SkASSERT(edge->fTop && edge->fBottom);
726 TESS_LOG("removing edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBottom->fID,
727 edge->fBottom->fID);
728 list_remove<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>(
729 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove);
730}

◆ remove_edge_below()

static void remove_edge_below ( Edge edge)
static

Definition at line 732 of file GrTriangulator.cpp.

732 {
733 SkASSERT(edge->fTop && edge->fBottom);
734 TESS_LOG("removing edge (%g -> %g) below vertex %g\n",
735 edge->fTop->fID, edge->fBottom->fID, edge->fTop->fID);
736 list_remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>(
737 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow);
738}

◆ rewind()

static bool rewind ( EdgeList activeEdges,
Vertex **  current,
Vertex dst,
const Comparator c 
)
static

Definition at line 745 of file GrTriangulator.cpp.

745 {
746 if (!current || *current == dst || c.sweep_lt((*current)->fPoint, dst->fPoint)) {
747 return true;
748 }
749 Vertex* v = *current;
750 TESS_LOG("rewinding active edges from vertex %g to vertex %g\n", v->fID, dst->fID);
751 while (v != dst) {
752 v = v->fPrev;
753 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) {
754 if (!activeEdges->remove(e)) {
755 return false;
756 }
757 }
758 Edge* leftEdge = v->fLeftEnclosingEdge;
759 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) {
760 if (!activeEdges->insert(e, leftEdge)) {
761 return false;
762 }
763 leftEdge = e;
764 Vertex* top = e->fTop;
765 if (c.sweep_lt(top->fPoint, dst->fPoint) &&
766 ((top->fLeftEnclosingEdge && !top->fLeftEnclosingEdge->isLeftOf(*e->fTop)) ||
767 (top->fRightEnclosingEdge && !top->fRightEnclosingEdge->isRightOf(*e->fTop)))) {
768 dst = top;
769 }
770 }
771 }
772 *current = v;
773 return true;
774}
dst
Definition: cp.py:12
bool sweep_lt(const SkPoint &a, const SkPoint &b) const
void insert(Edge *edge, Edge *prev, Edge *next)

◆ rewind_if_necessary()

static bool rewind_if_necessary ( Edge edge,
EdgeList activeEdges,
Vertex **  current,
const Comparator c 
)
static

Definition at line 776 of file GrTriangulator.cpp.

777 {
778 if (!activeEdges || !current) {
779 return true;
780 }
781 if (!edge) {
782 return false;
783 }
784 Vertex* top = edge->fTop;
785 Vertex* bottom = edge->fBottom;
786 if (edge->fLeft) {
787 Vertex* leftTop = edge->fLeft->fTop;
788 Vertex* leftBottom = edge->fLeft->fBottom;
789 if (leftTop && leftBottom) {
790 if (c.sweep_lt(leftTop->fPoint, top->fPoint) && !edge->fLeft->isLeftOf(*top)) {
791 if (!rewind(activeEdges, current, leftTop, c)) {
792 return false;
793 }
794 } else if (c.sweep_lt(top->fPoint, leftTop->fPoint) && !edge->isRightOf(*leftTop)) {
795 if (!rewind(activeEdges, current, top, c)) {
796 return false;
797 }
798 } else if (c.sweep_lt(bottom->fPoint, leftBottom->fPoint) &&
799 !edge->fLeft->isLeftOf(*bottom)) {
800 if (!rewind(activeEdges, current, leftTop, c)) {
801 return false;
802 }
803 } else if (c.sweep_lt(leftBottom->fPoint, bottom->fPoint) &&
804 !edge->isRightOf(*leftBottom)) {
805 if (!rewind(activeEdges, current, top, c)) {
806 return false;
807 }
808 }
809 }
810 }
811 if (edge->fRight) {
812 Vertex* rightTop = edge->fRight->fTop;
813 Vertex* rightBottom = edge->fRight->fBottom;
814 if (rightTop && rightBottom) {
815 if (c.sweep_lt(rightTop->fPoint, top->fPoint) && !edge->fRight->isRightOf(*top)) {
816 if (!rewind(activeEdges, current, rightTop, c)) {
817 return false;
818 }
819 } else if (c.sweep_lt(top->fPoint, rightTop->fPoint) && !edge->isLeftOf(*rightTop)) {
820 if (!rewind(activeEdges, current, top, c)) {
821 return false;
822 }
823 } else if (c.sweep_lt(bottom->fPoint, rightBottom->fPoint) &&
824 !edge->fRight->isRightOf(*bottom)) {
825 if (!rewind(activeEdges, current, rightTop, c)) {
826 return false;
827 }
828 } else if (c.sweep_lt(rightBottom->fPoint, bottom->fPoint) &&
829 !edge->isLeftOf(*rightBottom)) {
830 if (!rewind(activeEdges, current, top, c)) {
831 return false;
832 }
833 }
834 }
835 }
836 return true;
837}
static bool rewind(EdgeList *activeEdges, Vertex **current, Vertex *dst, const Comparator &c)

◆ round()

static void round ( SkPoint p)
inlinestatic

Definition at line 138 of file GrTriangulator.cpp.

138 {
139 p->fX = SkScalarRoundToScalar(p->fX * 4.0f) * 0.25f;
140 p->fY = SkScalarRoundToScalar(p->fY * 4.0f) * 0.25f;
141}
#define SkScalarRoundToScalar(x)
Definition: SkScalar.h:32

◆ sorted_merge()

template<CompareFunc sweep_lt>
static void sorted_merge ( VertexList front,
VertexList back,
VertexList result 
)
static

Definition at line 1318 of file GrTriangulator.cpp.

1318 {
1319 Vertex* a = front->fHead;
1320 Vertex* b = back->fHead;
1321 while (a && b) {
1322 if (sweep_lt(a->fPoint, b->fPoint)) {
1323 front->remove(a);
1324 result->append(a);
1325 a = front->fHead;
1326 } else {
1327 back->remove(b);
1328 result->append(b);
1329 b = back->fHead;
1330 }
1331 }
1332 result->append(*front);
1333 result->append(*back);
1334}
GAsyncResult * result

◆ sweep_lt_horiz()

static bool sweep_lt_horiz ( const SkPoint a,
const SkPoint b 
)
static

Definition at line 84 of file GrTriangulator.cpp.

84 {
85 return a.fX < b.fX || (a.fX == b.fX && a.fY > b.fY);
86}

◆ sweep_lt_vert()

static bool sweep_lt_vert ( const SkPoint a,
const SkPoint b 
)
static

Definition at line 88 of file GrTriangulator.cpp.

88 {
89 return a.fY < b.fY || (a.fY == b.fY && a.fX < b.fX);
90}

◆ top_collinear()

static bool top_collinear ( Edge left,
Edge right 
)
static

Definition at line 941 of file GrTriangulator.cpp.

941 {
942 if (!left || !right) {
943 return false;
944 }
945 return left->fTop->fPoint == right->fTop->fPoint ||
946 !left->isLeftOf(*right->fTop) || !right->isRightOf(*left->fTop);
947}