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