| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 #ifndef SkIntersections_DEFINE | 7 #ifndef SkIntersections_DEFINE |
| 8 #define SkIntersections_DEFINE | 8 #define SkIntersections_DEFINE |
| 9 | 9 |
| 10 #include "SkPathOpsCubic.h" | 10 #include "SkPathOpsCubic.h" |
| 11 #include "SkPathOpsLine.h" | 11 #include "SkPathOpsLine.h" |
| 12 #include "SkPathOpsPoint.h" | 12 #include "SkPathOpsPoint.h" |
| 13 #include "SkPathOpsQuad.h" | 13 #include "SkPathOpsQuad.h" |
| 14 | 14 |
| 15 class SkIntersections { | 15 class SkIntersections { |
| 16 public: | 16 public: |
| 17 SkIntersections() | 17 SkIntersections() |
| 18 : fSwap(0) | 18 : fSwap(0) |
| 19 #ifdef SK_DEBUG | 19 #ifdef SK_DEBUG |
| 20 , fDepth(0) | 20 , fDepth(0) |
| 21 #endif | 21 #endif |
| 22 { | 22 { |
| 23 sk_bzero(fPt, sizeof(fPt)); | 23 sk_bzero(fPt, sizeof(fPt)); |
| 24 sk_bzero(fT, sizeof(fT)); | 24 sk_bzero(fT, sizeof(fT)); |
| 25 sk_bzero(fIsCoincident, sizeof(fIsCoincident)); | 25 sk_bzero(fIsCoincident, sizeof(fIsCoincident)); |
| 26 sk_bzero(&fIsNear, sizeof(fIsNear)); | 26 sk_bzero(&fIsNear, sizeof(fIsNear)); |
| 27 reset(); | 27 reset(); |
| 28 fMax = 0; // require that the caller set the max |
| 28 } | 29 } |
| 29 | 30 |
| 30 class TArray { | 31 class TArray { |
| 31 public: | 32 public: |
| 32 explicit TArray(const double ts[9]) : fTArray(ts) {} | 33 explicit TArray(const double ts[9]) : fTArray(ts) {} |
| 33 double operator[](int n) const { | 34 double operator[](int n) const { |
| 34 return fTArray[n]; | 35 return fTArray[n]; |
| 35 } | 36 } |
| 36 const double* fTArray; | 37 const double* fTArray; |
| 37 }; | 38 }; |
| 38 TArray operator[](int n) const { return TArray(fT[n]); } | 39 TArray operator[](int n) const { return TArray(fT[n]); } |
| 39 | 40 |
| 40 void set(const SkIntersections& i) { | 41 void set(const SkIntersections& i) { |
| 41 memcpy(fPt, i.fPt, sizeof(fPt)); | 42 memcpy(fPt, i.fPt, sizeof(fPt)); |
| 42 memcpy(fT, i.fT, sizeof(fT)); | 43 memcpy(fT, i.fT, sizeof(fT)); |
| 43 memcpy(fIsCoincident, i.fIsCoincident, sizeof(fIsCoincident)); | 44 memcpy(fIsCoincident, i.fIsCoincident, sizeof(fIsCoincident)); |
| 44 memcpy(&fIsNear, &i.fIsNear, sizeof(fIsNear)); | 45 memcpy(&fIsNear, &i.fIsNear, sizeof(fIsNear)); |
| 45 fUsed = i.fUsed; | 46 fUsed = i.fUsed; |
| 47 fMax = i.fMax; |
| 46 fSwap = i.fSwap; | 48 fSwap = i.fSwap; |
| 47 SkDEBUGCODE(fDepth = i.fDepth); | 49 SkDEBUGCODE(fDepth = i.fDepth); |
| 48 } | 50 } |
| 49 | 51 |
| 50 void allowNear(bool nearAllowed) { | 52 void allowNear(bool nearAllowed) { |
| 51 fAllowNear = nearAllowed; | 53 fAllowNear = nearAllowed; |
| 52 } | 54 } |
| 53 | 55 |
| 54 int cubic(const SkPoint a[4]) { | 56 int cubic(const SkPoint a[4]) { |
| 55 SkDCubic cubic; | 57 SkDCubic cubic; |
| 56 cubic.set(a); | 58 cubic.set(a); |
| 59 fMax = 1; // self intersect |
| 57 return intersect(cubic); | 60 return intersect(cubic); |
| 58 } | 61 } |
| 59 | 62 |
| 60 int cubicCubic(const SkPoint a[4], const SkPoint b[4]) { | 63 int cubicCubic(const SkPoint a[4], const SkPoint b[4]) { |
| 61 SkDCubic aCubic; | 64 SkDCubic aCubic; |
| 62 aCubic.set(a); | 65 aCubic.set(a); |
| 63 SkDCubic bCubic; | 66 SkDCubic bCubic; |
| 64 bCubic.set(b); | 67 bCubic.set(b); |
| 68 fMax = 9; |
| 65 return intersect(aCubic, bCubic); | 69 return intersect(aCubic, bCubic); |
| 66 } | 70 } |
| 67 | 71 |
| 68 int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkSca
lar y, | 72 int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkSca
lar y, |
| 69 bool flipped) { | 73 bool flipped) { |
| 70 SkDCubic cubic; | 74 SkDCubic cubic; |
| 71 cubic.set(a); | 75 cubic.set(a); |
| 76 fMax = 3; |
| 72 return horizontal(cubic, left, right, y, flipped); | 77 return horizontal(cubic, left, right, y, flipped); |
| 73 } | 78 } |
| 74 | 79 |
| 75 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScala
r x, bool flipped) { | 80 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScala
r x, bool flipped) { |
| 76 SkDCubic cubic; | 81 SkDCubic cubic; |
| 77 cubic.set(a); | 82 cubic.set(a); |
| 83 fMax = 3; |
| 78 return vertical(cubic, top, bottom, x, flipped); | 84 return vertical(cubic, top, bottom, x, flipped); |
| 79 } | 85 } |
| 80 | 86 |
| 81 int cubicLine(const SkPoint a[4], const SkPoint b[2]) { | 87 int cubicLine(const SkPoint a[4], const SkPoint b[2]) { |
| 82 SkDCubic cubic; | 88 SkDCubic cubic; |
| 83 cubic.set(a); | 89 cubic.set(a); |
| 84 SkDLine line; | 90 SkDLine line; |
| 85 line.set(b); | 91 line.set(b); |
| 92 fMax = 3; |
| 86 return intersect(cubic, line); | 93 return intersect(cubic, line); |
| 87 } | 94 } |
| 88 | 95 |
| 89 int cubicQuad(const SkPoint a[4], const SkPoint b[3]) { | 96 int cubicQuad(const SkPoint a[4], const SkPoint b[3]) { |
| 90 SkDCubic cubic; | 97 SkDCubic cubic; |
| 91 cubic.set(a); | 98 cubic.set(a); |
| 92 SkDQuad quad; | 99 SkDQuad quad; |
| 93 quad.set(b); | 100 quad.set(b); |
| 101 fMax = 6; |
| 94 return intersect(cubic, quad); | 102 return intersect(cubic, quad); |
| 95 } | 103 } |
| 96 | 104 |
| 97 bool hasT(double t) const { | 105 bool hasT(double t) const { |
| 98 SkASSERT(t == 0 || t == 1); | 106 SkASSERT(t == 0 || t == 1); |
| 99 return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1); | 107 return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1); |
| 100 } | 108 } |
| 101 | 109 |
| 102 int insertSwap(double one, double two, const SkDPoint& pt) { | 110 int insertSwap(double one, double two, const SkDPoint& pt) { |
| 103 if (fSwap) { | 111 if (fSwap) { |
| 104 return insert(two, one, pt); | 112 return insert(two, one, pt); |
| 105 } else { | 113 } else { |
| 106 return insert(one, two, pt); | 114 return insert(one, two, pt); |
| 107 } | 115 } |
| 108 } | 116 } |
| 109 | 117 |
| 110 bool isCoincident(int index) { | 118 bool isCoincident(int index) { |
| 111 return (fIsCoincident[0] & 1 << index) != 0; | 119 return (fIsCoincident[0] & 1 << index) != 0; |
| 112 } | 120 } |
| 113 | 121 |
| 114 bool isNear(int index) { | 122 bool isNear(int index) { |
| 115 return (fIsNear & 1 << index) != 0; | 123 return (fIsNear & 1 << index) != 0; |
| 116 } | 124 } |
| 117 | 125 |
| 118 int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScal
ar y, | 126 int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScal
ar y, |
| 119 bool flipped) { | 127 bool flipped) { |
| 120 SkDLine line; | 128 SkDLine line; |
| 121 line.set(a); | 129 line.set(a); |
| 130 fMax = 2; |
| 122 return horizontal(line, left, right, y, flipped); | 131 return horizontal(line, left, right, y, flipped); |
| 123 } | 132 } |
| 124 | 133 |
| 125 int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped) { | 134 int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped) { |
| 126 SkDLine line; | 135 SkDLine line; |
| 127 line.set(a); | 136 line.set(a); |
| 137 fMax = 2; |
| 128 return vertical(line, top, bottom, x, flipped); | 138 return vertical(line, top, bottom, x, flipped); |
| 129 } | 139 } |
| 130 | 140 |
| 131 int lineLine(const SkPoint a[2], const SkPoint b[2]) { | 141 int lineLine(const SkPoint a[2], const SkPoint b[2]) { |
| 132 SkDLine aLine, bLine; | 142 SkDLine aLine, bLine; |
| 133 aLine.set(a); | 143 aLine.set(a); |
| 134 bLine.set(b); | 144 bLine.set(b); |
| 145 fMax = 2; |
| 135 return intersect(aLine, bLine); | 146 return intersect(aLine, bLine); |
| 136 } | 147 } |
| 137 | 148 |
| 138 const SkDPoint& pt(int index) const { | 149 const SkDPoint& pt(int index) const { |
| 139 return fPt[index]; | 150 return fPt[index]; |
| 140 } | 151 } |
| 141 | 152 |
| 142 int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScal
ar y, | 153 int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScal
ar y, |
| 143 bool flipped) { | 154 bool flipped) { |
| 144 SkDQuad quad; | 155 SkDQuad quad; |
| 145 quad.set(a); | 156 quad.set(a); |
| 157 fMax = 2; |
| 146 return horizontal(quad, left, right, y, flipped); | 158 return horizontal(quad, left, right, y, flipped); |
| 147 } | 159 } |
| 148 | 160 |
| 149 int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped) { | 161 int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped) { |
| 150 SkDQuad quad; | 162 SkDQuad quad; |
| 151 quad.set(a); | 163 quad.set(a); |
| 164 fMax = 2; |
| 152 return vertical(quad, top, bottom, x, flipped); | 165 return vertical(quad, top, bottom, x, flipped); |
| 153 } | 166 } |
| 154 | 167 |
| 155 int quadLine(const SkPoint a[3], const SkPoint b[2]) { | 168 int quadLine(const SkPoint a[3], const SkPoint b[2]) { |
| 156 SkDQuad quad; | 169 SkDQuad quad; |
| 157 quad.set(a); | 170 quad.set(a); |
| 158 SkDLine line; | 171 SkDLine line; |
| 159 line.set(b); | 172 line.set(b); |
| 173 fMax = 2; |
| 160 return intersect(quad, line); | 174 return intersect(quad, line); |
| 161 } | 175 } |
| 162 | 176 |
| 163 int quadQuad(const SkPoint a[3], const SkPoint b[3]) { | 177 int quadQuad(const SkPoint a[3], const SkPoint b[3]) { |
| 164 SkDQuad aQuad; | 178 SkDQuad aQuad; |
| 165 aQuad.set(a); | 179 aQuad.set(a); |
| 166 SkDQuad bQuad; | 180 SkDQuad bQuad; |
| 167 bQuad.set(b); | 181 bQuad.set(b); |
| 182 fMax = 4; |
| 168 return intersect(aQuad, bQuad); | 183 return intersect(aQuad, bQuad); |
| 169 } | 184 } |
| 170 | 185 |
| 171 int quadRay(const SkPoint pts[3], const SkDLine& line); | 186 int quadRay(const SkPoint pts[3], const SkDLine& line); |
| 172 void removeOne(int index); | 187 void removeOne(int index); |
| 173 | 188 |
| 174 // leaves flip, swap alone | 189 // leaves flip, swap, max alone |
| 175 void reset() { | 190 void reset() { |
| 176 fAllowNear = true; | 191 fAllowNear = true; |
| 177 fUsed = 0; | 192 fUsed = 0; |
| 178 } | 193 } |
| 179 | 194 |
| 195 void setMax(int max) { |
| 196 fMax = max; |
| 197 } |
| 198 |
| 180 void swap() { | 199 void swap() { |
| 181 fSwap ^= true; | 200 fSwap ^= true; |
| 182 } | 201 } |
| 183 | 202 |
| 184 void swapPts(); | 203 void swapPts(); |
| 185 | 204 |
| 186 bool swapped() const { | 205 bool swapped() const { |
| 187 return fSwap; | 206 return fSwap; |
| 188 } | 207 } |
| 189 | 208 |
| 190 int used() const { | 209 int used() const { |
| 191 return fUsed; | 210 return fUsed; |
| 192 } | 211 } |
| 193 | 212 |
| 194 void downDepth() { | 213 void downDepth() { |
| 195 SkASSERT(--fDepth >= 0); | 214 SkASSERT(--fDepth >= 0); |
| 196 } | 215 } |
| 197 | 216 |
| 198 void upDepth() { | 217 void upDepth() { |
| 199 SkASSERT(++fDepth < 16); | 218 SkASSERT(++fDepth < 16); |
| 200 } | 219 } |
| 201 | 220 |
| 202 static double Axial(const SkDQuad& , const SkDPoint& , bool vertical); | 221 static double Axial(const SkDQuad& , const SkDPoint& , bool vertical); |
| 222 void cleanUpCoincidence(); |
| 203 int coincidentUsed() const; | 223 int coincidentUsed() const; |
| 204 int cubicRay(const SkPoint pts[4], const SkDLine& line); | 224 int cubicRay(const SkPoint pts[4], const SkDLine& line); |
| 205 void flip(); | 225 void flip(); |
| 206 int horizontal(const SkDLine&, double y); | 226 int horizontal(const SkDLine&, double y); |
| 207 int horizontal(const SkDLine&, double left, double right, double y, bool fli
pped); | 227 int horizontal(const SkDLine&, double left, double right, double y, bool fli
pped); |
| 208 int horizontal(const SkDQuad&, double left, double right, double y, bool fli
pped); | 228 int horizontal(const SkDQuad&, double left, double right, double y, bool fli
pped); |
| 209 int horizontal(const SkDQuad&, double left, double right, double y, double t
Range[2]); | 229 int horizontal(const SkDQuad&, double left, double right, double y, double t
Range[2]); |
| 210 int horizontal(const SkDCubic&, double y, double tRange[3]); | 230 int horizontal(const SkDCubic&, double y, double tRange[3]); |
| 211 int horizontal(const SkDCubic&, double left, double right, double y, bool fl
ipped); | 231 int horizontal(const SkDCubic&, double left, double right, double y, bool fl
ipped); |
| 212 int horizontal(const SkDCubic&, double left, double right, double y, double
tRange[3]); | 232 int horizontal(const SkDCubic&, double left, double right, double y, double
tRange[3]); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 239 | 259 |
| 240 int depth() const { | 260 int depth() const { |
| 241 #ifdef SK_DEBUG | 261 #ifdef SK_DEBUG |
| 242 return fDepth; | 262 return fDepth; |
| 243 #else | 263 #else |
| 244 return 0; | 264 return 0; |
| 245 #endif | 265 #endif |
| 246 } | 266 } |
| 247 | 267 |
| 248 private: | 268 private: |
| 249 int computePoints(const SkDLine& line, int used); | 269 bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2); |
| 270 bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic
2); |
| 271 void cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2
, const SkDRect& ); |
| 272 void cleanUpParallelLines(bool parallel); |
| 273 void computePoints(const SkDLine& line, int used); |
| 250 // used by addCoincident to remove ordinary intersections in range | 274 // used by addCoincident to remove ordinary intersections in range |
| 251 // void remove(double one, double two, const SkDPoint& startPt, const SkDPoin
t& endPt); | 275 // void remove(double one, double two, const SkDPoint& startPt, const SkDPoin
t& endPt); |
| 252 | 276 |
| 253 SkDPoint fPt[9]; // FIXME: since scans store points as SkPoint, this should
also | 277 SkDPoint fPt[9]; // FIXME: since scans store points as SkPoint, this should
also |
| 254 double fT[2][9]; | 278 double fT[2][9]; |
| 255 uint16_t fIsCoincident[2]; // bit set for each curve's coincident T | 279 uint16_t fIsCoincident[2]; // bit set for each curve's coincident T |
| 256 uint16_t fIsNear; // bit set for each T if 2nd curve's point is near but no
t equal to 1st | 280 uint16_t fIsNear; // bit set for each T if 2nd curve's point is near but no
t equal to 1st |
| 257 unsigned char fUsed; | 281 unsigned char fUsed; |
| 282 unsigned char fMax; |
| 258 bool fAllowNear; | 283 bool fAllowNear; |
| 259 bool fSwap; | 284 bool fSwap; |
| 260 #ifdef SK_DEBUG | 285 #ifdef SK_DEBUG |
| 261 int fDepth; | 286 int fDepth; |
| 262 #endif | 287 #endif |
| 263 }; | 288 }; |
| 264 | 289 |
| 265 extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& ); | 290 extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& ); |
| 266 extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, Sk
Scalar bottom, | 291 extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, Sk
Scalar bottom, |
| 267 SkScalar x, bool flipped); | 292 SkScalar x, bool flipped); |
| 268 | 293 |
| 269 #endif | 294 #endif |
| OLD | NEW |