Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: src/pathops/SkOpContour.cpp

Issue 21359002: path ops work in progress (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: remove space Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/pathops/SkOpContour.h ('k') | src/pathops/SkOpEdgeBuilder.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "SkIntersections.h" 7 #include "SkIntersections.h"
8 #include "SkOpContour.h" 8 #include "SkOpContour.h"
9 #include "SkPathWriter.h" 9 #include "SkPathWriter.h"
10 #include "SkTSort.h" 10 #include "SkTSort.h"
11 11
12 void SkOpContour::addCoincident(int index, SkOpContour* other, int otherIndex, 12 void SkOpContour::addCoincident(int index, SkOpContour* other, int otherIndex,
13 const SkIntersections& ts, bool swap) { 13 const SkIntersections& ts, bool swap) {
14 SkCoincidence& coincidence = fCoincidences.push_back(); 14 SkCoincidence& coincidence = fCoincidences.push_back();
15 coincidence.fContours[0] = this; // FIXME: no need to store 15 coincidence.fOther = other;
16 coincidence.fContours[1] = other;
17 coincidence.fSegments[0] = index; 16 coincidence.fSegments[0] = index;
18 coincidence.fSegments[1] = otherIndex; 17 coincidence.fSegments[1] = otherIndex;
19 coincidence.fTs[swap][0] = ts[0][0]; 18 coincidence.fTs[swap][0] = ts[0][0];
20 coincidence.fTs[swap][1] = ts[0][1]; 19 coincidence.fTs[swap][1] = ts[0][1];
21 coincidence.fTs[!swap][0] = ts[1][0]; 20 coincidence.fTs[!swap][0] = ts[1][0];
22 coincidence.fTs[!swap][1] = ts[1][1]; 21 coincidence.fTs[!swap][1] = ts[1][1];
23 coincidence.fPts[0] = ts.pt(0).asSkPoint(); 22 coincidence.fPts[0] = ts.pt(0).asSkPoint();
24 coincidence.fPts[1] = ts.pt(1).asSkPoint(); 23 coincidence.fPts[1] = ts.pt(1).asSkPoint();
25 } 24 }
26 25
(...skipping 14 matching lines...) Expand all
41 } 40 }
42 return NULL; 41 return NULL;
43 } 42 }
44 43
45 // first pass, add missing T values 44 // first pass, add missing T values
46 // second pass, determine winding values of overlaps 45 // second pass, determine winding values of overlaps
47 void SkOpContour::addCoincidentPoints() { 46 void SkOpContour::addCoincidentPoints() {
48 int count = fCoincidences.count(); 47 int count = fCoincidences.count();
49 for (int index = 0; index < count; ++index) { 48 for (int index = 0; index < count; ++index) {
50 SkCoincidence& coincidence = fCoincidences[index]; 49 SkCoincidence& coincidence = fCoincidences[index];
51 SkASSERT(coincidence.fContours[0] == this);
52 int thisIndex = coincidence.fSegments[0]; 50 int thisIndex = coincidence.fSegments[0];
53 SkOpSegment& thisOne = fSegments[thisIndex]; 51 SkOpSegment& thisOne = fSegments[thisIndex];
54 SkOpContour* otherContour = coincidence.fContours[1]; 52 SkOpContour* otherContour = coincidence.fOther;
55 int otherIndex = coincidence.fSegments[1]; 53 int otherIndex = coincidence.fSegments[1];
56 SkOpSegment& other = otherContour->fSegments[otherIndex]; 54 SkOpSegment& other = otherContour->fSegments[otherIndex];
57 if ((thisOne.done() || other.done()) && thisOne.complete() && other.comp lete()) { 55 if ((thisOne.done() || other.done()) && thisOne.complete() && other.comp lete()) {
58 // OPTIMIZATION: remove from array 56 // OPTIMIZATION: remove from array
59 continue; 57 continue;
60 } 58 }
61 #if DEBUG_CONCIDENT 59 #if DEBUG_CONCIDENT
62 thisOne.debugShowTs(); 60 thisOne.debugShowTs();
63 other.debugShowTs(); 61 other.debugShowTs();
64 #endif 62 #endif
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 other.addTPair(oEndT, &thisOne, endT, true, coincidence.fPts[!oS tartSwapped]); 94 other.addTPair(oEndT, &thisOne, endT, true, coincidence.fPts[!oS tartSwapped]);
97 } 95 }
98 } 96 }
99 #if DEBUG_CONCIDENT 97 #if DEBUG_CONCIDENT
100 thisOne.debugShowTs(); 98 thisOne.debugShowTs();
101 other.debugShowTs(); 99 other.debugShowTs();
102 #endif 100 #endif
103 } 101 }
104 } 102 }
105 103
104 void SkOpContour::addPartialCoincident(int index, SkOpContour* other, int otherI ndex,
105 const SkIntersections& ts, int ptIndex, bool swap) {
106 SkCoincidence& coincidence = fPartialCoincidences.push_back();
107 coincidence.fOther = other;
108 coincidence.fSegments[0] = index;
109 coincidence.fSegments[1] = otherIndex;
110 coincidence.fTs[swap][0] = ts[0][index];
111 coincidence.fTs[swap][1] = ts[0][index + 1];
112 coincidence.fTs[!swap][0] = ts[1][index];
113 coincidence.fTs[!swap][1] = ts[1][index + 1];
114 coincidence.fPts[0] = ts.pt(index).asSkPoint();
115 coincidence.fPts[1] = ts.pt(index + 1).asSkPoint();
116 }
117
106 void SkOpContour::calcCoincidentWinding() { 118 void SkOpContour::calcCoincidentWinding() {
107 int count = fCoincidences.count(); 119 int count = fCoincidences.count();
120 #if DEBUG_CONCIDENT
121 if (count > 0) {
122 SkDebugf("%s count=%d\n", __FUNCTION__, count);
123 }
124 #endif
108 for (int index = 0; index < count; ++index) { 125 for (int index = 0; index < count; ++index) {
109 SkCoincidence& coincidence = fCoincidences[index]; 126 SkCoincidence& coincidence = fCoincidences[index];
110 SkASSERT(coincidence.fContours[0] == this); 127 calcCommonCoincidentWinding(coincidence);
111 int thisIndex = coincidence.fSegments[0];
112 SkOpSegment& thisOne = fSegments[thisIndex];
113 if (thisOne.done()) {
114 continue;
115 }
116 SkOpContour* otherContour = coincidence.fContours[1];
117 int otherIndex = coincidence.fSegments[1];
118 SkOpSegment& other = otherContour->fSegments[otherIndex];
119 if (other.done()) {
120 continue;
121 }
122 double startT = coincidence.fTs[0][0];
123 double endT = coincidence.fTs[0][1];
124 bool cancelers;
125 if ((cancelers = startT > endT)) {
126 SkTSwap<double>(startT, endT);
127 }
128 SkASSERT(!approximately_negative(endT - startT));
129 double oStartT = coincidence.fTs[1][0];
130 double oEndT = coincidence.fTs[1][1];
131 if (oStartT > oEndT) {
132 SkTSwap<double>(oStartT, oEndT);
133 cancelers ^= true;
134 }
135 SkASSERT(!approximately_negative(oEndT - oStartT));
136 if (cancelers) {
137 // make sure startT and endT have t entries
138 if (!thisOne.done() && !other.done()) {
139 thisOne.addTCancel(startT, endT, &other, oStartT, oEndT);
140 }
141 } else {
142 if (!thisOne.done() && !other.done()) {
143 thisOne.addTCoincident(startT, endT, &other, oStartT, oEndT);
144 }
145 }
146 #if DEBUG_CONCIDENT
147 thisOne.debugShowTs();
148 other.debugShowTs();
149 #endif
150 } 128 }
151 } 129 }
152 130
131 void SkOpContour::calcPartialCoincidentWinding() {
132 int count = fPartialCoincidences.count();
133 #if DEBUG_CONCIDENT
134 if (count > 0) {
135 SkDebugf("%s count=%d\n", __FUNCTION__, count);
136 }
137 #endif
138 for (int index = 0; index < count; ++index) {
139 SkCoincidence& coincidence = fPartialCoincidences[index];
140 calcCommonCoincidentWinding(coincidence);
141 }
142 }
143
144 void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
145 int thisIndex = coincidence.fSegments[0];
146 SkOpSegment& thisOne = fSegments[thisIndex];
147 if (thisOne.done()) {
148 return;
149 }
150 SkOpContour* otherContour = coincidence.fOther;
151 int otherIndex = coincidence.fSegments[1];
152 SkOpSegment& other = otherContour->fSegments[otherIndex];
153 if (other.done()) {
154 return;
155 }
156 double startT = coincidence.fTs[0][0];
157 double endT = coincidence.fTs[0][1];
158 const SkPoint* startPt = &coincidence.fPts[0];
159 const SkPoint* endPt = &coincidence.fPts[1];
160 bool cancelers;
161 if ((cancelers = startT > endT)) {
162 SkTSwap<double>(startT, endT);
163 SkTSwap<const SkPoint*>(startPt, endPt);
164 }
165 SkASSERT(!approximately_negative(endT - startT));
166 double oStartT = coincidence.fTs[1][0];
167 double oEndT = coincidence.fTs[1][1];
168 if (oStartT > oEndT) {
169 SkTSwap<double>(oStartT, oEndT);
170 cancelers ^= true;
171 }
172 SkASSERT(!approximately_negative(oEndT - oStartT));
173 if (cancelers) {
174 thisOne.addTCancel(*startPt, *endPt, &other);
175 } else {
176 thisOne.addTCoincident(*startPt, *endPt, &other);
177 }
178 #if DEBUG_CONCIDENT
179 thisOne.debugShowTs();
180 other.debugShowTs();
181 #endif
182 }
183
153 void SkOpContour::sortSegments() { 184 void SkOpContour::sortSegments() {
154 int segmentCount = fSegments.count(); 185 int segmentCount = fSegments.count();
155 fSortedSegments.push_back_n(segmentCount); 186 fSortedSegments.push_back_n(segmentCount);
156 for (int test = 0; test < segmentCount; ++test) { 187 for (int test = 0; test < segmentCount; ++test) {
157 fSortedSegments[test] = &fSegments[test]; 188 fSortedSegments[test] = &fSegments[test];
158 } 189 }
159 SkTQSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1); 190 SkTQSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1);
160 fFirstSorted = 0; 191 fFirstSorted = 0;
161 } 192 }
162 193
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 int SkOpContour::debugShowWindingValues(int totalSegments, int ofInterest) { 253 int SkOpContour::debugShowWindingValues(int totalSegments, int ofInterest) {
223 int count = fSegments.count(); 254 int count = fSegments.count();
224 int sum = 0; 255 int sum = 0;
225 for (int index = 0; index < count; ++index) { 256 for (int index = 0; index < count; ++index) {
226 sum += fSegments[index].debugShowWindingValues(totalSegments, ofInterest ); 257 sum += fSegments[index].debugShowWindingValues(totalSegments, ofInterest );
227 } 258 }
228 // SkDebugf("%s sum=%d\n", __FUNCTION__, sum); 259 // SkDebugf("%s sum=%d\n", __FUNCTION__, sum);
229 return sum; 260 return sum;
230 } 261 }
231 262
232 static void SkOpContour::debugShowWindingValues(const SkTArray<SkOpContour*, tru e>& contourList) { 263 void SkOpContour::debugShowWindingValues(const SkTArray<SkOpContour*, true>& con tourList) {
233 // int ofInterest = 1 << 1 | 1 << 5 | 1 << 9 | 1 << 13; 264 // int ofInterest = 1 << 1 | 1 << 5 | 1 << 9 | 1 << 13;
234 // int ofInterest = 1 << 4 | 1 << 8 | 1 << 12 | 1 << 16; 265 // int ofInterest = 1 << 4 | 1 << 8 | 1 << 12 | 1 << 16;
235 int ofInterest = 1 << 5 | 1 << 8; 266 int ofInterest = 1 << 5 | 1 << 8;
236 int total = 0; 267 int total = 0;
237 int index; 268 int index;
238 for (index = 0; index < contourList.count(); ++index) { 269 for (index = 0; index < contourList.count(); ++index) {
239 total += contourList[index]->segments().count(); 270 total += contourList[index]->segments().count();
240 } 271 }
241 int sum = 0; 272 int sum = 0;
242 for (index = 0; index < contourList.count(); ++index) { 273 for (index = 0; index < contourList.count(); ++index) {
243 sum += contourList[index]->debugShowWindingValues(total, ofInterest); 274 sum += contourList[index]->debugShowWindingValues(total, ofInterest);
244 } 275 }
245 // SkDebugf("%s total=%d\n", __FUNCTION__, sum); 276 // SkDebugf("%s total=%d\n", __FUNCTION__, sum);
246 } 277 }
247 #endif 278 #endif
248 279
249 void SkOpContour::setBounds() { 280 void SkOpContour::setBounds() {
250 int count = fSegments.count(); 281 int count = fSegments.count();
251 if (count == 0) { 282 if (count == 0) {
252 SkDebugf("%s empty contour\n", __FUNCTION__); 283 SkDebugf("%s empty contour\n", __FUNCTION__);
253 SkASSERT(0); 284 SkASSERT(0);
254 // FIXME: delete empty contour? 285 // FIXME: delete empty contour?
255 return; 286 return;
256 } 287 }
257 fBounds = fSegments.front().bounds(); 288 fBounds = fSegments.front().bounds();
258 for (int index = 1; index < count; ++index) { 289 for (int index = 1; index < count; ++index) {
259 fBounds.add(fSegments[index].bounds()); 290 fBounds.add(fSegments[index].bounds());
260 } 291 }
261 } 292 }
OLDNEW
« no previous file with comments | « src/pathops/SkOpContour.h ('k') | src/pathops/SkOpEdgeBuilder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698