Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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) {
72 SkDConic conic;
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) {
80 SkDConic conic;
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]) {
87 SkDConic conic;
88 conic.set(a, weight);
89 SkDLine line;
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) {
97 SkDCubic cubic;
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) {
104 SkDCubic cubic;
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]) {
111 SkDCubic cubic;
112 cubic.set(a);
113 SkDLine line;
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) {
147 SkDLine line;
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) {
154 SkDLine line;
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);
199 SkDLine line;
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
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
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static bool between(SkScalar a, SkScalar b, SkScalar c)
#define SK_DEBUG
static void sk_bzero(void *buffer, size_t size)
Definition SkMalloc.h:105
#define SkDEBUGPARAMS(...)
const double BUMP_EPSILON
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
Type::kYUV Type::kRGBA() int(0.7 *637)
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
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)
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
const SkDLine & set(const SkPoint pts[2])
const SkDQuad & set(const SkPoint pts[kPointCount] SkDEBUGPARAMS(SkOpGlobalState *state=nullptr))