| 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* fContours[2]; | 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 #if DEBUG_DUMP | 28 #ifdef SK_DEBUG |
| 29 fID = ++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 |
| 39 void addCoincident(int index, SkOpContour* other, int otherIndex, | 39 void addCoincident(int index, SkOpContour* other, int otherIndex, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 56 | 56 |
| 57 int addLine(const SkPoint pts[2]) { | 57 int addLine(const SkPoint pts[2]) { |
| 58 fSegments.push_back().addLine(pts, fOperand, fXor); | 58 fSegments.push_back().addLine(pts, fOperand, fXor); |
| 59 return fSegments.count(); | 59 return fSegments.count(); |
| 60 } | 60 } |
| 61 | 61 |
| 62 void addOtherT(int segIndex, int tIndex, double otherT, int otherIndex) { | 62 void addOtherT(int segIndex, int tIndex, double otherT, int otherIndex) { |
| 63 fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex); | 63 fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex); |
| 64 } | 64 } |
| 65 | 65 |
| 66 void addPartialCoincident(int index, SkOpContour* other, int otherIndex, |
| 67 const SkIntersections& ts, int ptIndex, bool swap); |
| 68 |
| 66 int addQuad(const SkPoint pts[3]) { | 69 int addQuad(const SkPoint pts[3]) { |
| 67 fSegments.push_back().addQuad(pts, fOperand, fXor); | 70 fSegments.push_back().addQuad(pts, fOperand, fXor); |
| 68 fContainsCurves = true; | 71 fContainsCurves = true; |
| 69 return fSegments.count(); | 72 return fSegments.count(); |
| 70 } | 73 } |
| 71 | 74 |
| 72 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 bool isNear) { |
| 73 setContainsIntercepts(); | 77 setContainsIntercepts(); |
| 74 return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT)
; | 78 return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT,
isNear); |
| 75 } | 79 } |
| 76 | 80 |
| 77 int addSelfT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint
& pt, double newT) { | 81 int addSelfT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint
& pt, double newT) { |
| 78 setContainsIntercepts(); | 82 setContainsIntercepts(); |
| 79 return fSegments[segIndex].addSelfT(&other->fSegments[otherIndex], pt, n
ewT); | 83 return fSegments[segIndex].addSelfT(&other->fSegments[otherIndex], pt, n
ewT); |
| 80 } | 84 } |
| 81 | 85 |
| 82 int addUnsortableT(int segIndex, SkOpContour* other, int otherIndex, bool st
art, | |
| 83 const SkPoint& pt, double newT) { | |
| 84 return fSegments[segIndex].addUnsortableT(&other->fSegments[otherIndex],
start, pt, newT); | |
| 85 } | |
| 86 | |
| 87 const SkPathOpsBounds& bounds() const { | 86 const SkPathOpsBounds& bounds() const { |
| 88 return fBounds; | 87 return fBounds; |
| 89 } | 88 } |
| 90 | 89 |
| 91 void calcCoincidentWinding(); | 90 void calcCoincidentWinding(); |
| 91 void calcPartialCoincidentWinding(); |
| 92 | 92 |
| 93 void checkEnds() { | 93 void checkEnds() { |
| 94 if (!fContainsCurves) { | 94 if (!fContainsCurves) { |
| 95 return; | 95 return; |
| 96 } | 96 } |
| 97 int segmentCount = fSegments.count(); | 97 int segmentCount = fSegments.count(); |
| 98 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { | 98 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 99 SkOpSegment* segment = &fSegments[sIndex]; | 99 SkOpSegment* segment = &fSegments[sIndex]; |
| 100 if (segment->verb() == SkPath::kLine_Verb) { | 100 if (segment->verb() == SkPath::kLine_Verb) { |
| 101 continue; | 101 continue; |
| 102 } | 102 } |
| 103 fSegments[sIndex].checkEnds(); | 103 segment->checkEnds(); |
| 104 } | 104 } |
| 105 } | 105 } |
| 106 | 106 |
| 107 // if same point has different T values, choose a common T |
| 108 void checkTiny() { |
| 109 int segmentCount = fSegments.count(); |
| 110 if (segmentCount <= 2) { |
| 111 return; |
| 112 } |
| 113 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 114 fSegments[sIndex].checkTiny(); |
| 115 } |
| 116 } |
| 117 |
| 107 void complete() { | 118 void complete() { |
| 108 setBounds(); | 119 setBounds(); |
| 109 fContainsIntercepts = false; | 120 fContainsIntercepts = false; |
| 110 } | 121 } |
| 111 | 122 |
| 112 bool containsCubics() const { | 123 bool containsCubics() const { |
| 113 return fContainsCubics; | 124 return fContainsCubics; |
| 114 } | 125 } |
| 115 | 126 |
| 116 bool crosses(const SkOpContour* crosser) const { | 127 bool crosses(const SkOpContour* crosser) const { |
| 117 for (int index = 0; index < fCrosses.count(); ++index) { | 128 for (int index = 0; index < fCrosses.count(); ++index) { |
| 118 if (fCrosses[index] == crosser) { | 129 if (fCrosses[index] == crosser) { |
| 119 return true; | 130 return true; |
| 120 } | 131 } |
| 121 } | 132 } |
| 122 return false; | 133 return false; |
| 123 } | 134 } |
| 124 | 135 |
| 125 bool done() const { | 136 bool done() const { |
| 126 return fDone; | 137 return fDone; |
| 127 } | 138 } |
| 128 | 139 |
| 129 const SkPoint& end() const { | 140 const SkPoint& end() const { |
| 130 const SkOpSegment& segment = fSegments.back(); | 141 const SkOpSegment& segment = fSegments.back(); |
| 131 return segment.pts()[SkPathOpsVerbToPoints(segment.verb())]; | 142 return segment.pts()[SkPathOpsVerbToPoints(segment.verb())]; |
| 132 } | 143 } |
| 133 | 144 |
| 134 void findTooCloseToCall() { | |
| 135 int segmentCount = fSegments.count(); | |
| 136 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { | |
| 137 fSegments[sIndex].findTooCloseToCall(); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 void fixOtherTIndex() { | 145 void fixOtherTIndex() { |
| 142 int segmentCount = fSegments.count(); | 146 int segmentCount = fSegments.count(); |
| 143 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { | 147 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { |
| 144 fSegments[sIndex].fixOtherTIndex(); | 148 fSegments[sIndex].fixOtherTIndex(); |
| 145 } | 149 } |
| 146 } | 150 } |
| 147 | 151 |
| 148 SkOpSegment* nonVerticalSegment(int* start, int* end); | 152 SkOpSegment* nonVerticalSegment(int* start, int* end); |
| 149 | 153 |
| 150 bool operand() const { | 154 bool operand() const { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 } | 229 } |
| 226 } | 230 } |
| 227 #endif | 231 #endif |
| 228 | 232 |
| 229 #if DEBUG_SHOW_WINDING | 233 #if DEBUG_SHOW_WINDING |
| 230 int debugShowWindingValues(int totalSegments, int ofInterest); | 234 int debugShowWindingValues(int totalSegments, int ofInterest); |
| 231 static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& conto
urList); | 235 static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& conto
urList); |
| 232 #endif | 236 #endif |
| 233 | 237 |
| 234 private: | 238 private: |
| 239 void calcCommonCoincidentWinding(const SkCoincidence& coincidence); |
| 235 void setBounds(); | 240 void setBounds(); |
| 236 | 241 |
| 237 SkTArray<SkOpSegment> fSegments; | 242 SkTArray<SkOpSegment> fSegments; |
| 238 SkTArray<SkOpSegment*, true> fSortedSegments; | 243 SkTArray<SkOpSegment*, true> fSortedSegments; |
| 239 int fFirstSorted; | 244 int fFirstSorted; |
| 240 SkTArray<SkCoincidence, true> fCoincidences; | 245 SkTArray<SkCoincidence, true> fCoincidences; |
| 246 SkTArray<SkCoincidence, true> fPartialCoincidences; |
| 241 SkTArray<const SkOpContour*, true> fCrosses; | 247 SkTArray<const SkOpContour*, true> fCrosses; |
| 242 SkPathOpsBounds fBounds; | 248 SkPathOpsBounds fBounds; |
| 243 bool fContainsIntercepts; // FIXME: is this used by anybody? | 249 bool fContainsIntercepts; // FIXME: is this used by anybody? |
| 244 bool fContainsCubics; | 250 bool fContainsCubics; |
| 245 bool fContainsCurves; | 251 bool fContainsCurves; |
| 246 bool fDone; | 252 bool fDone; |
| 247 bool fOperand; // true for the second argument to a binary operator | 253 bool fOperand; // true for the second argument to a binary operator |
| 248 bool fXor; | 254 bool fXor; |
| 249 bool fOppXor; | 255 bool fOppXor; |
| 250 #if DEBUG_DUMP | 256 #ifdef SK_DEBUG |
| 251 int fID; | 257 int fID; |
| 252 #endif | 258 #endif |
| 253 }; | 259 }; |
| 254 | 260 |
| 255 #endif | 261 #endif |
| OLD | NEW |