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" |
11 | 11 |
12 // FIXME: this and find chase should be merge together, along with | 12 // FIXME: this and find chase should be merge together, along with |
13 // other code that walks winding in angles | 13 // other code that walks winding in angles |
14 // OPTIMIZATION: Probably, the walked winding should be rolled into the angle st
ructure | 14 // OPTIMIZATION: Probably, the walked winding should be rolled into the angle st
ructure |
15 // so it isn't duplicated by walkers like this one | 15 // so it isn't duplicated by walkers like this one |
16 static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int
& nextEnd) { | 16 static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int
& nextEnd) { |
17 while (chase.count()) { | 17 while (chase.count()) { |
18 SkOpSpan* span; | 18 SkOpSpan* span; |
19 chase.pop(&span); | 19 chase.pop(&span); |
20 const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex); | 20 const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex); |
21 SkOpSegment* segment = backPtr.fOther; | 21 SkOpSegment* segment = backPtr.fOther; |
22 nextStart = backPtr.fOtherIndex; | 22 nextStart = backPtr.fOtherIndex; |
23 SkTDArray<SkOpAngle> angles; | 23 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
24 int done = 0; | 24 int done = 0; |
25 if (segment->activeAngle(nextStart, &done, &angles)) { | 25 if (segment->activeAngle(nextStart, &done, &angles)) { |
26 SkOpAngle* last = angles.end() - 1; | 26 SkOpAngle* last = angles.end() - 1; |
27 nextStart = last->start(); | 27 nextStart = last->start(); |
28 nextEnd = last->end(); | 28 nextEnd = last->end(); |
29 #if TRY_ROTATE | 29 #if TRY_ROTATE |
30 *chase.insert(0) = span; | 30 *chase.insert(0) = span; |
31 #else | 31 #else |
32 *chase.append() = span; | 32 *chase.append() = span; |
33 #endif | 33 #endif |
34 return last->segment(); | 34 return last->segment(); |
35 } | 35 } |
36 if (done == angles.count()) { | 36 if (done == angles.count()) { |
37 continue; | 37 continue; |
38 } | 38 } |
39 SkTDArray<SkOpAngle*> sorted; | 39 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
40 bool sortable = SkOpSegment::SortAngles(angles, &sorted, | 40 bool sortable = SkOpSegment::SortAngles(angles, &sorted, |
41 SkOpSegment::kMayBeUnordered_SortAngleKind); | 41 SkOpSegment::kMayBeUnordered_SortAngleKind); |
42 int angleCount = sorted.count(); | 42 int angleCount = sorted.count(); |
43 #if DEBUG_SORT | 43 #if DEBUG_SORT |
44 sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0); | 44 sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0); |
45 #endif | 45 #endif |
46 if (!sortable) { | 46 if (!sortable) { |
47 continue; | 47 continue; |
48 } | 48 } |
49 // find first angle, initialize winding to computed fWindSum | 49 // find first angle, initialize winding to computed fWindSum |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 return spanWinding != oppSpanWinding; | 119 return spanWinding != oppSpanWinding; |
120 default: | 120 default: |
121 SkASSERT(0); | 121 SkASSERT(0); |
122 } | 122 } |
123 } | 123 } |
124 bool opActive = oppWinding != 0; | 124 bool opActive = oppWinding != 0; |
125 return gOpLookup[op][opActive][windingIsOp]; | 125 return gOpLookup[op][opActive][windingIsOp]; |
126 } | 126 } |
127 */ | 127 */ |
128 | 128 |
129 static bool bridgeOp(SkTDArray<SkOpContour*>& contourList, const SkPathOp op, | 129 static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp o
p, |
130 const int xorMask, const int xorOpMask, SkPathWriter* simple) { | 130 const int xorMask, const int xorOpMask, SkPathWriter* simple) { |
131 bool firstContour = true; | 131 bool firstContour = true; |
132 bool unsortable = false; | 132 bool unsortable = false; |
133 bool topUnsortable = false; | 133 bool topUnsortable = false; |
134 SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin}; | 134 SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin}; |
135 do { | 135 do { |
136 int index, endIndex; | 136 int index, endIndex; |
137 bool done; | 137 bool done; |
138 SkOpSegment* current = FindSortableTop(contourList, &firstContour, &inde
x, &endIndex, | 138 SkOpSegment* current = FindSortableTop(contourList, &firstContour, &inde
x, &endIndex, |
139 &topLeft, &topUnsortable, &done, true); | 139 &topLeft, &topUnsortable, &done, true); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 // FIXME: add self-intersecting cubics' T values to segment | 256 // FIXME: add self-intersecting cubics' T values to segment |
257 SkOpEdgeBuilder builder(*minuend, contours); | 257 SkOpEdgeBuilder builder(*minuend, contours); |
258 const int xorMask = builder.xorMask(); | 258 const int xorMask = builder.xorMask(); |
259 builder.addOperand(*subtrahend); | 259 builder.addOperand(*subtrahend); |
260 if (!builder.finish()) { | 260 if (!builder.finish()) { |
261 return false; | 261 return false; |
262 } | 262 } |
263 result->reset(); | 263 result->reset(); |
264 result->setFillType(fillType); | 264 result->setFillType(fillType); |
265 const int xorOpMask = builder.xorMask(); | 265 const int xorOpMask = builder.xorMask(); |
266 SkTDArray<SkOpContour*> contourList; | 266 SkTArray<SkOpContour*, true> contourList; |
267 MakeContourList(contours, contourList, xorMask == kEvenOdd_PathOpsMask, | 267 MakeContourList(contours, contourList, xorMask == kEvenOdd_PathOpsMask, |
268 xorOpMask == kEvenOdd_PathOpsMask); | 268 xorOpMask == kEvenOdd_PathOpsMask); |
269 SkOpContour** currentPtr = contourList.begin(); | 269 SkOpContour** currentPtr = contourList.begin(); |
270 if (!currentPtr) { | 270 if (!currentPtr) { |
271 return true; | 271 return true; |
272 } | 272 } |
273 SkOpContour** listEnd = contourList.end(); | 273 SkOpContour** listEnd = contourList.end(); |
274 // find all intersections between segments | 274 // find all intersections between segments |
275 do { | 275 do { |
276 SkOpContour** nextPtr = currentPtr; | 276 SkOpContour** nextPtr = currentPtr; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 { // if some edges could not be resolved, assemble remaining fragments | 308 { // if some edges could not be resolved, assemble remaining fragments |
309 SkPath temp; | 309 SkPath temp; |
310 temp.setFillType(fillType); | 310 temp.setFillType(fillType); |
311 SkPathWriter assembled(temp); | 311 SkPathWriter assembled(temp); |
312 Assemble(wrapper, &assembled); | 312 Assemble(wrapper, &assembled); |
313 *result = *assembled.nativePath(); | 313 *result = *assembled.nativePath(); |
314 result->setFillType(fillType); | 314 result->setFillType(fillType); |
315 } | 315 } |
316 return true; | 316 return true; |
317 } | 317 } |
OLD | NEW |