Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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

◆ 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}
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition SkVx.h:707
Definition ref_ptr.h:256
float fX
x-axis value
float fY
y-axis value

◆ 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
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ 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 1708 of file GrTriangulator.cpp.

1708 {
1709 // We could theoretically be more aggressive about not counting empty contours, but we need to
1710 // actually match the exact number of contour linked lists the tessellator will create later on.
1711 int contourCnt = 1;
1712 bool hasPoints = false;
1713
1714 SkPath::Iter iter(path, false);
1715 SkPath::Verb verb;
1716 SkPoint pts[4];
1717 bool first = true;
1718 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
1719 switch (verb) {
1720 case SkPath::kMove_Verb:
1721 if (!first) {
1722 ++contourCnt;
1723 }
1724 [[fallthrough]];
1725 case SkPath::kLine_Verb:
1727 case SkPath::kQuad_Verb:
1729 hasPoints = true;
1730 break;
1731 default:
1732 break;
1733 }
1734 first = false;
1735 }
1736 if (!hasPoints) {
1737 return 0;
1738 }
1739 return contourCnt;
1740}
@ kMove_Verb
Definition SkPath.h:1458
@ kConic_Verb
Definition SkPath.h:1461
@ kDone_Verb
Definition SkPath.h:1464
@ kCubic_Verb
Definition SkPath.h:1462
@ kQuad_Verb
Definition SkPath.h:1460
@ kLine_Verb
Definition SkPath.h:1459

◆ 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

◆ 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}