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 8 #ifndef SkPathOpsQuad_DEFINED 9 #define SkPathOpsQuad_DEFINED 10 11 #include "SkPathOpsPoint.h" 12 13 struct SkOpCurve; 14 15 struct SkDQuadPair { 16 const SkDQuad& first() const { return (const SkDQuad&) pts[0]; } 17 const SkDQuad& second() const { return (const SkDQuad&) pts[2]; } 18 SkDPoint pts[5]; 19 }; 20 21 struct SkDQuad { 22 static const int kPointCount = 3; 23 static const int kPointLast = kPointCount - 1; 24 static const int kMaxIntersections = 4; 25 26 SkDPoint fPts[kPointCount]; 27 28 bool collapsed() const { 29 return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual(fPts[2]); 30 } 31 32 bool controlsInside() const { 33 SkDVector v01 = fPts[0] - fPts[1]; 34 SkDVector v02 = fPts[0] - fPts[2]; 35 SkDVector v12 = fPts[1] - fPts[2]; 36 return v02.dot(v01) > 0 && v02.dot(v12) > 0; 37 } 38 39 void debugInit() { 40 sk_bzero(fPts, sizeof(fPts)); 41 } 42 43 void debugSet(const SkDPoint* pts); 44 45 SkDQuad flip() const { 46 SkDQuad result = {{fPts[2], fPts[1], fPts[0]} SkDEBUGPARAMS(fDebugGlobalState) }; 47 return result; 48 } 49 50 static bool IsConic() { return false; } 51 52 const SkDQuad& set(const SkPoint pts[kPointCount] 53 SkDEBUGPARAMS(SkOpGlobalState* state = nullptr)) { 54 fPts[0] = pts[0]; 55 fPts[1] = pts[1]; 56 fPts[2] = pts[2]; 57 SkDEBUGCODE(fDebugGlobalState = state); 58 return *this; 59 } 60 61 const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; } 62 SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; } 63 64 static int AddValidTs(double s[], int realRoots, double* t); 65 void align(int endIndex, SkDPoint* dstPt) const; 66 SkDQuadPair chopAt(double t) const; 67 SkDVector dxdyAtT(double t) const; 68 static int FindExtrema(const double src[], double tValue[1]); 69 70 #ifdef SK_DEBUG 71 SkOpGlobalState* globalState() const { return fDebugGlobalState; } 72 #endif 73 74 /** 75 * Return the number of valid roots (0 < root < 1) for this cubic intersecting the 76 * specified horizontal line. 77 */ 78 int horizontalIntersect(double yIntercept, double roots[2]) const; 79 80 bool hullIntersects(const SkDQuad& , bool* isLinear) const; 81 bool hullIntersects(const SkDConic& , bool* isLinear) const; 82 bool hullIntersects(const SkDCubic& , bool* isLinear) const; 83 bool isLinear(int startIndex, int endIndex) const; 84 bool monotonicInX() const; 85 bool monotonicInY() const; 86 void otherPts(int oddMan, const SkDPoint* endPt[2]) const; 87 SkDPoint ptAtT(double t) const; 88 static int RootsReal(double A, double B, double C, double t[2]); 89 static int RootsValidT(const double A, const double B, const double C, double s[2]); 90 static void SetABC(const double* quad, double* a, double* b, double* c); 91 SkDQuad subDivide(double t1, double t2) const; 92 static SkDQuad SubDivide(const SkPoint a[kPointCount], double t1, double t2) { 93 SkDQuad quad; 94 quad.set(a); 95 return quad.subDivide(t1, t2); 96 } 97 SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const; 98 static SkDPoint SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, const SkDPoint& c, 99 double t1, double t2) { 100 SkDQuad quad; 101 quad.set(pts); 102 return quad.subDivide(a, c, t1, t2); 103 } 104 105 /** 106 * Return the number of valid roots (0 < root < 1) for this cubic intersecting the 107 * specified vertical line. 108 */ 109 int verticalIntersect(double xIntercept, double roots[2]) const; 110 111 SkDCubic debugToCubic() const; 112 // utilities callable by the user from the debugger when the implementation code is linked in 113 void dump() const; 114 void dumpID(int id) const; 115 void dumpInner() const; 116 117 SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState); 118 }; 119 120 #endif 121