| 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 |