| 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 "SkOpCoincidence.h" | 8 #include "SkOpCoincidence.h" |
| 9 #include "SkOpEdgeBuilder.h" | 9 #include "SkOpEdgeBuilder.h" |
| 10 #include "SkPathOpsCommon.h" | 10 #include "SkPathOpsCommon.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 } while (!simple->isClosed() && (!unsortable || !start->starter(
end)->done())); | 145 } while (!simple->isClosed() && (!unsortable || !start->starter(
end)->done())); |
| 146 if (current->activeWinding(start, end) && !simple->isClosed()) { | 146 if (current->activeWinding(start, end) && !simple->isClosed()) { |
| 147 SkOpSpan* spanStart = start->starter(end); | 147 SkOpSpan* spanStart = start->starter(end); |
| 148 if (!spanStart->done()) { | 148 if (!spanStart->done()) { |
| 149 if (!current->addCurveTo(start, end, simple)) { | 149 if (!current->addCurveTo(start, end, simple)) { |
| 150 return false; | 150 return false; |
| 151 } | 151 } |
| 152 current->markDone(spanStart); | 152 current->markDone(spanStart); |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 simple->close(); | 155 simple->finishContour(); |
| 156 } else { | 156 } else { |
| 157 SkOpSpanBase* last = current->markAndChaseDone(start, end); | 157 SkOpSpanBase* last = current->markAndChaseDone(start, end); |
| 158 if (last && !last->chased()) { | 158 if (last && !last->chased()) { |
| 159 last->setChased(true); | 159 last->setChased(true); |
| 160 SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last)); | 160 SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last)); |
| 161 *chase.append() = last; | 161 *chase.append() = last; |
| 162 #if DEBUG_WINDING | 162 #if DEBUG_WINDING |
| 163 SkDebugf("%s chase.append id=%d", __FUNCTION__, last->segmen
t()->debugID()); | 163 SkDebugf("%s chase.append id=%d", __FUNCTION__, last->segmen
t()->debugID()); |
| 164 if (!last->final()) { | 164 if (!last->final()) { |
| 165 SkDebugf(" windSum=%d", last->upCast()->windSum()); | 165 SkDebugf(" windSum=%d", last->upCast()->windSum()); |
| 166 } | 166 } |
| 167 SkDebugf("\n"); | 167 SkDebugf("\n"); |
| 168 #endif | 168 #endif |
| 169 } | 169 } |
| 170 } | 170 } |
| 171 current = findChaseOp(chase, &start, &end); | 171 current = findChaseOp(chase, &start, &end); |
| 172 SkPathOpsDebug::ShowActiveSpans(contourList); | 172 SkPathOpsDebug::ShowActiveSpans(contourList); |
| 173 if (!current) { | 173 if (!current) { |
| 174 break; | 174 break; |
| 175 } | 175 } |
| 176 } while (true); | 176 } while (true); |
| 177 } while (true); | 177 } while (true); |
| 178 return simple->someAssemblyRequired(); | 178 return true; |
| 179 } | 179 } |
| 180 | 180 |
| 181 // pretty picture: | 181 // pretty picture: |
| 182 // https://docs.google.com/a/google.com/drawings/d/1sPV8rPfpEFXymBp3iSbDRWAycp1b
-7vD9JP2V-kn9Ss/edit?usp=sharing | 182 // https://docs.google.com/a/google.com/drawings/d/1sPV8rPfpEFXymBp3iSbDRWAycp1b
-7vD9JP2V-kn9Ss/edit?usp=sharing |
| 183 static const SkPathOp gOpInverse[kReverseDifference_SkPathOp + 1][2][2] = { | 183 static const SkPathOp gOpInverse[kReverseDifference_SkPathOp + 1][2][2] = { |
| 184 // inside minuend outside minuend | 184 // inside minuend outside minuend |
| 185 // inside subtrahend outside subtrahend inside subtrahend outsi
de subtrahend | 185 // inside subtrahend outside subtrahend inside subtrahend outsi
de subtrahend |
| 186 {{ kDifference_SkPathOp, kIntersect_SkPathOp }, { kUnion_SkPathOp, kReverseDif
ference_SkPathOp }}, | 186 {{ kDifference_SkPathOp, kIntersect_SkPathOp }, { kUnion_SkPathOp, kReverseDif
ference_SkPathOp }}, |
| 187 {{ kIntersect_SkPathOp, kDifference_SkPathOp }, { kReverseDifference_SkPathOp,
kUnion_SkPathOp }}, | 187 {{ kIntersect_SkPathOp, kDifference_SkPathOp }, { kReverseDifference_SkPathOp,
kUnion_SkPathOp }}, |
| 188 {{ kUnion_SkPathOp, kReverseDifference_SkPathOp }, { kDifference_SkPathOp, kIn
tersect_SkPathOp }}, | 188 {{ kUnion_SkPathOp, kReverseDifference_SkPathOp }, { kDifference_SkPathOp, kIn
tersect_SkPathOp }}, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 subtrahend = &two; | 279 subtrahend = &two; |
| 280 } | 280 } |
| 281 if (op == kReverseDifference_SkPathOp) { | 281 if (op == kReverseDifference_SkPathOp) { |
| 282 SkTSwap(minuend, subtrahend); | 282 SkTSwap(minuend, subtrahend); |
| 283 op = kDifference_SkPathOp; | 283 op = kDifference_SkPathOp; |
| 284 } | 284 } |
| 285 #if DEBUG_SORT | 285 #if DEBUG_SORT |
| 286 SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault; | 286 SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault; |
| 287 #endif | 287 #endif |
| 288 // turn path into list of segments | 288 // turn path into list of segments |
| 289 SkOpEdgeBuilder builder(*minuend, &contour, &globalState); | 289 SkOpEdgeBuilder builder(*minuend, contourList, &globalState); |
| 290 if (builder.unparseable()) { | 290 if (builder.unparseable()) { |
| 291 return false; | 291 return false; |
| 292 } | 292 } |
| 293 const int xorMask = builder.xorMask(); | 293 const int xorMask = builder.xorMask(); |
| 294 builder.addOperand(*subtrahend); | 294 builder.addOperand(*subtrahend); |
| 295 if (!builder.finish()) { | 295 if (!builder.finish()) { |
| 296 return false; | 296 return false; |
| 297 } | 297 } |
| 298 #if DEBUG_DUMP_SEGMENTS | 298 #if DEBUG_DUMP_SEGMENTS |
| 299 contourList->dumpSegments("seg", op); | 299 contourList->dumpSegments("seg", op); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 320 if (!HandleCoincidence(contourList, &coincidence)) { | 320 if (!HandleCoincidence(contourList, &coincidence)) { |
| 321 return false; | 321 return false; |
| 322 } | 322 } |
| 323 #if DEBUG_ALIGNMENT | 323 #if DEBUG_ALIGNMENT |
| 324 contourList->dumpSegments("aligned"); | 324 contourList->dumpSegments("aligned"); |
| 325 #endif | 325 #endif |
| 326 // construct closed contours | 326 // construct closed contours |
| 327 result->reset(); | 327 result->reset(); |
| 328 result->setFillType(fillType); | 328 result->setFillType(fillType); |
| 329 SkPathWriter wrapper(*result); | 329 SkPathWriter wrapper(*result); |
| 330 bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper); | 330 if (!bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper)) { |
| 331 { // if some edges could not be resolved, assemble remaining fragments | 331 return false; |
| 332 SkPath temp; | |
| 333 temp.setFillType(fillType); | |
| 334 SkPathWriter assembled(temp); | |
| 335 Assemble(wrapper, &assembled); | |
| 336 *result = *assembled.nativePath(); | |
| 337 result->setFillType(fillType); | |
| 338 } | 332 } |
| 333 wrapper.assemble(); // if some edges could not be resolved, assemble remain
ing |
| 339 #if DEBUG_T_SECT_LOOP_COUNT | 334 #if DEBUG_T_SECT_LOOP_COUNT |
| 340 { | 335 { |
| 341 SkAutoMutexAcquire autoM(debugWorstLoop); | 336 SkAutoMutexAcquire autoM(debugWorstLoop); |
| 342 if (!gVerboseFinalize) { | 337 if (!gVerboseFinalize) { |
| 343 gVerboseFinalize = &ReportPathOpsDebugging; | 338 gVerboseFinalize = &ReportPathOpsDebugging; |
| 344 } | 339 } |
| 345 debugWorstState.debugDoYourWorst(&globalState); | 340 debugWorstState.debugDoYourWorst(&globalState); |
| 346 } | 341 } |
| 347 #endif | 342 #endif |
| 348 if (scaleFactor > 1) { | 343 if (scaleFactor > 1) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 one.dumpHex(); | 458 one.dumpHex(); |
| 464 SkDebugf("two: fill=%d\n", two.getFillType()); | 459 SkDebugf("two: fill=%d\n", two.getFillType()); |
| 465 two.dumpHex(); | 460 two.dumpHex(); |
| 466 SkASSERT(0); | 461 SkASSERT(0); |
| 467 } | 462 } |
| 468 return true; | 463 return true; |
| 469 #else | 464 #else |
| 470 return OpDebug(one, two, op, result SkDEBUGPARAMS(true) SkDEBUGPARAMS(nullp
tr)); | 465 return OpDebug(one, two, op, result SkDEBUGPARAMS(true) SkDEBUGPARAMS(nullp
tr)); |
| 471 #endif | 466 #endif |
| 472 } | 467 } |
| OLD | NEW |