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 Intersections_DEFINE 8 #define Intersections_DEFINE 9 10 class Intersections { 11 public: 12 Intersections() 13 : fFlip(0) 14 #ifdef SK_DEBUG 15 , fDepth(0) 16 #endif 17 , fSwap(0) 18 { 19 #ifdef SK_DEBUG 20 bzero(fPt, sizeof(fPt)); 21 bzero(fT, sizeof(fT)); 22 bzero(fIsCoincident, sizeof(fIsCoincident)); 23 #endif 24 reset(); 25 } 26 27 int coincidentUsed() const { 28 if (!fIsCoincident[0]) { 29 SkASSERT(!fIsCoincident[0]); 30 return 0; 31 } 32 int count = 0; 33 SkDEBUGCODE(int count2 = 0;) 34 for (int index = 0; index < fUsed; ++index) { 35 if (fIsCoincident[0] & (1 << index)) { 36 ++count; 37 } 38 #ifdef SK_DEBUG 39 if (fIsCoincident[1] & (1 << index)) { 40 ++count2; 41 } 42 #endif 43 } 44 SkASSERT(count == count2); 45 return count; 46 } 47 48 void offset(int base, double start, double end) { 49 for (int index = base; index < fUsed; ++index) { 50 double val = fT[fSwap][index]; 51 val *= end - start; 52 val += start; 53 fT[fSwap][index] = val; 54 } 55 } 56 57 // FIXME : does not respect swap 58 int insert(double one, double two, const _Point& pt); 59 60 // start if index == 0 : end if index == 1 61 void insertCoincident(double one, double two, const _Point& pt) { 62 int index = insertSwap(one, two, pt); 63 int bit = 1 << index; 64 fIsCoincident[0] |= bit; 65 fIsCoincident[1] |= bit; 66 } 67 68 void insertCoincidentPair(double s1, double e1, double s2, double e2, 69 const _Point& startPt, const _Point& endPt); 70 71 int insertSwap(double one, double two, const _Point& pt) { 72 if (fSwap) { 73 return insert(two, one, pt); 74 } else { 75 return insert(one, two, pt); 76 } 77 } 78 79 bool intersected() const { 80 return fUsed > 0; 81 } 82 83 void removeOne(int index); 84 85 // leaves flip, swap alone 86 void reset() { 87 fUsed = 0; 88 fUnsortable = false; 89 } 90 91 void swap() { 92 fSwap ^= true; 93 } 94 95 void swapPts() { 96 int index; 97 for (index = 0; index < fUsed; ++index) { 98 SkTSwap(fT[0][index], fT[1][index]); 99 } 100 } 101 102 bool swapped() const { 103 return fSwap; 104 } 105 106 bool unsortable() const { 107 return fUnsortable; 108 } 109 110 int used() const { 111 return fUsed; 112 } 113 114 void downDepth() { 115 SkASSERT(--fDepth >= 0); 116 } 117 118 void upDepth() { 119 SkASSERT(++fDepth < 16); 120 } 121 122 #ifdef SK_DEBUG 123 int depth() const { 124 return fDepth; 125 } 126 #endif 127 128 _Point fPt[9]; 129 double fT[2][9]; 130 unsigned short fIsCoincident[2]; // bit arrays, one bit set for each coincident T 131 unsigned char fUsed; 132 bool fFlip; 133 bool fUnsortable; 134 #ifdef SK_DEBUG 135 int fDepth; 136 #endif 137 protected: 138 // used by addCoincident to remove ordinary intersections in range 139 void remove(double one, double two, const _Point& startPt, const _Point& endPt); 140 private: 141 bool fSwap; 142 }; 143 144 #endif 145