caryclark@google.com | 9e49fb6 | 2012-08-27 14:11:33 +0000 | [diff] [blame] | 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 | */ |
caryclark@google.com | a576423 | 2012-03-28 16:20:21 +0000 | [diff] [blame] | 7 | #ifndef Intersections_DEFINE |
| 8 | #define Intersections_DEFINE |
| 9 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 10 | class Intersections { |
| 11 | public: |
skia.committer@gmail.com | 9f876ed | 2013-01-20 07:05:51 +0000 | [diff] [blame] | 12 | Intersections() |
caryclark@google.com | 05c4bad | 2013-01-19 13:22:39 +0000 | [diff] [blame] | 13 | : fFlip(0) |
caryclark@google.com | f9502d7 | 2013-02-04 14:06:49 +0000 | [diff] [blame] | 14 | #if SK_DEBUG |
| 15 | , fDepth(0) |
| 16 | #endif |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 17 | , fSwap(0) |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 18 | { |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 19 | #if SK_DEBUG |
| 20 | bzero(fPt, sizeof(fPt)); |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 21 | bzero(fT, sizeof(fT)); |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 22 | bzero(fIsCoincident, sizeof(fIsCoincident)); |
| 23 | #endif |
caryclark@google.com | 05c4bad | 2013-01-19 13:22:39 +0000 | [diff] [blame] | 24 | reset(); |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 25 | } |
| 26 | |
caryclark@google.com | f9502d7 | 2013-02-04 14:06:49 +0000 | [diff] [blame] | 27 | int coincidentUsed() const { |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 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 | #if SK_DEBUG |
| 39 | if (fIsCoincident[1] & (1 << index)) { |
| 40 | ++count2; |
| 41 | } |
| 42 | #endif |
| 43 | } |
| 44 | SkASSERT(count == count2); |
| 45 | return count; |
caryclark@google.com | 32546db | 2012-08-31 20:55:07 +0000 | [diff] [blame] | 46 | } |
skia.committer@gmail.com | 0c38ed3 | 2013-02-05 07:02:01 +0000 | [diff] [blame] | 47 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 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 | } |
skia.committer@gmail.com | 055c7c2 | 2012-09-15 02:01:41 +0000 | [diff] [blame] | 56 | |
caryclark@google.com | 7ff5c84 | 2013-02-26 15:56:05 +0000 | [diff] [blame] | 57 | // FIXME : does not respect swap |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 58 | int insert(double one, double two, const _Point& pt); |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 59 | |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 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 | } |
skia.committer@gmail.com | 044679e | 2013-02-15 07:16:57 +0000 | [diff] [blame] | 67 | |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 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 | } |
skia.committer@gmail.com | 044679e | 2013-02-15 07:16:57 +0000 | [diff] [blame] | 78 | |
caryclark@google.com | 235f56a | 2012-09-14 14:19:30 +0000 | [diff] [blame] | 79 | bool intersected() const { |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 80 | return fUsed > 0; |
| 81 | } |
skia.committer@gmail.com | 055c7c2 | 2012-09-15 02:01:41 +0000 | [diff] [blame] | 82 | |
caryclark@google.com | 47d73da | 2013-02-17 01:41:25 +0000 | [diff] [blame] | 83 | void removeOne(int index); |
skia.committer@gmail.com | e7707c2 | 2013-02-17 07:02:20 +0000 | [diff] [blame] | 84 | |
caryclark@google.com | 05c4bad | 2013-01-19 13:22:39 +0000 | [diff] [blame] | 85 | // leaves flip, swap alone |
| 86 | void reset() { |
caryclark@google.com | 47d73da | 2013-02-17 01:41:25 +0000 | [diff] [blame] | 87 | fUsed = 0; |
caryclark@google.com | 05c4bad | 2013-01-19 13:22:39 +0000 | [diff] [blame] | 88 | fUnsortable = false; |
| 89 | } |
| 90 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 91 | void swap() { |
caryclark@google.com | 73ca624 | 2013-01-17 21:02:47 +0000 | [diff] [blame] | 92 | fSwap ^= true; |
| 93 | } |
skia.committer@gmail.com | 15dd300 | 2013-01-18 07:07:28 +0000 | [diff] [blame] | 94 | |
caryclark@google.com | 73ca624 | 2013-01-17 21:02:47 +0000 | [diff] [blame] | 95 | void swapPts() { |
| 96 | int index; |
| 97 | for (index = 0; index < fUsed; ++index) { |
| 98 | SkTSwap(fT[0][index], fT[1][index]); |
| 99 | } |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 100 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 101 | |
caryclark@google.com | 73ca624 | 2013-01-17 21:02:47 +0000 | [diff] [blame] | 102 | bool swapped() const { |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 103 | return fSwap; |
| 104 | } |
| 105 | |
caryclark@google.com | 73ca624 | 2013-01-17 21:02:47 +0000 | [diff] [blame] | 106 | bool unsortable() const { |
| 107 | return fUnsortable; |
| 108 | } |
| 109 | |
| 110 | int used() const { |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 111 | return fUsed; |
| 112 | } |
| 113 | |
caryclark@google.com | f9502d7 | 2013-02-04 14:06:49 +0000 | [diff] [blame] | 114 | void downDepth() { |
| 115 | SkASSERT(--fDepth >= 0); |
| 116 | } |
| 117 | |
| 118 | void upDepth() { |
| 119 | SkASSERT(++fDepth < 16); |
| 120 | } |
| 121 | |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 122 | #if SK_DEBUG |
| 123 | int depth() const { |
| 124 | return fDepth; |
| 125 | } |
| 126 | #endif |
| 127 | |
| 128 | _Point fPt[9]; |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 129 | double fT[2][9]; |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 130 | unsigned short fIsCoincident[2]; // bit arrays, one bit set for each coincident T |
| 131 | unsigned char fUsed; |
caryclark@google.com | 73ca624 | 2013-01-17 21:02:47 +0000 | [diff] [blame] | 132 | bool fFlip; |
| 133 | bool fUnsortable; |
caryclark@google.com | f9502d7 | 2013-02-04 14:06:49 +0000 | [diff] [blame] | 134 | #if SK_DEBUG |
| 135 | int fDepth; |
| 136 | #endif |
caryclark@google.com | beda389 | 2013-02-07 13:13:41 +0000 | [diff] [blame] | 137 | protected: |
| 138 | // used by addCoincident to remove ordinary intersections in range |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 139 | void remove(double one, double two, const _Point& startPt, const _Point& endPt); |
caryclark@google.com | a576423 | 2012-03-28 16:20:21 +0000 | [diff] [blame] | 140 | private: |
caryclark@google.com | 45a8fc6 | 2013-02-14 15:29:11 +0000 | [diff] [blame] | 141 | bool fSwap; |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 142 | }; |
caryclark@google.com | a576423 | 2012-03-28 16:20:21 +0000 | [diff] [blame] | 143 | |
| 144 | #endif |