Flutter Engine
The Flutter Engine
SkIntersections.h
Go to the documentation of this file.
1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#ifndef SkIntersections_DEFINE
8#define SkIntersections_DEFINE
9
23
24#include <array>
25#include <cstdint>
26
27struct SkDRect;
28
30public:
32 : fSwap(0)
33#ifdef SK_DEBUG
34 SkDEBUGPARAMS(fDebugGlobalState(globalState))
35 , fDepth(0)
36#endif
37 {
38 sk_bzero(fPt, sizeof(fPt));
39 sk_bzero(fPt2, sizeof(fPt2));
40 sk_bzero(fT, sizeof(fT));
41 sk_bzero(fNearlySame, sizeof(fNearlySame));
42#if DEBUG_T_SECT_LOOP_COUNT
43 sk_bzero(fDebugLoopCount, sizeof(fDebugLoopCount));
44#endif
45 reset();
46 fMax = 0; // require that the caller set the max
47 }
48
49 class TArray {
50 public:
51 explicit TArray(const double ts[10]) : fTArray(ts) {}
52 double operator[](int n) const {
53 return fTArray[n];
54 }
55 const double* fTArray;
56 };
57 TArray operator[](int n) const { return TArray(fT[n]); }
58
59 void allowNear(bool nearAllowed) {
60 fAllowNear = nearAllowed;
61 }
62
63 void clearCoincidence(int index) {
64 SkASSERT(index >= 0);
65 int bit = 1 << index;
66 fIsCoincident[0] &= ~bit;
67 fIsCoincident[1] &= ~bit;
68 }
69
71 SkScalar y, bool flipped) {
73 conic.set(a, weight);
74 fMax = 2;
75 return horizontal(conic, left, right, y, flipped);
76 }
77
78 int conicVertical(const SkPoint a[3], SkScalar weight, SkScalar top, SkScalar bottom,
79 SkScalar x, bool flipped) {
81 conic.set(a, weight);
82 fMax = 2;
83 return vertical(conic, top, bottom, x, flipped);
84 }
85
86 int conicLine(const SkPoint a[3], SkScalar weight, const SkPoint b[2]) {
88 conic.set(a, weight);
90 line.set(b);
91 fMax = 3; // 2; permit small coincident segment + non-coincident intersection
92 return intersect(conic, line);
93 }
94
96 bool flipped) {
98 cubic.set(a);
99 fMax = 3;
100 return horizontal(cubic, left, right, y, flipped);
101 }
102
103 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
105 cubic.set(a);
106 fMax = 3;
107 return vertical(cubic, top, bottom, x, flipped);
108 }
109
110 int cubicLine(const SkPoint a[4], const SkPoint b[2]) {
112 cubic.set(a);
114 line.set(b);
115 fMax = 3;
116 return intersect(cubic, line);
117 }
118
119#ifdef SK_DEBUG
120 SkOpGlobalState* globalState() const { return fDebugGlobalState; }
121#endif
122
123 bool hasT(double t) const {
124 SkASSERT(t == 0 || t == 1);
125 return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1);
126 }
127
128 bool hasOppT(double t) const {
129 SkASSERT(t == 0 || t == 1);
130 return fUsed > 0 && (fT[1][0] == t || fT[1][fUsed - 1] == t);
131 }
132
133 int insertSwap(double one, double two, const SkDPoint& pt) {
134 if (fSwap) {
135 return insert(two, one, pt);
136 } else {
137 return insert(one, two, pt);
138 }
139 }
140
141 bool isCoincident(int index) {
142 return (fIsCoincident[0] & 1 << index) != 0;
143 }
144
146 bool flipped) {
148 line.set(a);
149 fMax = 2;
150 return horizontal(line, left, right, y, flipped);
151 }
152
153 int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
155 line.set(a);
156 fMax = 2;
157 return vertical(line, top, bottom, x, flipped);
158 }
159
160 int lineLine(const SkPoint a[2], const SkPoint b[2]) {
161 SkDLine aLine, bLine;
162 aLine.set(a);
163 bLine.set(b);
164 fMax = 2;
165 return intersect(aLine, bLine);
166 }
167
168 bool nearlySame(int index) const {
169 SkASSERT(index == 0 || index == 1);
170 return fNearlySame[index];
171 }
172
173 const SkDPoint& pt(int index) const {
174 return fPt[index];
175 }
176
177 const SkDPoint& pt2(int index) const {
178 return fPt2[index];
179 }
180
182 bool flipped) {
183 SkDQuad quad;
184 quad.set(a);
185 fMax = 2;
186 return horizontal(quad, left, right, y, flipped);
187 }
188
189 int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
190 SkDQuad quad;
191 quad.set(a);
192 fMax = 2;
193 return vertical(quad, top, bottom, x, flipped);
194 }
195
196 int quadLine(const SkPoint a[3], const SkPoint b[2]) {
197 SkDQuad quad;
198 quad.set(a);
200 line.set(b);
201 return intersect(quad, line);
202 }
203
204 // leaves swap, max alone
205 void reset() {
206 fAllowNear = true;
207 fUsed = 0;
208 sk_bzero(fIsCoincident, sizeof(fIsCoincident));
209 }
210
211 void set(bool swap, int tIndex, double t) {
212 fT[(int) swap][tIndex] = t;
213 }
214
215 void setMax(int max) {
216 SkASSERT(max <= (int) std::size(fPt));
217 fMax = max;
218 }
219
220 void swap() {
221 fSwap ^= true;
222 }
223
224 bool swapped() const {
225 return fSwap;
226 }
227
228 int used() const {
229 return fUsed;
230 }
231
232 void downDepth() {
233 SkASSERT(--fDepth >= 0);
234 }
235
236 bool unBumpT(int index) {
237 SkASSERT(fUsed == 1);
238 fT[0][index] = fT[0][index] * (1 + BUMP_EPSILON * 2) - BUMP_EPSILON;
239 if (!between(0, fT[0][index], 1)) {
240 fUsed = 0;
241 return false;
242 }
243 return true;
244 }
245
246 void upDepth() {
247 SkASSERT(++fDepth < 16);
248 }
249
250 void alignQuadPts(const SkPoint a[3], const SkPoint b[3]);
252 int closestTo(double rangeStart, double rangeEnd, const SkDPoint& testPt, double* dist) const;
253 void cubicInsert(double one, double two, const SkDPoint& pt, const SkDCubic& c1,
254 const SkDCubic& c2);
255 void flip();
256 int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
257 int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
258 int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
259 int horizontal(const SkDCubic&, double y, double tRange[3]);
260 int horizontal(const SkDConic&, double left, double right, double y, bool flipped);
261 int horizontal(const SkDCubic&, double left, double right, double y, bool flipped);
262 int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]);
263 static double HorizontalIntercept(const SkDLine& line, double y);
264 static int HorizontalIntercept(const SkDQuad& quad, SkScalar y, double* roots);
265 static int HorizontalIntercept(const SkDConic& conic, SkScalar y, double* roots);
266 // FIXME : does not respect swap
267 int insert(double one, double two, const SkDPoint& pt);
268 void insertNear(double one, double two, const SkDPoint& pt1, const SkDPoint& pt2);
269 // start if index == 0 : end if index == 1
270 int insertCoincident(double one, double two, const SkDPoint& pt);
271 int intersect(const SkDLine&, const SkDLine&);
272 int intersect(const SkDQuad&, const SkDLine&);
273 int intersect(const SkDQuad&, const SkDQuad&);
274 int intersect(const SkDConic&, const SkDLine&);
275 int intersect(const SkDConic&, const SkDQuad&);
276 int intersect(const SkDConic&, const SkDConic&);
277 int intersect(const SkDCubic&, const SkDLine&);
278 int intersect(const SkDCubic&, const SkDQuad&);
279 int intersect(const SkDCubic&, const SkDConic&);
280 int intersect(const SkDCubic&, const SkDCubic&);
281 int intersectRay(const SkDLine&, const SkDLine&);
282 int intersectRay(const SkDQuad&, const SkDLine&);
283 int intersectRay(const SkDConic&, const SkDLine&);
284 int intersectRay(const SkDCubic&, const SkDLine&);
285 int intersectRay(const SkTCurve& tCurve, const SkDLine& line) {
286 return tCurve.intersectRay(this, line);
287 }
288
289 void merge(const SkIntersections& , int , const SkIntersections& , int );
290 int mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin) const;
291 void removeOne(int index);
292 void setCoincident(int index);
293 int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
294 int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
295 int vertical(const SkDConic&, double top, double bottom, double x, bool flipped);
296 int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
297 static double VerticalIntercept(const SkDLine& line, double x);
298 static int VerticalIntercept(const SkDQuad& quad, SkScalar x, double* roots);
299 static int VerticalIntercept(const SkDConic& conic, SkScalar x, double* roots);
300
301 int depth() const {
302#ifdef SK_DEBUG
303 return fDepth;
304#else
305 return 0;
306#endif
307 }
308
313 };
314
316 int debugCoincidentUsed() const;
319 void dump() const; // implemented for testing only
320
321private:
322 bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2);
323 bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2);
324 void cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2, const SkDRect& );
325 void cleanUpParallelLines(bool parallel);
326 void computePoints(const SkDLine& line, int used);
327
328 SkDPoint fPt[13]; // FIXME: since scans store points as SkPoint, this should also
329 SkDPoint fPt2[2]; // used by nearly same to store alternate intersection point
330 double fT[2][13];
331 uint16_t fIsCoincident[2]; // bit set for each curve's coincident T
332 bool fNearlySame[2]; // true if end points nearly match
333 unsigned char fUsed;
334 unsigned char fMax;
335 bool fAllowNear;
336 bool fSwap;
337#ifdef SK_DEBUG
338 SkOpGlobalState* fDebugGlobalState;
339 int fDepth;
340#endif
341#if DEBUG_T_SECT_LOOP_COUNT
342 int fDebugLoopCount[3];
343#endif
344};
345
346#endif
sk_bzero(glyphs, sizeof(glyphs))
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SK_DEBUG
#define SkDEBUGPARAMS(...)
const double BUMP_EPSILON
bool between(double a, double b, double c)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
double operator[](int n) const
TArray(const double ts[10])
void merge(const SkIntersections &, int, const SkIntersections &, int)
const SkDPoint & pt2(int index) const
void cubicInsert(double one, double two, const SkDPoint &pt, const SkDCubic &c1, const SkDCubic &c2)
int intersectRay(const SkDLine &, const SkDLine &)
int conicHorizontal(const SkPoint a[3], SkScalar weight, SkScalar left, SkScalar right, SkScalar y, bool flipped)
int insertSwap(double one, double two, const SkDPoint &pt)
int horizontal(const SkDCubic &, double y, double tRange[3])
TArray operator[](int n) const
int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped)
bool nearlySame(int index) const
int insert(double one, double two, const SkDPoint &pt)
int intersect(const SkDLine &, const SkDLine &)
int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped)
int intersectRay(const SkTCurve &tCurve, const SkDLine &line)
void allowNear(bool nearAllowed)
void removeOne(int index)
int horizontal(const SkDQuad &, double left, double right, double y, double tRange[2])
const SkDPoint & pt(int index) const
void insertNear(double one, double two, const SkDPoint &pt1, const SkDPoint &pt2)
int lineLine(const SkPoint a[2], const SkPoint b[2])
int conicVertical(const SkPoint a[3], SkScalar weight, SkScalar top, SkScalar bottom, SkScalar x, bool flipped)
void dump() const
int insertCoincident(double one, double two, const SkDPoint &pt)
int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y, bool flipped)
bool swapped() const
int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped)
int debugLoopCount(DebugLoop) const
int cubicLine(const SkPoint a[4], const SkPoint b[2])
static double VerticalIntercept(const SkDLine &line, double x)
int vertical(const SkDLine &, double top, double bottom, double x, bool flipped)
int closestTo(double rangeStart, double rangeEnd, const SkDPoint &testPt, double *dist) const
int debugCoincidentUsed() const
int depth() const
bool hasOppT(double t) const
SkIntersections(SkDEBUGCODE(SkOpGlobalState *globalState=nullptr))
void alignQuadPts(const SkPoint a[3], const SkPoint b[3])
bool hasT(double t) const
static double HorizontalIntercept(const SkDLine &line, double y)
void debugResetLoopCount()
int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y, bool flipped)
int cleanUpCoincidence()
void debugBumpLoopCount(DebugLoop)
int used() const
bool unBumpT(int index)
void setCoincident(int index)
void set(bool swap, int tIndex, double t)
int horizontal(const SkDLine &, double left, double right, double y, bool flipped)
bool isCoincident(int index)
int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y, bool flipped)
int conicLine(const SkPoint a[3], SkScalar weight, const SkPoint b[2])
void clearCoincidence(int index)
void setMax(int max)
int quadLine(const SkPoint a[3], const SkPoint b[2])
int mostOutside(double rangeStart, double rangeEnd, const SkDPoint &origin) const
int horizontal(const SkDCubic &, double left, double right, double y, double tRange[3])
virtual int intersectRay(SkIntersections *i, const SkDLine &line) const =0
float SkScalar
Definition: extension.cpp:12
static bool b
struct MyStruct a[10]
static float max(float r, float g, float b)
Definition: hsl.cpp:49
double y
double x
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
Definition: switches.h:259
AI float conic(float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:287
AI float cubic(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:195
const SkDLine & set(const SkPoint pts[2])
Definition: SkPathOpsLine.h:20
const SkDQuad & set(const SkPoint pts[kPointCount] SkDEBUGPARAMS(SkOpGlobalState *state=nullptr))
Definition: SkPathOpsQuad.h:65