| 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 , fFlatMeasure(false) | |
| 20 #ifdef SK_DEBUG | 19 #ifdef SK_DEBUG |
| 21 , fDepth(0) | 20 , fDepth(0) |
| 22 #endif | 21 #endif |
| 23 { | 22 { |
| 24 sk_bzero(fPt, sizeof(fPt)); | 23 sk_bzero(fPt, sizeof(fPt)); |
| 25 sk_bzero(fPt2, sizeof(fPt2)); | 24 sk_bzero(fPt2, sizeof(fPt2)); |
| 26 sk_bzero(fT, sizeof(fT)); | 25 sk_bzero(fT, sizeof(fT)); |
| 27 sk_bzero(fIsCoincident, sizeof(fIsCoincident)); | |
| 28 sk_bzero(fNearlySame, sizeof(fNearlySame)); | 26 sk_bzero(fNearlySame, sizeof(fNearlySame)); |
| 29 reset(); | 27 reset(); |
| 30 fMax = 0; // require that the caller set the max | 28 fMax = 0; // require that the caller set the max |
| 31 } | 29 } |
| 32 | 30 |
| 33 class TArray { | 31 class TArray { |
| 34 public: | 32 public: |
| 35 explicit TArray(const double ts[9]) : fTArray(ts) {} | 33 explicit TArray(const double ts[10]) : fTArray(ts) {} |
| 36 double operator[](int n) const { | 34 double operator[](int n) const { |
| 37 return fTArray[n]; | 35 return fTArray[n]; |
| 38 } | 36 } |
| 39 const double* fTArray; | 37 const double* fTArray; |
| 40 }; | 38 }; |
| 41 TArray operator[](int n) const { return TArray(fT[n]); } | 39 TArray operator[](int n) const { return TArray(fT[n]); } |
| 42 | 40 |
| 43 void allowFlatMeasure(bool flatAllowed) { | |
| 44 fFlatMeasure = flatAllowed; | |
| 45 } | |
| 46 | |
| 47 void allowNear(bool nearAllowed) { | 41 void allowNear(bool nearAllowed) { |
| 48 fAllowNear = nearAllowed; | 42 fAllowNear = nearAllowed; |
| 49 } | 43 } |
| 50 | 44 |
| 51 int cubic(const SkPoint a[4]) { | 45 void clearCoincidence(int index) { |
| 52 SkDCubic cubic; | 46 SkASSERT(index >= 0); |
| 53 cubic.set(a); | 47 int bit = 1 << index; |
| 54 fMax = 1; // self intersect | 48 fIsCoincident[0] &= ~bit; |
| 55 return intersect(cubic); | 49 fIsCoincident[1] &= ~bit; |
| 56 } | |
| 57 | |
| 58 int cubicCubic(const SkPoint a[4], const SkPoint b[4]) { | |
| 59 SkDCubic aCubic; | |
| 60 aCubic.set(a); | |
| 61 SkDCubic bCubic; | |
| 62 bCubic.set(b); | |
| 63 fMax = 9; | |
| 64 return intersect(aCubic, bCubic); | |
| 65 } | 50 } |
| 66 | 51 |
| 67 int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkSca
lar y, | 52 int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkSca
lar y, |
| 68 bool flipped) { | 53 bool flipped) { |
| 69 SkDCubic cubic; | 54 SkDCubic cubic; |
| 70 cubic.set(a); | 55 cubic.set(a); |
| 71 fMax = 3; | 56 fMax = 3; |
| 72 return horizontal(cubic, left, right, y, flipped); | 57 return horizontal(cubic, left, right, y, flipped); |
| 73 } | 58 } |
| 74 | 59 |
| 75 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScala
r x, bool flipped) { | 60 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScala
r x, bool flipped) { |
| 76 SkDCubic cubic; | 61 SkDCubic cubic; |
| 77 cubic.set(a); | 62 cubic.set(a); |
| 78 fMax = 3; | 63 fMax = 3; |
| 79 return vertical(cubic, top, bottom, x, flipped); | 64 return vertical(cubic, top, bottom, x, flipped); |
| 80 } | 65 } |
| 81 | 66 |
| 82 int cubicLine(const SkPoint a[4], const SkPoint b[2]) { | 67 int cubicLine(const SkPoint a[4], const SkPoint b[2]) { |
| 83 SkDCubic cubic; | 68 SkDCubic cubic; |
| 84 cubic.set(a); | 69 cubic.set(a); |
| 85 SkDLine line; | 70 SkDLine line; |
| 86 line.set(b); | 71 line.set(b); |
| 87 fMax = 3; | 72 fMax = 3; |
| 88 return intersect(cubic, line); | 73 return intersect(cubic, line); |
| 89 } | 74 } |
| 90 | 75 |
| 91 int cubicQuad(const SkPoint a[4], const SkPoint b[3]) { | |
| 92 SkDCubic cubic; | |
| 93 cubic.set(a); | |
| 94 SkDQuad quad; | |
| 95 quad.set(b); | |
| 96 fMax = 7; | |
| 97 return intersect(cubic, quad); | |
| 98 } | |
| 99 | |
| 100 bool flatMeasure() const { | |
| 101 return fFlatMeasure; | |
| 102 } | |
| 103 | |
| 104 bool hasT(double t) const { | 76 bool hasT(double t) const { |
| 105 SkASSERT(t == 0 || t == 1); | 77 SkASSERT(t == 0 || t == 1); |
| 106 return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1); | 78 return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1); |
| 107 } | 79 } |
| 108 | 80 |
| 109 int insertSwap(double one, double two, const SkDPoint& pt) { | 81 int insertSwap(double one, double two, const SkDPoint& pt) { |
| 110 if (fSwap) { | 82 if (fSwap) { |
| 111 return insert(two, one, pt); | 83 return insert(two, one, pt); |
| 112 } else { | 84 } else { |
| 113 return insert(one, two, pt); | 85 return insert(one, two, pt); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 | 143 |
| 172 int quadLine(const SkPoint a[3], const SkPoint b[2]) { | 144 int quadLine(const SkPoint a[3], const SkPoint b[2]) { |
| 173 SkDQuad quad; | 145 SkDQuad quad; |
| 174 quad.set(a); | 146 quad.set(a); |
| 175 SkDLine line; | 147 SkDLine line; |
| 176 line.set(b); | 148 line.set(b); |
| 177 fMax = 3; // 2; permit small coincident segment + non-coincident inters
ection | 149 fMax = 3; // 2; permit small coincident segment + non-coincident inters
ection |
| 178 return intersect(quad, line); | 150 return intersect(quad, line); |
| 179 } | 151 } |
| 180 | 152 |
| 181 int quadQuad(const SkPoint a[3], const SkPoint b[3]) { | |
| 182 SkDQuad aQuad; | |
| 183 aQuad.set(a); | |
| 184 SkDQuad bQuad; | |
| 185 bQuad.set(b); | |
| 186 fMax = 4; | |
| 187 return intersect(aQuad, bQuad); | |
| 188 } | |
| 189 | |
| 190 // leaves swap, max alone | 153 // leaves swap, max alone |
| 191 void reset() { | 154 void reset() { |
| 192 fAllowNear = true; | 155 fAllowNear = true; |
| 193 fUsed = 0; | 156 fUsed = 0; |
| 157 sk_bzero(fIsCoincident, sizeof(fIsCoincident)); |
| 194 } | 158 } |
| 195 | 159 |
| 196 void set(bool swap, int tIndex, double t) { | 160 void set(bool swap, int tIndex, double t) { |
| 197 fT[(int) swap][tIndex] = t; | 161 fT[(int) swap][tIndex] = t; |
| 198 } | 162 } |
| 199 | 163 |
| 200 void setMax(int max) { | 164 void setMax(int max) { |
| 201 fMax = max; | 165 fMax = max; |
| 202 } | 166 } |
| 203 | 167 |
| 204 void swap() { | 168 void swap() { |
| 205 fSwap ^= true; | 169 fSwap ^= true; |
| 206 } | 170 } |
| 207 | 171 |
| 208 void swapPts(); | |
| 209 | |
| 210 bool swapped() const { | 172 bool swapped() const { |
| 211 return fSwap; | 173 return fSwap; |
| 212 } | 174 } |
| 213 | 175 |
| 214 int used() const { | 176 int used() const { |
| 215 return fUsed; | 177 return fUsed; |
| 216 } | 178 } |
| 217 | 179 |
| 218 void downDepth() { | 180 void downDepth() { |
| 219 SkASSERT(--fDepth >= 0); | 181 SkASSERT(--fDepth >= 0); |
| 220 } | 182 } |
| 221 | 183 |
| 184 bool unBumpT(int index) { |
| 185 SkASSERT(fUsed == 1); |
| 186 fT[0][index] = fT[0][index] * (1 + BUMP_EPSILON * 2) - BUMP_EPSILON; |
| 187 if (!between(0, fT[0][index], 1)) { |
| 188 fUsed = 0; |
| 189 return false; |
| 190 } |
| 191 return true; |
| 192 } |
| 193 |
| 222 void upDepth() { | 194 void upDepth() { |
| 223 SkASSERT(++fDepth < 16); | 195 SkASSERT(++fDepth < 16); |
| 224 } | 196 } |
| 225 | 197 |
| 226 void alignQuadPts(const SkPoint a[3], const SkPoint b[3]); | 198 void alignQuadPts(const SkPoint a[3], const SkPoint b[3]); |
| 227 void append(const SkIntersections& ); | |
| 228 int cleanUpCoincidence(); | 199 int cleanUpCoincidence(); |
| 200 int closestTo(double rangeStart, double rangeEnd, const SkDPoint& testPt, do
uble* dist) const; |
| 229 int coincidentUsed() const; | 201 int coincidentUsed() const; |
| 230 void cubicInsert(double one, double two, const SkDPoint& pt, const SkDCubic&
c1, | 202 void cubicInsert(double one, double two, const SkDPoint& pt, const SkDCubic&
c1, |
| 231 const SkDCubic& c2); | 203 const SkDCubic& c2); |
| 232 int cubicRay(const SkPoint pts[4], const SkDLine& line); | |
| 233 void flip(); | 204 void flip(); |
| 234 int horizontal(const SkDLine&, double y); | |
| 235 int horizontal(const SkDLine&, double left, double right, double y, bool fli
pped); | 205 int horizontal(const SkDLine&, double left, double right, double y, bool fli
pped); |
| 236 int horizontal(const SkDQuad&, double left, double right, double y, bool fli
pped); | 206 int horizontal(const SkDQuad&, double left, double right, double y, bool fli
pped); |
| 237 int horizontal(const SkDQuad&, double left, double right, double y, double t
Range[2]); | 207 int horizontal(const SkDQuad&, double left, double right, double y, double t
Range[2]); |
| 238 int horizontal(const SkDCubic&, double y, double tRange[3]); | 208 int horizontal(const SkDCubic&, double y, double tRange[3]); |
| 239 int horizontal(const SkDCubic&, double left, double right, double y, bool fl
ipped); | 209 int horizontal(const SkDCubic&, double left, double right, double y, bool fl
ipped); |
| 240 int horizontal(const SkDCubic&, double left, double right, double y, double
tRange[3]); | 210 int horizontal(const SkDCubic&, double left, double right, double y, double
tRange[3]); |
| 241 // FIXME : does not respect swap | 211 // FIXME : does not respect swap |
| 242 int insert(double one, double two, const SkDPoint& pt); | 212 int insert(double one, double two, const SkDPoint& pt); |
| 243 void insertNear(double one, double two, const SkDPoint& pt1, const SkDPoint&
pt2); | 213 void insertNear(double one, double two, const SkDPoint& pt1, const SkDPoint&
pt2); |
| 244 // start if index == 0 : end if index == 1 | 214 // start if index == 0 : end if index == 1 |
| 245 void insertCoincident(double one, double two, const SkDPoint& pt); | 215 int insertCoincident(double one, double two, const SkDPoint& pt); |
| 246 int intersect(const SkDLine&, const SkDLine&); | 216 int intersect(const SkDLine&, const SkDLine&); |
| 247 int intersect(const SkDQuad&, const SkDLine&); | 217 int intersect(const SkDQuad&, const SkDLine&); |
| 248 int intersect(const SkDQuad&, const SkDQuad&); | 218 int intersect(const SkDQuad&, const SkDQuad&); |
| 249 int intersect(const SkDCubic&); // return true if cubic self-intersects | |
| 250 int intersect(const SkDCubic&, const SkDLine&); | 219 int intersect(const SkDCubic&, const SkDLine&); |
| 251 int intersect(const SkDCubic&, const SkDQuad&); | |
| 252 int intersect(const SkDCubic&, const SkDCubic&); | 220 int intersect(const SkDCubic&, const SkDCubic&); |
| 253 int intersectRay(const SkDLine&, const SkDLine&); | 221 int intersectRay(const SkDLine&, const SkDLine&); |
| 254 int intersectRay(const SkDQuad&, const SkDLine&); | 222 int intersectRay(const SkDQuad&, const SkDLine&); |
| 255 int intersectRay(const SkDCubic&, const SkDLine&); | 223 int intersectRay(const SkDCubic&, const SkDLine&); |
| 256 static SkDPoint Line(const SkDLine&, const SkDLine&); | 224 void merge(const SkIntersections& , int , const SkIntersections& , int ); |
| 257 int lineRay(const SkPoint pts[2], const SkDLine& line); | 225 int mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin)
const; |
| 258 void offset(int base, double start, double end); | |
| 259 void quickRemoveOne(int index, int replace); | 226 void quickRemoveOne(int index, int replace); |
| 260 int quadRay(const SkPoint pts[3], const SkDLine& line); | |
| 261 void removeOne(int index); | 227 void removeOne(int index); |
| 262 static bool Test(const SkDLine& , const SkDLine&); | 228 void setCoincident(int index); |
| 263 int vertical(const SkDLine&, double x); | |
| 264 int vertical(const SkDLine&, double top, double bottom, double x, bool flipp
ed); | 229 int vertical(const SkDLine&, double top, double bottom, double x, bool flipp
ed); |
| 265 int vertical(const SkDQuad&, double top, double bottom, double x, bool flipp
ed); | 230 int vertical(const SkDQuad&, double top, double bottom, double x, bool flipp
ed); |
| 266 int vertical(const SkDCubic&, double top, double bottom, double x, bool flip
ped); | 231 int vertical(const SkDCubic&, double top, double bottom, double x, bool flip
ped); |
| 267 int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScala
r x, bool flipped); | 232 int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScala
r x, bool flipped); |
| 268 int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped); | 233 int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped); |
| 269 int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped); | 234 int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar
x, bool flipped); |
| 270 | 235 |
| 271 int depth() const { | 236 int depth() const { |
| 272 #ifdef SK_DEBUG | 237 #ifdef SK_DEBUG |
| 273 return fDepth; | 238 return fDepth; |
| 274 #else | 239 #else |
| 275 return 0; | 240 return 0; |
| 276 #endif | 241 #endif |
| 277 } | 242 } |
| 278 | 243 |
| 244 void dump() const; // implemented for testing only |
| 245 |
| 279 private: | 246 private: |
| 280 bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2); | 247 bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2); |
| 281 bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic
2); | 248 bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic
2); |
| 282 void cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2
, const SkDRect& ); | 249 void cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2
, const SkDRect& ); |
| 283 void cleanUpParallelLines(bool parallel); | 250 void cleanUpParallelLines(bool parallel); |
| 284 void computePoints(const SkDLine& line, int used); | 251 void computePoints(const SkDLine& line, int used); |
| 285 | 252 |
| 286 SkDPoint fPt[9]; // FIXME: since scans store points as SkPoint, this should
also | 253 SkDPoint fPt[10]; // FIXME: since scans store points as SkPoint, this shoul
d also |
| 287 SkDPoint fPt2[9]; // used by nearly same to store alternate intersection po
int | 254 SkDPoint fPt2[2]; // used by nearly same to store alternate intersection po
int |
| 288 double fT[2][9]; | 255 double fT[2][10]; |
| 289 uint16_t fIsCoincident[2]; // bit set for each curve's coincident T | 256 uint16_t fIsCoincident[2]; // bit set for each curve's coincident T |
| 290 bool fNearlySame[2]; // true if end points nearly match | 257 bool fNearlySame[2]; // true if end points nearly match |
| 291 unsigned char fUsed; | 258 unsigned char fUsed; |
| 292 unsigned char fMax; | 259 unsigned char fMax; |
| 293 bool fAllowNear; | 260 bool fAllowNear; |
| 294 bool fSwap; | 261 bool fSwap; |
| 295 bool fFlatMeasure; // backwards-compatibility when cubics uses quad interse
ction | |
| 296 #ifdef SK_DEBUG | 262 #ifdef SK_DEBUG |
| 297 int fDepth; | 263 int fDepth; |
| 298 #endif | 264 #endif |
| 299 }; | 265 }; |
| 300 | 266 |
| 301 extern int (SkIntersections::* const CurveRay[])(const SkPoint[], const SkDLine&
); | |
| 302 extern int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar
top, SkScalar bottom, | 267 extern int (SkIntersections::* const CurveVertical[])(const SkPoint[], SkScalar
top, SkScalar bottom, |
| 303 SkScalar x, bool flipped); | 268 SkScalar x, bool flipped); |
| 304 | 269 |
| 305 #endif | 270 #endif |
| OLD | NEW |