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