| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 SkOpContour_DEFINED | 7 #ifndef SkOpContour_DEFINED |
| 8 #define SkOpContour_DEFINED | 8 #define SkOpContour_DEFINED |
| 9 | 9 |
| 10 #include "SkOpSegment.h" | 10 #include "SkOpSegment.h" |
| 11 #include "SkTArray.h" | 11 #include "SkTArray.h" |
| 12 | 12 |
| 13 class SkIntersections; | 13 class SkIntersections; |
| 14 class SkOpContour; | 14 class SkOpContour; |
| 15 class SkPathWriter; | 15 class SkPathWriter; |
| 16 | 16 |
| 17 struct SkCoincidence { | 17 struct SkCoincidence { |
| 18 SkOpContour* fOther; | 18 SkOpContour* fOther; |
| 19 int fSegments[2]; | 19 int fSegments[2]; |
| 20 double fTs[2][2]; | 20 double fTs[2][2]; |
| 21 SkPoint fPts[2]; | 21 SkPoint fPts[2]; |
| 22 }; | 22 }; |
| 23 | 23 |
| 24 class SkOpContour { | 24 class SkOpContour { |
| 25 public: | 25 public: |
| 26 SkOpContour() { | 26 SkOpContour() { |
| 27 reset(); | 27 reset(); |
| 28 #ifdef SK_DEBUG | 28 #if defined(SK_DEBUG) || !FORCE_RELEASE |
| 29 fID = ++SkPathOpsDebug::gContourID; | 29 fID = ++SkPathOpsDebug::gContourID; |
| 30 #endif | 30 #endif |
| 31 } | 31 } |
| 32 | 32 |
| 33 bool operator<(const SkOpContour& rh) const { | 33 bool operator<(const SkOpContour& rh) const { |
| 34 return fBounds.fTop == rh.fBounds.fTop | 34 return fBounds.fTop == rh.fBounds.fTop |
| 35 ? fBounds.fLeft < rh.fBounds.fLeft | 35 ? fBounds.fLeft < rh.fBounds.fLeft |
| 36 : fBounds.fTop < rh.fBounds.fTop; | 36 : fBounds.fTop < rh.fBounds.fTop; |
| 37 } | 37 } |
| 38 | 38 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 fSegments.push_back().addQuad(pts, fOperand, fXor); | 70 fSegments.push_back().addQuad(pts, fOperand, fXor); |
| 71 fContainsCurves = true; | 71 fContainsCurves = true; |
| 72 return fSegments.count(); | 72 return fSegments.count(); |
| 73 } | 73 } |
| 74 | 74 |
| 75 int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt
, double newT) { | 75 int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt
, double newT) { |
| 76 setContainsIntercepts(); | 76 setContainsIntercepts(); |
| 77 return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT)
; | 77 return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT)
; |
| 78 } | 78 } |
| 79 | 79 |
| 80 int addSelfT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint
& pt, double newT) { | 80 int addSelfT(int segIndex, const SkPoint& pt, double newT) { |
| 81 setContainsIntercepts(); | 81 setContainsIntercepts(); |
| 82 return fSegments[segIndex].addSelfT(&other->fSegments[otherIndex], pt, n
ewT); | 82 return fSegments[segIndex].addSelfT(pt, newT); |
| 83 } | 83 } |
| 84 | 84 |
| 85 const SkPathOpsBounds& bounds() const { | 85 const SkPathOpsBounds& bounds() const { |
| 86 return fBounds; | 86 return fBounds; |
| 87 } | 87 } |
| 88 | 88 |
| 89 bool calcAngles(); |
| 89 void calcCoincidentWinding(); | 90 void calcCoincidentWinding(); |
| 90 void calcPartialCoincidentWinding(); | 91 void calcPartialCoincidentWinding(); |
| 91 | 92 |
| 93 void checkDuplicates() { |
| 94 int segmentCount = fSegments.count(); |
| 95 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 96 SkOpSegment& segment = fSegments[sIndex]; |
| 97 if (segment.count() > 2) { |
| 98 segment.checkDuplicates(); |
| 99 } |
| 100 } |
| 101 } |
| 102 |
| 92 void checkEnds() { | 103 void checkEnds() { |
| 93 if (!fContainsCurves) { | 104 if (!fContainsCurves) { |
| 94 return; | 105 return; |
| 95 } | 106 } |
| 96 int segmentCount = fSegments.count(); | 107 int segmentCount = fSegments.count(); |
| 97 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { | 108 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 98 SkOpSegment* segment = &fSegments[sIndex]; | 109 SkOpSegment* segment = &fSegments[sIndex]; |
| 99 if (segment->verb() == SkPath::kLine_Verb) { | 110 if (segment->verb() == SkPath::kLine_Verb) { |
| 100 continue; | 111 continue; |
| 101 } | 112 } |
| 102 if (segment->done()) { | 113 if (segment->done()) { |
| 103 continue; // likely coincident, nothing to do | 114 continue; // likely coincident, nothing to do |
| 104 } | 115 } |
| 105 segment->checkEnds(); | 116 segment->checkEnds(); |
| 106 } | 117 } |
| 107 } | 118 } |
| 108 | 119 |
| 120 void checkMultiples() { |
| 121 int segmentCount = fSegments.count(); |
| 122 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 123 SkOpSegment& segment = fSegments[sIndex]; |
| 124 if (segment.count() > 2) { |
| 125 segment.checkMultiples(); |
| 126 } |
| 127 } |
| 128 } |
| 129 |
| 130 void checkSmall() { |
| 131 int segmentCount = fSegments.count(); |
| 132 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 133 SkOpSegment& segment = fSegments[sIndex]; |
| 134 if (segment.hasSmall()) { |
| 135 segment.checkSmall(); |
| 136 } |
| 137 } |
| 138 } |
| 139 |
| 109 // if same point has different T values, choose a common T | 140 // if same point has different T values, choose a common T |
| 110 void checkTiny() { | 141 void checkTiny() { |
| 111 int segmentCount = fSegments.count(); | 142 int segmentCount = fSegments.count(); |
| 112 if (segmentCount <= 2) { | 143 if (segmentCount <= 2) { |
| 113 return; | 144 return; |
| 114 } | 145 } |
| 115 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { | 146 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 116 fSegments[sIndex].checkTiny(); | 147 SkOpSegment& segment = fSegments[sIndex]; |
| 148 if (segment.hasTiny()) { |
| 149 segment.checkTiny(); |
| 150 } |
| 117 } | 151 } |
| 118 } | 152 } |
| 119 | 153 |
| 120 void complete() { | 154 void complete() { |
| 121 setBounds(); | 155 setBounds(); |
| 122 fContainsIntercepts = false; | 156 fContainsIntercepts = false; |
| 123 } | 157 } |
| 124 | 158 |
| 125 bool containsCubics() const { | 159 bool containsCubics() const { |
| 126 return fContainsCubics; | 160 return fContainsCubics; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 int segmentCount = fSegments.count(); | 219 int segmentCount = fSegments.count(); |
| 186 for (int test = 0; test < segmentCount; ++test) { | 220 for (int test = 0; test < segmentCount; ++test) { |
| 187 fSegments[test].setOppXor(isOppXor); | 221 fSegments[test].setOppXor(isOppXor); |
| 188 } | 222 } |
| 189 } | 223 } |
| 190 | 224 |
| 191 void setXor(bool isXor) { | 225 void setXor(bool isXor) { |
| 192 fXor = isXor; | 226 fXor = isXor; |
| 193 } | 227 } |
| 194 | 228 |
| 229 void sortAngles(); |
| 195 void sortSegments(); | 230 void sortSegments(); |
| 196 | 231 |
| 197 const SkPoint& start() const { | 232 const SkPoint& start() const { |
| 198 return fSegments.front().pts()[0]; | 233 return fSegments.front().pts()[0]; |
| 199 } | 234 } |
| 200 | 235 |
| 201 void toPath(SkPathWriter* path) const; | 236 void toPath(SkPathWriter* path) const; |
| 202 | 237 |
| 203 void toPartialBackward(SkPathWriter* path) const { | 238 void toPartialBackward(SkPathWriter* path) const { |
| 204 int segmentCount = fSegments.count(); | 239 int segmentCount = fSegments.count(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 235 fSegments[index].debugShowActiveSpans(); | 270 fSegments[index].debugShowActiveSpans(); |
| 236 } | 271 } |
| 237 } | 272 } |
| 238 #endif | 273 #endif |
| 239 | 274 |
| 240 #if DEBUG_SHOW_WINDING | 275 #if DEBUG_SHOW_WINDING |
| 241 int debugShowWindingValues(int totalSegments, int ofInterest); | 276 int debugShowWindingValues(int totalSegments, int ofInterest); |
| 242 static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& conto
urList); | 277 static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& conto
urList); |
| 243 #endif | 278 #endif |
| 244 | 279 |
| 280 // available to test routines only |
| 281 void dump() const; |
| 282 void dumpAngles() const; |
| 283 void dumpPts() const; |
| 284 void dumpSpans() const; |
| 285 |
| 245 private: | 286 private: |
| 246 void calcCommonCoincidentWinding(const SkCoincidence& ); | 287 void calcCommonCoincidentWinding(const SkCoincidence& ); |
| 247 void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial); | 288 void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial); |
| 248 void setBounds(); | 289 void setBounds(); |
| 249 | 290 |
| 250 SkTArray<SkOpSegment> fSegments; | 291 SkTArray<SkOpSegment> fSegments; |
| 251 SkTArray<SkOpSegment*, true> fSortedSegments; | 292 SkTArray<SkOpSegment*, true> fSortedSegments; |
| 252 int fFirstSorted; | 293 int fFirstSorted; |
| 253 SkTArray<SkCoincidence, true> fCoincidences; | 294 SkTArray<SkCoincidence, true> fCoincidences; |
| 254 SkTArray<SkCoincidence, true> fPartialCoincidences; | 295 SkTArray<SkCoincidence, true> fPartialCoincidences; |
| 255 SkTArray<const SkOpContour*, true> fCrosses; | 296 SkTArray<const SkOpContour*, true> fCrosses; |
| 256 SkPathOpsBounds fBounds; | 297 SkPathOpsBounds fBounds; |
| 257 bool fContainsIntercepts; // FIXME: is this used by anybody? | 298 bool fContainsIntercepts; // FIXME: is this used by anybody? |
| 258 bool fContainsCubics; | 299 bool fContainsCubics; |
| 259 bool fContainsCurves; | 300 bool fContainsCurves; |
| 260 bool fDone; | 301 bool fDone; |
| 261 bool fOperand; // true for the second argument to a binary operator | 302 bool fOperand; // true for the second argument to a binary operator |
| 262 bool fXor; | 303 bool fXor; |
| 263 bool fOppXor; | 304 bool fOppXor; |
| 264 #ifdef SK_DEBUG | 305 #if defined(SK_DEBUG) || !FORCE_RELEASE |
| 306 int debugID() const { return fID; } |
| 265 int fID; | 307 int fID; |
| 308 #else |
| 309 int debugID() const { return -1; } |
| 266 #endif | 310 #endif |
| 267 }; | 311 }; |
| 268 | 312 |
| 269 #endif | 313 #endif |
| OLD | NEW |