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

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

Issue 1111333002: compute initial winding from projected rays (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add missing test reference Created 5 years, 7 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
« no previous file with comments | « src/pathops/SkPathOpsQuad.cpp ('k') | src/pathops/SkPathOpsTightBounds.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 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 #include "SkAddIntersections.h" 7 #include "SkAddIntersections.h"
8 #include "SkOpCoincidence.h" 8 #include "SkOpCoincidence.h"
9 #include "SkOpEdgeBuilder.h" 9 #include "SkOpEdgeBuilder.h"
10 #include "SkPathOpsCommon.h" 10 #include "SkPathOpsCommon.h"
11 #include "SkPathWriter.h" 11 #include "SkPathWriter.h"
12 12
13 static bool bridgeWinding(SkTDArray<SkOpContour* >& contourList, SkPathWriter* s imple, 13 static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
14 SkChunkAlloc* allocator) { 14 SkChunkAlloc* allocator) {
15 bool firstContour = true;
16 bool unsortable = false; 15 bool unsortable = false;
17 bool topUnsortable = false;
18 bool firstPass = true;
19 SkDPoint lastTopLeft;
20 SkDPoint topLeft = {SK_ScalarMin, SK_ScalarMin};
21 do { 16 do {
22 SkOpSpanBase* start = NULL; 17 SkOpSpan* span = FindSortableTop(contourList);
23 SkOpSpanBase* end = NULL; 18 if (!span) {
24 bool topDone;
25 bool onlyVertical = false;
26 lastTopLeft = topLeft;
27 SkOpSegment* current = FindSortableTop(contourList, firstPass, SkOpAngle ::kUnaryWinding,
28 &firstContour, &start, &end, &topLeft, &topUnsortable, &topDone, &onlyVertical,
29 allocator);
30 if (!current) {
31 if ((!topUnsortable || firstPass) && !topDone) {
32 SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMi n);
33 if (lastTopLeft.fX == SK_ScalarMin && lastTopLeft.fY == SK_Scala rMin) {
34 if (firstPass) {
35 firstPass = false;
36 } else {
37 break;
38 }
39 }
40 topLeft.fX = topLeft.fY = SK_ScalarMin;
41 continue;
42 }
43 break;
44 } else if (onlyVertical) {
45 break; 19 break;
46 } 20 }
47 firstPass = !topUnsortable || lastTopLeft != topLeft; 21 SkOpSegment* current = span->segment();
22 SkOpSpanBase* start = span->next();
23 SkOpSpanBase* end = span;
48 SkTDArray<SkOpSpanBase*> chase; 24 SkTDArray<SkOpSpanBase*> chase;
49 do { 25 do {
50 if (current->activeWinding(start, end)) { 26 if (current->activeWinding(start, end)) {
51 do { 27 do {
52 if (!unsortable && current->done()) { 28 if (!unsortable && current->done()) {
53 break; 29 break;
54 } 30 }
55 SkASSERT(unsortable || !current->done()); 31 SkASSERT(unsortable || !current->done());
56 SkOpSpanBase* nextStart = start; 32 SkOpSpanBase* nextStart = start;
57 SkOpSpanBase* nextEnd = end; 33 SkOpSpanBase* nextEnd = end;
(...skipping 28 matching lines...) Expand all
86 current->addCurveTo(start, end, simple, true); 62 current->addCurveTo(start, end, simple, true);
87 current->markDone(spanStart); 63 current->markDone(spanStart);
88 } 64 }
89 } 65 }
90 simple->close(); 66 simple->close();
91 } else { 67 } else {
92 SkOpSpanBase* last = current->markAndChaseDone(start, end); 68 SkOpSpanBase* last = current->markAndChaseDone(start, end);
93 if (last && !last->chased()) { 69 if (last && !last->chased()) {
94 last->setChased(true); 70 last->setChased(true);
95 SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last)); 71 SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last));
96 // assert that last isn't already in array
97 *chase.append() = last; 72 *chase.append() = last;
98 #if DEBUG_WINDING 73 #if DEBUG_WINDING
99 SkDebugf("%s chase.append id=%d", __FUNCTION__, last->segmen t()->debugID()); 74 SkDebugf("%s chase.append id=%d", __FUNCTION__, last->segmen t()->debugID());
100 if (!last->final()) { 75 if (!last->final()) {
101 SkDebugf(" windSum=%d", last->upCast()->windSum()); 76 SkDebugf(" windSum=%d", last->upCast()->windSum());
102 } 77 }
103 SkDebugf("\n"); 78 SkDebugf("\n");
104 #endif 79 #endif
105 } 80 }
106 } 81 }
107 current = FindChase(&chase, &start, &end); 82 current = FindChase(&chase, &start, &end);
108 #if DEBUG_ACTIVE_SPANS 83 #if DEBUG_ACTIVE_SPANS
109 DebugShowActiveSpans(contourList); 84 DebugShowActiveSpans(contourList);
110 #endif 85 #endif
111 if (!current) { 86 if (!current) {
112 break; 87 break;
113 } 88 }
114 } while (true); 89 } while (true);
115 } while (true); 90 } while (true);
116 return simple->someAssemblyRequired(); 91 return simple->someAssemblyRequired();
117 } 92 }
118 93
119 // returns true if all edges were processed 94 // returns true if all edges were processed
120 static bool bridgeXor(SkTDArray<SkOpContour* >& contourList, SkPathWriter* simpl e, 95 static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
121 SkChunkAlloc* allocator) { 96 SkChunkAlloc* allocator) {
122 SkOpSegment* current; 97 SkOpSegment* current;
123 SkOpSpanBase* start; 98 SkOpSpanBase* start;
124 SkOpSpanBase* end; 99 SkOpSpanBase* end;
125 bool unsortable = false; 100 bool unsortable = false;
126 bool closable = true; 101 bool closable = true;
127 while ((current = FindUndone(contourList, &start, &end))) { 102 while ((current = FindUndone(contourList, &start, &end))) {
128 do { 103 do {
129 #if DEBUG_ACTIVE_SPANS 104 #if DEBUG_ACTIVE_SPANS
130 if (!unsortable && current->done()) { 105 if (!unsortable && current->done()) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 if (path.isConvex()) { 159 if (path.isConvex()) {
185 if (result != &path) { 160 if (result != &path) {
186 *result = path; 161 *result = path;
187 } 162 }
188 result->setFillType(fillType); 163 result->setFillType(fillType);
189 return true; 164 return true;
190 } 165 }
191 // turn path into list of segments 166 // turn path into list of segments
192 SkOpCoincidence coincidence; 167 SkOpCoincidence coincidence;
193 SkOpContour contour; 168 SkOpContour contour;
194 SkOpGlobalState globalState(&coincidence SkDEBUGPARAMS(&contour)); 169 SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
195 #if DEBUG_SORT || DEBUG_SWAP_TOP 170 SkOpGlobalState globalState(&coincidence, contourList);
171 #if DEBUG_SORT
196 SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault; 172 SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
197 #endif 173 #endif
198 SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState); 174 SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
199 if (!builder.finish(&allocator)) { 175 if (!builder.finish(&allocator)) {
200 return false; 176 return false;
201 } 177 }
202 #if DEBUG_DUMP_SEGMENTS 178 #if DEBUG_DUMP_SEGMENTS
203 contour.dumpSegments((SkPathOp) -1); 179 contour.dumpSegments((SkPathOp) -1);
204 #endif 180 #endif
205 SkTDArray<SkOpContour* > contourList; 181 if (!SortContourList(&contourList, false, false)) {
206 MakeContourList(&contour, contourList, false, false);
207 SkOpContour** currentPtr = contourList.begin();
208 if (!currentPtr) {
209 result->reset(); 182 result->reset();
210 result->setFillType(fillType); 183 result->setFillType(fillType);
211 return true; 184 return true;
212 } 185 }
213 if ((*currentPtr)->count() == 0) {
214 SkASSERT((*currentPtr)->next() == NULL);
215 result->reset();
216 result->setFillType(fillType);
217 return true;
218 }
219 SkOpContour** listEnd2 = contourList.end();
220 // find all intersections between segments 186 // find all intersections between segments
187 SkOpContour* current = contourList;
221 do { 188 do {
222 SkOpContour** nextPtr = currentPtr; 189 SkOpContour* next = current;
223 SkOpContour* current = *currentPtr++; 190 while (AddIntersectTs(current, next, &coincidence, &allocator)
224 SkOpContour* next; 191 && (next = next->next()));
225 do { 192 } while ((current = current->next()));
226 next = *nextPtr++;
227 } while (AddIntersectTs(current, next, &coincidence, &allocator) && next Ptr != listEnd2);
228 } while (currentPtr != listEnd2);
229 #if DEBUG_VALIDATE 193 #if DEBUG_VALIDATE
230 globalState.setPhase(SkOpGlobalState::kWalking); 194 globalState.setPhase(SkOpGlobalState::kWalking);
231 #endif 195 #endif
232 if (!HandleCoincidence(&contourList, &coincidence, &allocator, &globalState) ) { 196 if (!HandleCoincidence(contourList, &coincidence, &allocator)) {
233 return false; 197 return false;
234 } 198 }
235 // construct closed contours 199 // construct closed contours
236 result->reset(); 200 result->reset();
237 result->setFillType(fillType); 201 result->setFillType(fillType);
238 SkPathWriter wrapper(*result); 202 SkPathWriter wrapper(*result);
239 if (builder.xorMask() == kWinding_PathOpsMask ? bridgeWinding(contourList, & wrapper, &allocator) 203 if (builder.xorMask() == kWinding_PathOpsMask ? bridgeWinding(contourList, & wrapper, &allocator)
240 : !bridgeXor(contourList, &wrapper, &allocator)) 204 : !bridgeXor(contourList, &wrapper, &allocator))
241 { // if some edges could not be resolved, assemble remaining fragments 205 { // if some edges could not be resolved, assemble remaining fragments
242 SkPath temp; 206 SkPath temp;
243 temp.setFillType(fillType); 207 temp.setFillType(fillType);
244 SkPathWriter assembled(temp); 208 SkPathWriter assembled(temp);
245 Assemble(wrapper, &assembled); 209 Assemble(wrapper, &assembled);
246 *result = *assembled.nativePath(); 210 *result = *assembled.nativePath();
247 result->setFillType(fillType); 211 result->setFillType(fillType);
248 } 212 }
249 return true; 213 return true;
250 } 214 }
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsQuad.cpp ('k') | src/pathops/SkPathOpsTightBounds.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698