| Index: src/pathops/SkPathOpsOp.cpp
|
| ===================================================================
|
| --- src/pathops/SkPathOpsOp.cpp (revision 8745)
|
| +++ src/pathops/SkPathOpsOp.cpp (working copy)
|
| @@ -206,18 +206,48 @@
|
| return simple->someAssemblyRequired();
|
| }
|
|
|
| +// pretty picture:
|
| +// https://docs.google.com/a/google.com/drawings/d/1sPV8rPfpEFXymBp3iSbDRWAycp1b-7vD9JP2V-kn9Ss/edit?usp=sharing
|
| +static const SkPathOp gOpInverse[kReverseDifference_PathOp + 1][2][2] = {
|
| +// inside minuend outside minuend
|
| +// inside subtrahend outside subtrahend inside subtrahend outside subtrahend
|
| + {{ kDifference_PathOp, kIntersect_PathOp }, { kUnion_PathOp, kReverseDifference_PathOp }},
|
| + {{ kIntersect_PathOp, kDifference_PathOp }, { kReverseDifference_PathOp, kUnion_PathOp }},
|
| + {{ kUnion_PathOp, kReverseDifference_PathOp }, { kDifference_PathOp, kIntersect_PathOp }},
|
| + {{ kXOR_PathOp, kXOR_PathOp }, { kXOR_PathOp, kXOR_PathOp }},
|
| + {{ kReverseDifference_PathOp, kUnion_PathOp }, { kIntersect_PathOp, kDifference_PathOp }},
|
| +};
|
| +
|
| +static const bool gOutInverse[kReverseDifference_PathOp + 1][2][2] = {
|
| + {{ false, false }, { true, false }}, // diff
|
| + {{ false, false }, { false, true }}, // sect
|
| + {{ false, true }, { true, true }}, // union
|
| + {{ false, true }, { true, false }}, // xor
|
| + {{ false, true }, { false, false }}, // rev diff
|
| +};
|
| +
|
| void Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
|
| + op = gOpInverse[op][one.isInverseFillType()][two.isInverseFillType()];
|
| + result->reset();
|
| + SkPath::FillType fillType = gOutInverse[op][one.isInverseFillType()][two.isInverseFillType()]
|
| + ? SkPath::kInverseEvenOdd_FillType : SkPath::kEvenOdd_FillType;
|
| + result->setFillType(fillType);
|
| + const SkPath* minuend = &one;
|
| + const SkPath* subtrahend = &two;
|
| + if (op == kReverseDifference_PathOp) {
|
| + minuend = &two;
|
| + subtrahend = &one;
|
| + op = kDifference_PathOp;
|
| + }
|
| #if DEBUG_SORT || DEBUG_SWAP_TOP
|
| gDebugSortCount = gDebugSortCountDefault;
|
| #endif
|
| - result->reset();
|
| - result->setFillType(SkPath::kEvenOdd_FillType);
|
| // turn path into list of segments
|
| SkTArray<SkOpContour> contours;
|
| // FIXME: add self-intersecting cubics' T values to segment
|
| - SkOpEdgeBuilder builder(one, contours);
|
| + SkOpEdgeBuilder builder(*minuend, contours);
|
| const int xorMask = builder.xorMask();
|
| - builder.addOperand(two);
|
| + builder.addOperand(*subtrahend);
|
| builder.finish();
|
| const int xorOpMask = builder.xorMask();
|
| SkTDArray<SkOpContour*> contourList;
|
| @@ -264,7 +294,7 @@
|
| bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper);
|
| { // if some edges could not be resolved, assemble remaining fragments
|
| SkPath temp;
|
| - temp.setFillType(SkPath::kEvenOdd_FillType);
|
| + temp.setFillType(fillType);
|
| SkPathWriter assembled(temp);
|
| Assemble(wrapper, &assembled);
|
| *result = *assembled.nativePath();
|
|
|