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 #include "SkAddIntersections.h" | 7 #include "SkAddIntersections.h" |
8 #include "SkOpEdgeBuilder.h" | 8 #include "SkOpEdgeBuilder.h" |
9 #include "SkPathOpsCommon.h" | 9 #include "SkPathOpsCommon.h" |
10 #include "SkPathWriter.h" | 10 #include "SkPathWriter.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMi
n); | 25 SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMi
n); |
26 topLeft.fX = topLeft.fY = SK_ScalarMin; | 26 topLeft.fX = topLeft.fY = SK_ScalarMin; |
27 continue; | 27 continue; |
28 } | 28 } |
29 break; | 29 break; |
30 } | 30 } |
31 SkTDArray<SkOpSpan*> chaseArray; | 31 SkTDArray<SkOpSpan*> chaseArray; |
32 do { | 32 do { |
33 if (current->activeWinding(index, endIndex)) { | 33 if (current->activeWinding(index, endIndex)) { |
34 do { | 34 do { |
| 35 if (!unsortable && current->done()) { |
35 #if DEBUG_ACTIVE_SPANS | 36 #if DEBUG_ACTIVE_SPANS |
36 if (!unsortable && current->done()) { | |
37 DebugShowActiveSpans(contourList); | 37 DebugShowActiveSpans(contourList); |
| 38 #endif |
| 39 if (simple->isEmpty()) { |
| 40 simple->init(); |
| 41 break; |
| 42 } |
38 } | 43 } |
39 #endif | |
40 SkASSERT(unsortable || !current->done()); | 44 SkASSERT(unsortable || !current->done()); |
41 int nextStart = index; | 45 int nextStart = index; |
42 int nextEnd = endIndex; | 46 int nextEnd = endIndex; |
43 SkOpSegment* next = current->findNextWinding(&chaseArray, &n
extStart, &nextEnd, | 47 SkOpSegment* next = current->findNextWinding(&chaseArray, &n
extStart, &nextEnd, |
44 &unsortable); | 48 &unsortable); |
45 if (!next) { | 49 if (!next) { |
46 if (!unsortable && simple->hasMove() | 50 if (!unsortable && simple->hasMove() |
47 && current->verb() != SkPath::kLine_Verb | 51 && current->verb() != SkPath::kLine_Verb |
48 && !simple->isClosed()) { | 52 && !simple->isClosed()) { |
49 current->addCurveTo(index, endIndex, simple, true); | 53 current->addCurveTo(index, endIndex, simple, true); |
50 SkASSERT(simple->isClosed()); | 54 SkASSERT(simple->isClosed()); |
51 } | 55 } |
52 break; | 56 break; |
53 } | 57 } |
54 #if DEBUG_FLOW | 58 #if DEBUG_FLOW |
55 SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", _
_FUNCTION__, | 59 SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", _
_FUNCTION__, |
56 current->debugID(), current->xyAtT(index).fX, current->xyAtT
(index).fY, | 60 current->debugID(), current->xyAtT(index).fX, current->xyAtT
(index).fY, |
57 current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY); | 61 current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY); |
58 #endif | 62 #endif |
59 current->addCurveTo(index, endIndex, simple, true); | 63 current->addCurveTo(index, endIndex, simple, true); |
60 current = next; | 64 current = next; |
61 index = nextStart; | 65 index = nextStart; |
62 endIndex = nextEnd; | 66 endIndex = nextEnd; |
63 } while (!simple->isClosed() && (!unsortable | 67 } while (!simple->isClosed() && (!unsortable |
64 || !current->done(SkMin32(index, endIndex)))); | 68 || !current->done(SkMin32(index, endIndex)))); |
65 if (current->activeWinding(index, endIndex) && !simple->isClosed
()) { | 69 if (current->activeWinding(index, endIndex) && !simple->isClosed
()) { |
66 SkASSERT(unsortable); | 70 SkASSERT(unsortable || simple->isEmpty()); |
67 int min = SkMin32(index, endIndex); | 71 int min = SkMin32(index, endIndex); |
68 if (!current->done(min)) { | 72 if (!current->done(min)) { |
69 current->addCurveTo(index, endIndex, simple, true); | 73 current->addCurveTo(index, endIndex, simple, true); |
70 current->markDoneUnary(min); | 74 current->markDoneUnary(min); |
71 } | 75 } |
72 } | 76 } |
73 simple->close(); | 77 simple->close(); |
74 } else { | 78 } else { |
75 SkOpSpan* last = current->markAndChaseDoneUnary(index, endIndex)
; | 79 SkOpSpan* last = current->markAndChaseDoneUnary(index, endIndex)
; |
76 if (last && !last->fLoop) { | 80 if (last && !last->fLoop) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 } | 179 } |
176 SkOpContour* next; | 180 SkOpContour* next; |
177 do { | 181 do { |
178 next = *nextPtr++; | 182 next = *nextPtr++; |
179 } while (AddIntersectTs(current, next) && nextPtr != listEnd); | 183 } while (AddIntersectTs(current, next) && nextPtr != listEnd); |
180 } while (currentPtr != listEnd); | 184 } while (currentPtr != listEnd); |
181 // eat through coincident edges | 185 // eat through coincident edges |
182 CoincidenceCheck(&contourList, 0); | 186 CoincidenceCheck(&contourList, 0); |
183 FixOtherTIndex(&contourList); | 187 FixOtherTIndex(&contourList); |
184 SortSegments(&contourList); | 188 SortSegments(&contourList); |
185 #if DEBUG_ACTIVE_SPANS | 189 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY |
186 DebugShowActiveSpans(contourList); | 190 DebugShowActiveSpans(contourList); |
187 #endif | 191 #endif |
188 // construct closed contours | 192 // construct closed contours |
189 SkPathWriter simple(*result); | 193 SkPathWriter simple(*result); |
190 if (builder.xorMask() == kWinding_PathOpsMask ? bridgeWinding(contourList, &
simple) | 194 if (builder.xorMask() == kWinding_PathOpsMask ? bridgeWinding(contourList, &
simple) |
191 : !bridgeXor(contourList, &simple)) | 195 : !bridgeXor(contourList, &simple)) |
192 { // if some edges could not be resolved, assemble remaining fragments | 196 { // if some edges could not be resolved, assemble remaining fragments |
193 SkPath temp; | 197 SkPath temp; |
194 temp.setFillType(fillType); | 198 temp.setFillType(fillType); |
195 SkPathWriter assembled(temp); | 199 SkPathWriter assembled(temp); |
196 Assemble(simple, &assembled); | 200 Assemble(simple, &assembled); |
197 *result = *assembled.nativePath(); | 201 *result = *assembled.nativePath(); |
198 result->setFillType(fillType); | 202 result->setFillType(fillType); |
199 } | 203 } |
200 return true; | 204 return true; |
201 } | 205 } |
OLD | NEW |