OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2014 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 SkCubicSpan_DEFINE |
| 8 #define SkCubicSpan_DEFINE |
| 9 |
| 10 #include "SkChunkAlloc.h" |
| 11 #include "SkPathOpsRect.h" |
| 12 #include "SkPathOpsCubic.h" |
| 13 #include "SkTArray.h" |
| 14 |
| 15 class SkIntersections; |
| 16 |
| 17 class SkCubicCoincident { |
| 18 public: |
| 19 bool isCoincident() const { |
| 20 return fCoincident; |
| 21 } |
| 22 |
| 23 void init() { |
| 24 fCoincident = false; |
| 25 SkDEBUGCODE(fPerpPt.fX = fPerpPt.fY = SK_ScalarNaN); |
| 26 SkDEBUGCODE(fPerpT = SK_ScalarNaN); |
| 27 } |
| 28 |
| 29 void markCoincident() { |
| 30 if (!fCoincident) { |
| 31 fPerpT = -1; |
| 32 } |
| 33 fCoincident = true; |
| 34 } |
| 35 |
| 36 const SkDPoint& perpPt() const { |
| 37 return fPerpPt; |
| 38 } |
| 39 |
| 40 double perpT() const { |
| 41 return fPerpT; |
| 42 } |
| 43 |
| 44 void setPerp(const SkDCubic& cubic1, double t, const SkDPoint& qPt, const Sk
DCubic& cubic2); |
| 45 |
| 46 private: |
| 47 SkDPoint fPerpPt; |
| 48 double fPerpT; // perpendicular intersection on opposite Cubic |
| 49 bool fCoincident; |
| 50 }; |
| 51 |
| 52 class SkCubicSect; // used only by debug id |
| 53 |
| 54 class SkCubicSpan { |
| 55 public: |
| 56 void init(const SkDCubic& Cubic); |
| 57 void initBounds(const SkDCubic& Cubic); |
| 58 |
| 59 bool contains(double t) const { |
| 60 return !! const_cast<SkCubicSpan*>(this)->innerFind(t); |
| 61 } |
| 62 |
| 63 bool contains(const SkCubicSpan* span) const; |
| 64 |
| 65 SkCubicSpan* find(double t) { |
| 66 SkCubicSpan* result = innerFind(t); |
| 67 SkASSERT(result); |
| 68 return result; |
| 69 } |
| 70 |
| 71 bool intersects(const SkCubicSpan* span) const; |
| 72 |
| 73 const SkCubicSpan* next() const { |
| 74 return fNext; |
| 75 } |
| 76 |
| 77 void reset() { |
| 78 fBounded.reset(); |
| 79 } |
| 80 |
| 81 bool split(SkCubicSpan* work) { |
| 82 return splitAt(work, (work->fStartT + work->fEndT) * 0.5); |
| 83 } |
| 84 |
| 85 bool splitAt(SkCubicSpan* work, double t); |
| 86 bool tightBoundsIntersects(const SkCubicSpan* span) const; |
| 87 |
| 88 // implementation is for testing only |
| 89 void dump() const; |
| 90 |
| 91 private: |
| 92 bool hullIntersects(const SkDCubic& ) const; |
| 93 SkCubicSpan* innerFind(double t); |
| 94 bool linearIntersects(const SkDCubic& ) const; |
| 95 |
| 96 // implementation is for testing only |
| 97 #if DEBUG_BINARY_CUBIC |
| 98 int debugID(const SkCubicSect* ) const { return fDebugID; } |
| 99 #else |
| 100 int debugID(const SkCubicSect* ) const; |
| 101 #endif |
| 102 void dump(const SkCubicSect* ) const; |
| 103 void dumpID(const SkCubicSect* ) const; |
| 104 |
| 105 #if DEBUG_BINARY_CUBIC |
| 106 void validate() const; |
| 107 #endif |
| 108 |
| 109 SkDCubic fPart; |
| 110 SkCubicCoincident fCoinStart; |
| 111 SkCubicCoincident fCoinEnd; |
| 112 SkSTArray<4, SkCubicSpan*, true> fBounded; |
| 113 SkCubicSpan* fPrev; |
| 114 SkCubicSpan* fNext; |
| 115 SkDRect fBounds; |
| 116 double fStartT; |
| 117 double fEndT; |
| 118 double fBoundsMax; |
| 119 bool fCollapsed; |
| 120 bool fHasPerp; |
| 121 mutable bool fIsLinear; |
| 122 #if DEBUG_BINARY_CUBIC |
| 123 int fDebugID; |
| 124 bool fDebugDeleted; |
| 125 #endif |
| 126 friend class SkCubicSect; |
| 127 }; |
| 128 |
| 129 class SkCubicSect { |
| 130 public: |
| 131 SkCubicSect(const SkDCubic& Cubic PATH_OPS_DEBUG_PARAMS(int id)); |
| 132 static void BinarySearch(SkCubicSect* sect1, SkCubicSect* sect2, SkIntersect
ions* intersections); |
| 133 |
| 134 // for testing only |
| 135 void dumpCubics() const; |
| 136 private: |
| 137 SkCubicSpan* addOne(); |
| 138 bool binarySearchCoin(const SkCubicSect& , double tStart, double tStep, doub
le* t, |
| 139 double* oppT); |
| 140 SkCubicSpan* boundsMax() const; |
| 141 void coincidentCheck(SkCubicSect* sect2); |
| 142 bool intersects(const SkCubicSpan* span, const SkCubicSect* opp, const SkCub
icSpan* oppSpan) const; |
| 143 void onCurveCheck(SkCubicSect* sect2, SkCubicSpan* first, SkCubicSpan* last)
; |
| 144 void recoverCollapsed(); |
| 145 void removeSpan(SkCubicSpan* span); |
| 146 void removeOne(const SkCubicSpan* test, SkCubicSpan* span); |
| 147 void removeSpans(SkCubicSpan* span, SkCubicSect* opp); |
| 148 void setPerp(const SkDCubic& opp, SkCubicSpan* first, SkCubicSpan* last); |
| 149 void trim(SkCubicSpan* span, SkCubicSect* opp); |
| 150 |
| 151 // for testing only |
| 152 void dump() const; |
| 153 void dumpBoth(const SkCubicSect& opp) const; |
| 154 void dumpBoth(const SkCubicSect* opp) const; |
| 155 |
| 156 #if DEBUG_BINARY_CUBIC |
| 157 int debugID() const { return fDebugID; } |
| 158 void validate() const; |
| 159 #else |
| 160 int debugID() const { return 0; } |
| 161 #endif |
| 162 const SkDCubic& fCubic; |
| 163 SkChunkAlloc fHeap; |
| 164 SkCubicSpan* fHead; |
| 165 SkCubicSpan* fDeleted; |
| 166 int fActiveCount; |
| 167 #if DEBUG_BINARY_CUBIC |
| 168 int fDebugID; |
| 169 int fDebugCount; |
| 170 int fDebugAllocatedCount; |
| 171 #endif |
| 172 friend class SkCubicSpan; // only used by debug id |
| 173 }; |
| 174 |
| 175 #endif |
OLD | NEW |