| Index: src/pathops/SkPathOpsSimplify.cpp
|
| diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
|
| index fa1003054eb76678582968626837b7b270d366bf..dcd75f166641b90f6c3b2f2fce9088d685cf9d57 100644
|
| --- a/src/pathops/SkPathOpsSimplify.cpp
|
| +++ b/src/pathops/SkPathOpsSimplify.cpp
|
| @@ -10,8 +10,7 @@
|
| #include "SkPathOpsCommon.h"
|
| #include "SkPathWriter.h"
|
|
|
| -static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
|
| - SkChunkAlloc* allocator, bool* closable) {
|
| +static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple, bool* closable) {
|
| bool unsortable = false;
|
| do {
|
| SkOpSpan* span = FindSortableTop(contourList);
|
| @@ -40,11 +39,9 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
|
| if (!current->addCurveTo(start, end, simple)) {
|
| return false;
|
| }
|
| - #if DEBUG_ACTIVE_SPANS
|
| if (!simple->isClosed()) {
|
| - DebugShowActiveSpans(contourList);
|
| + SkPathOpsDebug::ShowActiveSpans(contourList);
|
| }
|
| - #endif
|
| }
|
| break;
|
| }
|
| @@ -86,9 +83,7 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
|
| }
|
| }
|
| current = FindChase(&chase, &start, &end);
|
| - #if DEBUG_ACTIVE_SPANS
|
| - DebugShowActiveSpans(contourList);
|
| - #endif
|
| + SkPathOpsDebug::ShowActiveSpans(contourList);
|
| if (!current) {
|
| break;
|
| }
|
| @@ -99,8 +94,7 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
|
| }
|
|
|
| // returns true if all edges were processed
|
| -static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
|
| - SkChunkAlloc* allocator, bool* closable) {
|
| +static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple, bool* closable) {
|
| SkOpSegment* current;
|
| SkOpSpanBase* start;
|
| SkOpSpanBase* end;
|
| @@ -108,11 +102,9 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
|
| *closable = true;
|
| while ((current = FindUndone(contourList, &start, &end))) {
|
| do {
|
| - #if DEBUG_ACTIVE_SPANS
|
| if (!unsortable && current->done()) {
|
| - DebugShowActiveSpans(contourList);
|
| + SkPathOpsDebug::ShowActiveSpans(contourList);
|
| }
|
| - #endif
|
| SkASSERT(unsortable || !current->done());
|
| SkOpSpanBase* nextStart = start;
|
| SkOpSpanBase* nextEnd = end;
|
| @@ -124,11 +116,9 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
|
| if (!current->addCurveTo(start, end, simple)) {
|
| return false;
|
| }
|
| - #if DEBUG_ACTIVE_SPANS
|
| if (!simple->isClosed()) {
|
| - DebugShowActiveSpans(contourList);
|
| + SkPathOpsDebug::ShowActiveSpans(contourList);
|
| }
|
| - #endif
|
| }
|
| break;
|
| }
|
| @@ -156,16 +146,14 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
|
| *closable = false;
|
| }
|
| simple->close();
|
| - #if DEBUG_ACTIVE_SPANS
|
| - DebugShowActiveSpans(contourList);
|
| - #endif
|
| + SkPathOpsDebug::ShowActiveSpans(contourList);
|
| }
|
| return true;
|
| }
|
|
|
| // FIXME : add this as a member of SkPath
|
| -bool Simplify(const SkPath& path, SkPath* result) {
|
| - SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
|
| +bool SimplifyDebug(const SkPath& path, SkPath* result
|
| + SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) {
|
| // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
|
| SkPath::FillType fillType = path.isInverseFillType() ? SkPath::kInverseEvenOdd_FillType
|
| : SkPath::kEvenOdd_FillType;
|
| @@ -177,16 +165,26 @@ bool Simplify(const SkPath& path, SkPath* result) {
|
| return true;
|
| }
|
| // turn path into list of segments
|
| - SkOpCoincidence coincidence;
|
| + SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
|
| SkOpContour contour;
|
| SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
|
| - SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(false)
|
| - SkDEBUGPARAMS(nullptr));
|
| + SkOpGlobalState globalState(contourList, &allocator
|
| + SkDEBUGPARAMS(skipAssert) SkDEBUGPARAMS(testName));
|
| + SkOpCoincidence coincidence(&globalState);
|
| + SkScalar scaleFactor = ScaleFactor(path);
|
| + SkPath scaledPath;
|
| + const SkPath* workingPath;
|
| + if (scaleFactor > SK_Scalar1) {
|
| + ScalePath(path, 1.f / scaleFactor, &scaledPath);
|
| + workingPath = &scaledPath;
|
| + } else {
|
| + workingPath = &path;
|
| + }
|
| #if DEBUG_SORT
|
| SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
|
| #endif
|
| - SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
|
| - if (!builder.finish(&allocator)) {
|
| + SkOpEdgeBuilder builder(*workingPath, &contour, &globalState);
|
| + if (!builder.finish()) {
|
| return false;
|
| }
|
| #if DEBUG_DUMP_SEGMENTS
|
| @@ -201,13 +199,13 @@ bool Simplify(const SkPath& path, SkPath* result) {
|
| SkOpContour* current = contourList;
|
| do {
|
| SkOpContour* next = current;
|
| - while (AddIntersectTs(current, next, &coincidence, &allocator)
|
| + while (AddIntersectTs(current, next, &coincidence)
|
| && (next = next->next()));
|
| } while ((current = current->next()));
|
| #if DEBUG_VALIDATE
|
| globalState.setPhase(SkOpGlobalState::kWalking);
|
| #endif
|
| - if (!HandleCoincidence(contourList, &coincidence, &allocator)) {
|
| + if (!HandleCoincidence(contourList, &coincidence)) {
|
| return false;
|
| }
|
| #if DEBUG_DUMP_ALIGNMENT
|
| @@ -219,8 +217,8 @@ bool Simplify(const SkPath& path, SkPath* result) {
|
| SkPathWriter wrapper(*result);
|
| bool closable SK_INIT_TO_AVOID_WARNING;
|
| if (builder.xorMask() == kWinding_PathOpsMask
|
| - ? !bridgeWinding(contourList, &wrapper, &allocator, &closable)
|
| - : !bridgeXor(contourList, &wrapper, &allocator, &closable)) {
|
| + ? !bridgeWinding(contourList, &wrapper, &closable)
|
| + : !bridgeXor(contourList, &wrapper, &closable)) {
|
| return false;
|
| }
|
| if (!closable)
|
| @@ -232,6 +230,12 @@ bool Simplify(const SkPath& path, SkPath* result) {
|
| *result = *assembled.nativePath();
|
| result->setFillType(fillType);
|
| }
|
| + if (scaleFactor > 1) {
|
| + ScalePath(*result, scaleFactor, result);
|
| + }
|
| return true;
|
| }
|
|
|
| +bool Simplify(const SkPath& path, SkPath* result) {
|
| + return SimplifyDebug(path, result SkDEBUGPARAMS(true) SkDEBUGPARAMS(nullptr));
|
| +}
|
|
|