/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkMutex.h"
#include "SkOpCoincidence.h"
#include "SkOpContour.h"
#include "SkOSFile.h"
#include "SkPath.h"
#include "SkPathOpsDebug.h"
#include "SkString.h"

#include <utility>

#if DEBUG_DUMP_VERIFY
bool SkPathOpsDebug::gDumpOp;  // set to true to write op to file before a crash
bool SkPathOpsDebug::gVerifyOp;  // set to true to compare result against regions
#endif

bool SkPathOpsDebug::gRunFail;  // set to true to check for success on tests known to fail
bool SkPathOpsDebug::gVeryVerbose;  // set to true to run extensive checking tests

#undef FAIL_IF
#define FAIL_IF(cond, coin) \
         do { if (cond) log->record(SkPathOpsDebug::kFail_Glitch, coin); } while (false)

#undef FAIL_WITH_NULL_IF
#define FAIL_WITH_NULL_IF(cond, span) \
         do { if (cond) log->record(SkPathOpsDebug::kFail_Glitch, span); } while (false)

#undef RETURN_FALSE_IF
#define RETURN_FALSE_IF(cond, span) \
         do { if (cond) log->record(SkPathOpsDebug::kReturnFalse_Glitch, span); \
         } while (false)

class SkCoincidentSpans;

#if DEBUG_SORT
int SkPathOpsDebug::gSortCountDefault = SK_MaxS32;
int SkPathOpsDebug::gSortCount;
#endif

#if DEBUG_ACTIVE_OP
const char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor", "rdiff"};
#endif

#if defined SK_DEBUG || !FORCE_RELEASE

int SkPathOpsDebug::gContourID = 0;
int SkPathOpsDebug::gSegmentID = 0;

bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpanBase* >& chaseArray,
        const SkOpSpanBase* span) {
    for (int index = 0; index < chaseArray.count(); ++index) {
        const SkOpSpanBase* entry = chaseArray[index];
        if (entry == span) {
            return true;
        }
    }
    return false;
}
#endif

#if DEBUG_ACTIVE_SPANS
SkString SkPathOpsDebug::gActiveSpans;
#endif

#if DEBUG_COIN

SkPathOpsDebug::CoinDict SkPathOpsDebug::gCoinSumChangedDict;
SkPathOpsDebug::CoinDict SkPathOpsDebug::gCoinSumVisitedDict;

static const int kGlitchType_Count = SkPathOpsDebug::kUnalignedTail_Glitch + 1;

struct SpanGlitch {
    const SkOpSpanBase* fBase;
    const SkOpSpanBase* fSuspect;
    const SkOpSegment* fSegment;
    const SkOpSegment* fOppSegment;
    const SkOpPtT* fCoinSpan;
    const SkOpPtT* fEndSpan;
    const SkOpPtT* fOppSpan;
    const SkOpPtT* fOppEndSpan;
    double fStartT;
    double fEndT;
    double fOppStartT;
    double fOppEndT;
    SkPoint fPt;
    SkPathOpsDebug::GlitchType fType;

    void dumpType() const;
};

struct SkPathOpsDebug::GlitchLog {
    void init(const SkOpGlobalState* state) {
        fGlobalState = state;
    }

    SpanGlitch* recordCommon(GlitchType type) {
        SpanGlitch* glitch = fGlitches.push();
        glitch->fBase = nullptr;
        glitch->fSuspect = nullptr;
        glitch->fSegment = nullptr;
        glitch->fOppSegment = nullptr;
        glitch->fCoinSpan = nullptr;
        glitch->fEndSpan = nullptr;
        glitch->fOppSpan = nullptr;
        glitch->fOppEndSpan = nullptr;
        glitch->fStartT = SK_ScalarNaN;
        glitch->fEndT = SK_ScalarNaN;
        glitch->fOppStartT = SK_ScalarNaN;
        glitch->fOppEndT = SK_ScalarNaN;
        glitch->fPt = { SK_ScalarNaN, SK_ScalarNaN };
        glitch->fType = type;
        return glitch;
    }

    void record(GlitchType type, const SkOpSpanBase* base,
            const SkOpSpanBase* suspect = NULL) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fBase = base;
        glitch->fSuspect = suspect;
    }

    void record(GlitchType type, const SkOpSpanBase* base,
            const SkOpPtT* ptT) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fBase = base;
        glitch->fCoinSpan = ptT;
    }

    void record(GlitchType type, const SkCoincidentSpans* coin,
            const SkCoincidentSpans* opp = NULL) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fCoinSpan = coin->coinPtTStart();
        glitch->fEndSpan = coin->coinPtTEnd();
        if (opp) {
            glitch->fOppSpan = opp->coinPtTStart();
            glitch->fOppEndSpan = opp->coinPtTEnd();
        }
    }

    void record(GlitchType type, const SkOpSpanBase* base,
            const SkOpSegment* seg, double t, SkPoint pt) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fBase = base;
        glitch->fSegment = seg;
        glitch->fStartT = t;
        glitch->fPt = pt;
    }

    void record(GlitchType type, const SkOpSpanBase* base, double t,
            SkPoint pt) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fBase = base;
        glitch->fStartT = t;
        glitch->fPt = pt;
    }

    void record(GlitchType type, const SkCoincidentSpans* coin,
            const SkOpPtT* coinSpan, const SkOpPtT* endSpan) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fCoinSpan = coin->coinPtTStart();
        glitch->fEndSpan = coin->coinPtTEnd();
        glitch->fEndSpan = endSpan;
        glitch->fOppSpan = coinSpan;
        glitch->fOppEndSpan = endSpan;
    }

    void record(GlitchType type, const SkCoincidentSpans* coin,
            const SkOpSpanBase* base) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fBase = base;
        glitch->fCoinSpan = coin->coinPtTStart();
        glitch->fEndSpan = coin->coinPtTEnd();
    }

    void record(GlitchType type, const SkOpPtT* ptTS, const SkOpPtT* ptTE,
            const SkOpPtT* oPtTS, const SkOpPtT* oPtTE) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fCoinSpan = ptTS;
        glitch->fEndSpan = ptTE;
        glitch->fOppSpan = oPtTS;
        glitch->fOppEndSpan = oPtTE;
    }

    void record(GlitchType type, const SkOpSegment* seg, double startT,
            double endT, const SkOpSegment* oppSeg, double oppStartT, double oppEndT) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fSegment = seg;
        glitch->fStartT = startT;
        glitch->fEndT = endT;
        glitch->fOppSegment = oppSeg;
        glitch->fOppStartT = oppStartT;
        glitch->fOppEndT = oppEndT;
    }

    void record(GlitchType type, const SkOpSegment* seg,
            const SkOpSpan* span) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fSegment = seg;
        glitch->fBase = span;
    }

    void record(GlitchType type, double t, const SkOpSpanBase* span) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fStartT = t;
        glitch->fBase = span;
    }

    void record(GlitchType type, const SkOpSegment* seg) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fSegment = seg;
    }

    void record(GlitchType type, const SkCoincidentSpans* coin,
            const SkOpPtT* ptT) {
        SpanGlitch* glitch = recordCommon(type);
        glitch->fCoinSpan = coin->coinPtTStart();
        glitch->fEndSpan = ptT;
    }

    SkTDArray<SpanGlitch> fGlitches;
    const SkOpGlobalState* fGlobalState;
};


void SkPathOpsDebug::CoinDict::add(const SkPathOpsDebug::CoinDict& dict) {
    int count = dict.fDict.count();
    for (int index = 0; index < count; ++index) {
        this->add(dict.fDict[index]);
    }
}

void SkPathOpsDebug::CoinDict::add(const CoinDictEntry& key) {
    int count = fDict.count();
    for (int index = 0; index < count; ++index) {
        CoinDictEntry* entry = &fDict[index];
        if (entry->fIteration == key.fIteration && entry->fLineNumber == key.fLineNumber) {
            SkASSERT(!strcmp(entry->fFunctionName, key.fFunctionName));
            if (entry->fGlitchType == kUninitialized_Glitch) {
                entry->fGlitchType = key.fGlitchType;
            }
            return;
        }
    }
    *fDict.append() = key;
}

#endif

#if DEBUG_COIN
static void missing_coincidence(SkPathOpsDebug::GlitchLog* glitches, const SkOpContourHead* contourList) {
    const SkOpContour* contour = contourList;
    // bool result = false;
    do {
        /* result |= */ contour->debugMissingCoincidence(glitches);
    } while ((contour = contour->next()));
    return;
}

static void move_multiples(SkPathOpsDebug::GlitchLog* glitches, const SkOpContourHead* contourList) {
    const SkOpContour* contour = contourList;
    do {
        if (contour->debugMoveMultiples(glitches), false) {
            return;
        }
    } while ((contour = contour->next()));
    return;
}

static void move_nearby(SkPathOpsDebug::GlitchLog* glitches, const SkOpContourHead* contourList) {
    const SkOpContour* contour = contourList;
    do {
        contour->debugMoveNearby(glitches);
    } while ((contour = contour->next()));
}


#endif

#if DEBUG_COIN
void SkOpGlobalState::debugAddToCoinChangedDict() {

#if DEBUG_COINCIDENCE
    SkPathOpsDebug::CheckHealth(fContourHead);
#endif
    // see if next coincident operation makes a change; if so, record it
    SkPathOpsDebug::GlitchLog glitches;
    const char* funcName = fCoinDictEntry.fFunctionName;
    if (!strcmp("calc_angles", funcName)) {
        ;
    } else if (!strcmp("missing_coincidence", funcName)) {
        missing_coincidence(&glitches, fContourHead);
    } else if (!strcmp("move_multiples", funcName)) {
        move_multiples(&glitches, fContourHead);
    } else if (!strcmp("move_nearby", funcName)) {
        move_nearby(&glitches, fContourHead);
    } else if (!strcmp("addExpanded", funcName)) {
        fCoincidence->debugAddExpanded(&glitches);
    } else if (!strcmp("addMissing", funcName)) {
        bool added;
        fCoincidence->debugAddMissing(&glitches, &added);
    } else if (!strcmp("addEndMovedSpans", funcName)) {
        fCoincidence->debugAddEndMovedSpans(&glitches);
    } else if (!strcmp("correctEnds", funcName)) {
        fCoincidence->debugCorrectEnds(&glitches);
    } else if (!strcmp("expand", funcName)) {
        fCoincidence->debugExpand(&glitches);
    } else if (!strcmp("findOverlaps", funcName)) {
        ;
    } else if (!strcmp("mark", funcName)) {
        fCoincidence->debugMark(&glitches);
    } else if (!strcmp("apply", funcName)) {
        ;
    } else {
        SkASSERT(0);   // add missing case
    }
    if (glitches.fGlitches.count()) {
        fCoinDictEntry.fGlitchType = glitches.fGlitches[0].fType;
    }
    fCoinChangedDict.add(fCoinDictEntry);
}
#endif

void SkPathOpsDebug::ShowActiveSpans(SkOpContourHead* contourList) {
#if DEBUG_ACTIVE_SPANS
    SkString str;
    SkOpContour* contour = contourList;
    do {
        contour->debugShowActiveSpans(&str);
    } while ((contour = contour->next()));
    if (!gActiveSpans.equals(str)) {
        const char* s = str.c_str();
        const char* end;
        while ((end = strchr(s, '\n'))) {
            SkDebugf("%.*s", end - s + 1, s);
            s = end + 1;
        }
        gActiveSpans.set(str);
    }
#endif
}

#if DEBUG_COINCIDENCE || DEBUG_COIN
void SkPathOpsDebug::CheckHealth(SkOpContourHead* contourList) {
#if DEBUG_COINCIDENCE
    contourList->globalState()->debugSetCheckHealth(true);
#endif
#if DEBUG_COIN
    GlitchLog glitches;
    const SkOpContour* contour = contourList;
    const SkOpCoincidence* coincidence = contour->globalState()->coincidence();
    coincidence->debugCheckValid(&glitches); // don't call validate; spans may be inconsistent
    do {
        contour->debugCheckHealth(&glitches);
        contour->debugMissingCoincidence(&glitches);
    } while ((contour = contour->next()));
    bool added;
    coincidence->debugAddMissing(&glitches, &added);
    coincidence->debugExpand(&glitches);
    coincidence->debugAddExpanded(&glitches);
    coincidence->debugMark(&glitches);
    unsigned mask = 0;
    for (int index = 0; index < glitches.fGlitches.count(); ++index) {
        const SpanGlitch& glitch = glitches.fGlitches[index];
        mask |= 1 << glitch.fType;
    }
    for (int index = 0; index < kGlitchType_Count; ++index) {
        SkDebugf(mask & (1 << index) ? "x" : "-");
    }
    SkDebugf(" %s\n", contourList->globalState()->debugCoinDictEntry().fFunctionName);
    for (int index = 0; index < glitches.fGlitches.count(); ++index) {
        const SpanGlitch& glitch = glitches.fGlitches[index];
        SkDebugf("%02d: ", index);
        if (glitch.fBase) {
            SkDebugf(" seg/base=%d/%d", glitch.fBase->segment()->debugID(),
                    glitch.fBase->debugID());
        }
        if (glitch.fSuspect) {
            SkDebugf(" seg/base=%d/%d", glitch.fSuspect->segment()->debugID(),
                    glitch.fSuspect->debugID());
        }
        if (glitch.fSegment) {
            SkDebugf(" segment=%d", glitch.fSegment->debugID());
        }
        if (glitch.fCoinSpan) {
            SkDebugf(" coinSeg/Span/PtT=%d/%d/%d", glitch.fCoinSpan->segment()->debugID(),
                    glitch.fCoinSpan->span()->debugID(), glitch.fCoinSpan->debugID());
        }
        if (glitch.fEndSpan) {
            SkDebugf(" endSpan=%d", glitch.fEndSpan->debugID());
        }
        if (glitch.fOppSpan) {
            SkDebugf(" oppSeg/Span/PtT=%d/%d/%d", glitch.fOppSpan->segment()->debugID(),
                    glitch.fOppSpan->span()->debugID(), glitch.fOppSpan->debugID());
        }
        if (glitch.fOppEndSpan) {
            SkDebugf(" oppEndSpan=%d", glitch.fOppEndSpan->debugID());
        }
        if (!SkScalarIsNaN(glitch.fStartT)) {
            SkDebugf(" startT=%g", glitch.fStartT);
        }
        if (!SkScalarIsNaN(glitch.fEndT)) {
            SkDebugf(" endT=%g", glitch.fEndT);
        }
        if (glitch.fOppSegment) {
            SkDebugf(" segment=%d", glitch.fOppSegment->debugID());
        }
        if (!SkScalarIsNaN(glitch.fOppStartT)) {
            SkDebugf(" oppStartT=%g", glitch.fOppStartT);
        }
        if (!SkScalarIsNaN(glitch.fOppEndT)) {
            SkDebugf(" oppEndT=%g", glitch.fOppEndT);
        }
        if (!SkScalarIsNaN(glitch.fPt.fX) || !SkScalarIsNaN(glitch.fPt.fY)) {
            SkDebugf(" pt=%g,%g", glitch.fPt.fX, glitch.fPt.fY);
        }
        DumpGlitchType(glitch.fType);
        SkDebugf("\n");
    }
#if DEBUG_COINCIDENCE
    contourList->globalState()->debugSetCheckHealth(false);
#endif
#if 01 && DEBUG_ACTIVE_SPANS
//    SkDebugf("active after %s:\n", id);
    ShowActiveSpans(contourList);
#endif
#endif
}
#endif

#if DEBUG_COIN
void SkPathOpsDebug::DumpGlitchType(GlitchType glitchType) {
    switch (glitchType) {
        case kAddCorruptCoin_Glitch: SkDebugf(" AddCorruptCoin"); break;
        case kAddExpandedCoin_Glitch: SkDebugf(" AddExpandedCoin"); break;
        case kAddExpandedFail_Glitch: SkDebugf(" AddExpandedFail"); break;
        case kAddIfCollapsed_Glitch: SkDebugf(" AddIfCollapsed"); break;; break;
        case kAddIfMissingCoin_Glitch: SkDebugf(" AddIfMissingCoin"); break;
        case kAddMissingCoin_Glitch: SkDebugf(" AddMissingCoin"); break;
        case kAddMissingExtend_Glitch: SkDebugf(" AddMissingExtend"); break;
        case kAddOrOverlap_Glitch: SkDebugf(" AAddOrOverlap"); break;
        case kCollapsedCoin_Glitch: SkDebugf(" CollapsedCoin"); break;
        case kCollapsedDone_Glitch: SkDebugf(" CollapsedDone"); break;
        case kCollapsedOppValue_Glitch: SkDebugf(" CollapsedOppValue"); break;
        case kCollapsedSpan_Glitch: SkDebugf(" CollapsedSpan"); break;
        case kCollapsedWindValue_Glitch: SkDebugf(" CollapsedWindValue"); break;
        case kCorrectEnd_Glitch: SkDebugf(" CorrectEnd"); break;
        case kDeletedCoin_Glitch: SkDebugf(" DeletedCoin"); break;
        case kExpandCoin_Glitch: SkDebugf(" ExpandCoin"); break;
        case kFail_Glitch: SkDebugf(" Fail"); break;
        case kMarkCoinEnd_Glitch: SkDebugf(" MarkCoinEnd"); break;
        case kMarkCoinInsert_Glitch: SkDebugf(" MarkCoinInsert"); break;
        case kMarkCoinMissing_Glitch: SkDebugf(" MarkCoinMissing"); break;
        case kMarkCoinStart_Glitch: SkDebugf(" MarkCoinStart"); break;
        case kMergeMatches_Glitch: SkDebugf(" MergeMatches"); break;
        case kMissingCoin_Glitch: SkDebugf(" MissingCoin"); break;
        case kMissingDone_Glitch: SkDebugf(" MissingDone"); break;
        case kMissingIntersection_Glitch: SkDebugf(" MissingIntersection"); break;
        case kMoveMultiple_Glitch: SkDebugf(" MoveMultiple"); break;
        case kMoveNearbyClearAll_Glitch: SkDebugf(" MoveNearbyClearAll"); break;
        case kMoveNearbyClearAll2_Glitch: SkDebugf(" MoveNearbyClearAll2"); break;
        case kMoveNearbyMerge_Glitch: SkDebugf(" MoveNearbyMerge"); break;
        case kMoveNearbyMergeFinal_Glitch: SkDebugf(" MoveNearbyMergeFinal"); break;
        case kMoveNearbyRelease_Glitch: SkDebugf(" MoveNearbyRelease"); break;
        case kMoveNearbyReleaseFinal_Glitch: SkDebugf(" MoveNearbyReleaseFinal"); break;
        case kReleasedSpan_Glitch: SkDebugf(" ReleasedSpan"); break;
        case kReturnFalse_Glitch: SkDebugf(" ReturnFalse"); break;
        case kUnaligned_Glitch: SkDebugf(" Unaligned"); break;
        case kUnalignedHead_Glitch: SkDebugf(" UnalignedHead"); break;
        case kUnalignedTail_Glitch: SkDebugf(" UnalignedTail"); break;
        case kUninitialized_Glitch: break;
        default: SkASSERT(0);
    }
}
#endif

#if defined SK_DEBUG || !FORCE_RELEASE
void SkPathOpsDebug::MathematicaIze(char* str, size_t bufferLen) {
    size_t len = strlen(str);
    bool num = false;
    for (size_t idx = 0; idx < len; ++idx) {
        if (num && str[idx] == 'e') {
            if (len + 2 >= bufferLen) {
                return;
            }
            memmove(&str[idx + 2], &str[idx + 1], len - idx);
            str[idx] = '*';
            str[idx + 1] = '^';
            ++len;
        }
        num = str[idx] >= '0' && str[idx] <= '9';
    }
}

bool SkPathOpsDebug::ValidWind(int wind) {
    return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
}

void SkPathOpsDebug::WindingPrintf(int wind) {
    if (wind == SK_MinS32) {
        SkDebugf("?");
    } else {
        SkDebugf("%d", wind);
    }
}
#endif //  defined SK_DEBUG || !FORCE_RELEASE


#if DEBUG_SHOW_TEST_NAME
void* SkPathOpsDebug::CreateNameStr() { return new char[DEBUG_FILENAME_STRING_LENGTH]; }

void SkPathOpsDebug::DeleteNameStr(void* v) { delete[] reinterpret_cast<char*>(v); }

void SkPathOpsDebug::BumpTestName(char* test) {
    char* num = test + strlen(test);
    while (num[-1] >= '0' && num[-1] <= '9') {
        --num;
    }
    if (num[0] == '\0') {
        return;
    }
    int dec = atoi(num);
    if (dec == 0) {
        return;
    }
    ++dec;
    SK_SNPRINTF(num, DEBUG_FILENAME_STRING_LENGTH - (num - test), "%d", dec);
}
#endif

static void show_function_header(const char* functionName) {
    SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName);
    if (strcmp("skphealth_com76", functionName) == 0) {
        SkDebugf("found it\n");
    }
}

static const char* gOpStrs[] = {
    "kDifference_SkPathOp",
    "kIntersect_SkPathOp",
    "kUnion_SkPathOp",
    "kXOR_PathOp",
    "kReverseDifference_SkPathOp",
};

const char* SkPathOpsDebug::OpStr(SkPathOp op) {
    return gOpStrs[op];
}

static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) {
    SkDebugf("    testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]);
    SkDebugf("}\n");
}

SK_DECLARE_STATIC_MUTEX(gTestMutex);

void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp,
        const char* testName) {
    SkAutoMutexAcquire ac(gTestMutex);
    show_function_header(testName);
    ShowOnePath(a, "path", true);
    ShowOnePath(b, "pathB", true);
    show_op(shapeOp, "path", "pathB");
}

#include "SkPathOpsTypes.h"
#include "SkIntersectionHelper.h"
#include "SkIntersections.h"

#if DEBUG_COIN

SK_DECLARE_STATIC_MUTEX(gCoinDictMutex);

void SkOpGlobalState::debugAddToGlobalCoinDicts() {
    SkAutoMutexAcquire ac(&gCoinDictMutex);
    SkPathOpsDebug::gCoinSumChangedDict.add(fCoinChangedDict);
    SkPathOpsDebug::gCoinSumVisitedDict.add(fCoinVisitedDict);
}

#endif

#if DEBUG_T_SECT_LOOP_COUNT
void SkOpGlobalState::debugAddLoopCount(SkIntersections* i, const SkIntersectionHelper& wt,
        const SkIntersectionHelper& wn) {
    for (int index = 0; index < (int) SK_ARRAY_COUNT(fDebugLoopCount); ++index) {
        SkIntersections::DebugLoop looper = (SkIntersections::DebugLoop) index;
        if (fDebugLoopCount[index] >= i->debugLoopCount(looper)) {
            continue;
        }
        fDebugLoopCount[index] = i->debugLoopCount(looper);
        fDebugWorstVerb[index * 2] = wt.segment()->verb();
        fDebugWorstVerb[index * 2 + 1] = wn.segment()->verb();
        sk_bzero(&fDebugWorstPts[index * 8], sizeof(SkPoint) * 8);
        memcpy(&fDebugWorstPts[index * 2 * 4], wt.pts(),
                (SkPathOpsVerbToPoints(wt.segment()->verb()) + 1) * sizeof(SkPoint));
        memcpy(&fDebugWorstPts[(index * 2 + 1) * 4], wn.pts(),
                (SkPathOpsVerbToPoints(wn.segment()->verb()) + 1) * sizeof(SkPoint));
        fDebugWorstWeight[index * 2] = wt.weight();
        fDebugWorstWeight[index * 2 + 1] = wn.weight();
    }
    i->debugResetLoopCount();
}

void SkOpGlobalState::debugDoYourWorst(SkOpGlobalState* local) {
    for (int index = 0; index < (int) SK_ARRAY_COUNT(fDebugLoopCount); ++index) {
        if (fDebugLoopCount[index] >= local->fDebugLoopCount[index]) {
            continue;
        }
        fDebugLoopCount[index] = local->fDebugLoopCount[index];
        fDebugWorstVerb[index * 2] = local->fDebugWorstVerb[index * 2];
        fDebugWorstVerb[index * 2 + 1] = local->fDebugWorstVerb[index * 2 + 1];
        memcpy(&fDebugWorstPts[index * 2 * 4], &local->fDebugWorstPts[index * 2 * 4],
                sizeof(SkPoint) * 8);
        fDebugWorstWeight[index * 2] = local->fDebugWorstWeight[index * 2];
        fDebugWorstWeight[index * 2 + 1] = local->fDebugWorstWeight[index * 2 + 1];
    }
    local->debugResetLoopCounts();
}

static void dump_curve(SkPath::Verb verb, const SkPoint& pts, float weight) {
    if (!verb) {
        return;
    }
    const char* verbs[] = { "", "line", "quad", "conic", "cubic" };
    SkDebugf("%s: {{", verbs[verb]);
    int ptCount = SkPathOpsVerbToPoints(verb);
    for (int index = 0; index <= ptCount; ++index) {
        SkDPoint::Dump((&pts)[index]);
        if (index < ptCount - 1) {
            SkDebugf(", ");
        }
    }
    SkDebugf("}");
    if (weight != 1) {
        SkDebugf(", ");
        if (weight == floorf(weight)) {
            SkDebugf("%.0f", weight);
        } else {
            SkDebugf("%1.9gf", weight);
        }
    }
    SkDebugf("}\n");
}

void SkOpGlobalState::debugLoopReport() {
    const char* loops[] = { "iterations", "coinChecks", "perpCalcs" };
    SkDebugf("\n");
    for (int index = 0; index < (int) SK_ARRAY_COUNT(fDebugLoopCount); ++index) {
        SkDebugf("%s: %d\n", loops[index], fDebugLoopCount[index]);
        dump_curve(fDebugWorstVerb[index * 2], fDebugWorstPts[index * 2 * 4],
                fDebugWorstWeight[index * 2]);
        dump_curve(fDebugWorstVerb[index * 2 + 1], fDebugWorstPts[(index * 2 + 1) * 4],
                fDebugWorstWeight[index * 2 + 1]);
    }
}

void SkOpGlobalState::debugResetLoopCounts() {
    sk_bzero(fDebugLoopCount, sizeof(fDebugLoopCount));
    sk_bzero(fDebugWorstVerb, sizeof(fDebugWorstVerb));
    sk_bzero(fDebugWorstPts, sizeof(fDebugWorstPts));
    sk_bzero(fDebugWorstWeight, sizeof(fDebugWorstWeight));
}
#endif

bool SkOpGlobalState::DebugRunFail() {
    return SkPathOpsDebug::gRunFail;
}

// this is const so it can be called by const methods that overwise don't alter state
#if DEBUG_VALIDATE || DEBUG_COIN
void SkOpGlobalState::debugSetPhase(const char* funcName  DEBUG_COIN_DECLARE_PARAMS()) const {
    auto writable = const_cast<SkOpGlobalState*>(this);
#if DEBUG_VALIDATE
    writable->setPhase(phase);
#endif
#if DEBUG_COIN
    SkPathOpsDebug::CoinDictEntry* entry = &writable->fCoinDictEntry;
    writable->fPreviousFuncName = entry->fFunctionName;
    entry->fIteration = iteration;
    entry->fLineNumber = lineNo;
    entry->fGlitchType = SkPathOpsDebug::kUninitialized_Glitch;
    entry->fFunctionName = funcName;
    writable->fCoinVisitedDict.add(*entry);
    writable->debugAddToCoinChangedDict();
#endif
}
#endif

#if DEBUG_T_SECT_LOOP_COUNT
void SkIntersections::debugBumpLoopCount(DebugLoop index) {
    fDebugLoopCount[index]++;
}

int SkIntersections::debugLoopCount(DebugLoop index) const {
    return fDebugLoopCount[index];
}

void SkIntersections::debugResetLoopCount() {
    sk_bzero(fDebugLoopCount, sizeof(fDebugLoopCount));
}
#endif

#include "SkPathOpsConic.h"
#include "SkPathOpsCubic.h"

SkDCubic SkDQuad::debugToCubic() const {
    SkDCubic cubic;
    cubic[0] = fPts[0];
    cubic[2] = fPts[1];
    cubic[3] = fPts[2];
    cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3;
    cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3;
    cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3;
    cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3;
    return cubic;
}

void SkDQuad::debugSet(const SkDPoint* pts) {
    memcpy(fPts, pts, sizeof(fPts));
    SkDEBUGCODE(fDebugGlobalState = nullptr);
}

void SkDCubic::debugSet(const SkDPoint* pts) {
    memcpy(fPts, pts, sizeof(fPts));
    SkDEBUGCODE(fDebugGlobalState = nullptr);
}

void SkDConic::debugSet(const SkDPoint* pts, SkScalar weight) {
    fPts.debugSet(pts);
    fWeight = weight;
}

void SkDRect::debugInit() {
    fLeft = fTop = fRight = fBottom = SK_ScalarNaN;
}

#include "SkOpAngle.h"
#include "SkOpSegment.h"

#if DEBUG_COIN
// commented-out lines keep this in sync with addT()
 const SkOpPtT* SkOpSegment::debugAddT(double t, SkPathOpsDebug::GlitchLog* log) const {
    debugValidate();
    SkPoint pt = this->ptAtT(t);
    const SkOpSpanBase* span = &fHead;
    do {
        const SkOpPtT* result = span->ptT();
        if (t == result->fT || this->match(result, this, t, pt)) {
//             span->bumpSpanAdds();
             return result;
        }
        if (t < result->fT) {
            const SkOpSpan* prev = result->span()->prev();
            FAIL_WITH_NULL_IF(!prev, span);
            // marks in global state that new op span has been allocated
            this->globalState()->setAllocatedOpSpan();
//             span->init(this, prev, t, pt);
            this->debugValidate();
// #if DEBUG_ADD_T
//             SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__, t,
//                     span->segment()->debugID(), span->debugID());
// #endif
//             span->bumpSpanAdds();
            return nullptr;
        }
        FAIL_WITH_NULL_IF(span != &fTail, span);
    } while ((span = span->upCast()->next()));
    SkASSERT(0);
    return nullptr;  // we never get here, but need this to satisfy compiler
}
#endif

#if DEBUG_ANGLE
void SkOpSegment::debugCheckAngleCoin() const {
    const SkOpSpanBase* base = &fHead;
    const SkOpSpan* span;
    do {
        const SkOpAngle* angle = base->fromAngle();
        if (angle && angle->debugCheckCoincidence()) {
            angle->debugCheckNearCoincidence();
        }
        if (base->final()) {
             break;
        }
        span = base->upCast();
        angle = span->toAngle();
        if (angle && angle->debugCheckCoincidence()) {
            angle->debugCheckNearCoincidence();
        }
    } while ((base = span->next()));
}
#endif

#if DEBUG_COIN
// this mimics the order of the checks in handle coincidence
void SkOpSegment::debugCheckHealth(SkPathOpsDebug::GlitchLog* glitches) const {
    debugMoveMultiples(glitches);
    debugMoveNearby(glitches);
    debugMissingCoincidence(glitches);
}

// commented-out lines keep this in sync with clearAll()
void SkOpSegment::debugClearAll(SkPathOpsDebug::GlitchLog* glitches) const {
    const SkOpSpan* span = &fHead;
    do {
        this->debugClearOne(span, glitches);
    } while ((span = span->next()->upCastable()));
    this->globalState()->coincidence()->debugRelease(glitches, this);
}

// commented-out lines keep this in sync with clearOne()
void SkOpSegment::debugClearOne(const SkOpSpan* span, SkPathOpsDebug::GlitchLog* glitches) const {
    if (span->windValue()) glitches->record(SkPathOpsDebug::kCollapsedWindValue_Glitch, span);
    if (span->oppValue()) glitches->record(SkPathOpsDebug::kCollapsedOppValue_Glitch, span);
    if (!span->done()) glitches->record(SkPathOpsDebug::kCollapsedDone_Glitch, span);
}
#endif

SkOpAngle* SkOpSegment::debugLastAngle() {
    SkOpAngle* result = nullptr;
    SkOpSpan* span = this->head();
    do {
        if (span->toAngle()) {
            SkASSERT(!result);
            result = span->toAngle();
        }
    } while ((span = span->next()->upCastable()));
    SkASSERT(result);
    return result;
}

#if DEBUG_COIN
// commented-out lines keep this in sync with ClearVisited
void SkOpSegment::DebugClearVisited(const SkOpSpanBase* span) {
    // reset visited flag back to false
    do {
        const SkOpPtT* ptT = span->ptT(), * stopPtT = ptT;
        while ((ptT = ptT->next()) != stopPtT) {
            const SkOpSegment* opp = ptT->segment();
            opp->resetDebugVisited();
        }
    } while (!span->final() && (span = span->upCast()->next()));
}
#endif

#if DEBUG_COIN
// commented-out lines keep this in sync with missingCoincidence()
// look for pairs of undetected coincident curves
// assumes that segments going in have visited flag clear
// Even though pairs of curves correct detect coincident runs, a run may be missed
// if the coincidence is a product of multiple intersections. For instance, given
// curves A, B, and C:
// A-B intersect at a point 1; A-C and B-C intersect at point 2, so near
// the end of C that the intersection is replaced with the end of C.
// Even though A-B correctly do not detect an intersection at point 2,
// the resulting run from point 1 to point 2 is coincident on A and B.
void SkOpSegment::debugMissingCoincidence(SkPathOpsDebug::GlitchLog* log) const {
    if (this->done()) {
        return;
    }
    const SkOpSpan* prior = nullptr;
    const SkOpSpanBase* spanBase = &fHead;
//    bool result = false;
    do {
        const SkOpPtT* ptT = spanBase->ptT(), * spanStopPtT = ptT;
        SkASSERT(ptT->span() == spanBase);
        while ((ptT = ptT->next()) != spanStopPtT) {
            if (ptT->deleted()) {
                continue;
            }
            const SkOpSegment* opp = ptT->span()->segment();
            if (opp->done()) {
                continue;
            }
            // when opp is encounted the 1st time, continue; on 2nd encounter, look for coincidence
            if (!opp->debugVisited()) {
                continue;
            }
            if (spanBase == &fHead) {
                continue;
            }
            if (ptT->segment() == this) {
                continue;
            }
            const SkOpSpan* span = spanBase->upCastable();
            // FIXME?: this assumes that if the opposite segment is coincident then no more
            // coincidence needs to be detected. This may not be true.
            if (span && span->segment() != opp && span->containsCoincidence(opp)) {  // debug has additional condition since it may be called before inner duplicate points have been deleted
                continue;
            }
            if (spanBase->segment() != opp && spanBase->containsCoinEnd(opp)) {  // debug has additional condition since it may be called before inner duplicate points have been deleted
                continue;
            }
            const SkOpPtT* priorPtT = nullptr, * priorStopPtT;
            // find prior span containing opp segment
            const SkOpSegment* priorOpp = nullptr;
            const SkOpSpan* priorTest = spanBase->prev();
            while (!priorOpp && priorTest) {
                priorStopPtT = priorPtT = priorTest->ptT();
                while ((priorPtT = priorPtT->next()) != priorStopPtT) {
                    if (priorPtT->deleted()) {
                        continue;
                    }
                    const SkOpSegment* segment = priorPtT->span()->segment();
                    if (segment == opp) {
                        prior = priorTest;
                        priorOpp = opp;
                        break;
                    }
                }
                priorTest = priorTest->prev();
            }
            if (!priorOpp) {
                continue;
            }
            if (priorPtT == ptT) {
                continue;
            }
            const SkOpPtT* oppStart = prior->ptT();
            const SkOpPtT* oppEnd = spanBase->ptT();
            bool swapped = priorPtT->fT > ptT->fT;
            if (swapped) {
                using std::swap;
                swap(priorPtT, ptT);
                swap(oppStart, oppEnd);
            }
            const SkOpCoincidence* coincidence = this->globalState()->coincidence();
            const SkOpPtT* rootPriorPtT = priorPtT->span()->ptT();
            const SkOpPtT* rootPtT = ptT->span()->ptT();
            const SkOpPtT* rootOppStart = oppStart->span()->ptT();
            const SkOpPtT* rootOppEnd = oppEnd->span()->ptT();
            if (coincidence->contains(rootPriorPtT, rootPtT, rootOppStart, rootOppEnd)) {
                goto swapBack;
            }
            if (testForCoincidence(rootPriorPtT, rootPtT, prior, spanBase, opp)) {
            // mark coincidence
#if DEBUG_COINCIDENCE_VERBOSE
//                 SkDebugf("%s coinSpan=%d endSpan=%d oppSpan=%d oppEndSpan=%d\n", __FUNCTION__,
//                         rootPriorPtT->debugID(), rootPtT->debugID(), rootOppStart->debugID(),
//                         rootOppEnd->debugID());
#endif
                log->record(SkPathOpsDebug::kMissingCoin_Glitch, priorPtT, ptT, oppStart, oppEnd);
                //   coincidences->add(rootPriorPtT, rootPtT, rootOppStart, rootOppEnd);
                // }
#if DEBUG_COINCIDENCE
//                SkASSERT(coincidences->contains(rootPriorPtT, rootPtT, rootOppStart, rootOppEnd);
#endif
                // result = true;
            }
    swapBack:
            if (swapped) {
                using std::swap;
                swap(priorPtT, ptT);
            }
        }
    } while ((spanBase = spanBase->final() ? nullptr : spanBase->upCast()->next()));
    DebugClearVisited(&fHead);
    return;
}

// commented-out lines keep this in sync with moveMultiples()
// if a span has more than one intersection, merge the other segments' span as needed
void SkOpSegment::debugMoveMultiples(SkPathOpsDebug::GlitchLog* glitches) const {
    debugValidate();
    const SkOpSpanBase* test = &fHead;
    do {
        int addCount = test->spanAddsCount();
//        SkASSERT(addCount >= 1);
        if (addCount <= 1) {
            continue;
        }
        const SkOpPtT* startPtT = test->ptT();
        const SkOpPtT* testPtT = startPtT;
        do {  // iterate through all spans associated with start
            const SkOpSpanBase* oppSpan = testPtT->span();
            if (oppSpan->spanAddsCount() == addCount) {
                continue;
            }
            if (oppSpan->deleted()) {
                continue;
            }
            const SkOpSegment* oppSegment = oppSpan->segment();
            if (oppSegment == this) {
                continue;
            }
            // find range of spans to consider merging
            const SkOpSpanBase* oppPrev = oppSpan;
            const SkOpSpanBase* oppFirst = oppSpan;
            while ((oppPrev = oppPrev->prev())) {
                if (!roughly_equal(oppPrev->t(), oppSpan->t())) {
                    break;
                }
                if (oppPrev->spanAddsCount() == addCount) {
                    continue;
                }
                if (oppPrev->deleted()) {
                    continue;
                }
                oppFirst = oppPrev;
            }
            const SkOpSpanBase* oppNext = oppSpan;
            const SkOpSpanBase* oppLast = oppSpan;
            while ((oppNext = oppNext->final() ? nullptr : oppNext->upCast()->next())) {
                if (!roughly_equal(oppNext->t(), oppSpan->t())) {
                    break;
                }
                if (oppNext->spanAddsCount() == addCount) {
                    continue;
                }
                if (oppNext->deleted()) {
                    continue;
                }
                oppLast = oppNext;
            }
            if (oppFirst == oppLast) {
                continue;
            }
            const SkOpSpanBase* oppTest = oppFirst;
            do {
                if (oppTest == oppSpan) {
                    continue;
                }
                // check to see if the candidate meets specific criteria:
                // it contains spans of segments in test's loop but not including 'this'
                const SkOpPtT* oppStartPtT = oppTest->ptT();
                const SkOpPtT* oppPtT = oppStartPtT;
                while ((oppPtT = oppPtT->next()) != oppStartPtT) {
                    const SkOpSegment* oppPtTSegment = oppPtT->segment();
                    if (oppPtTSegment == this) {
                        goto tryNextSpan;
                    }
                    const SkOpPtT* matchPtT = startPtT;
                    do {
                        if (matchPtT->segment() == oppPtTSegment) {
                            goto foundMatch;
                        }
                    } while ((matchPtT = matchPtT->next()) != startPtT);
                    goto tryNextSpan;
            foundMatch:  // merge oppTest and oppSpan
                    oppSegment->debugValidate();
                    oppTest->debugMergeMatches(glitches, oppSpan);
                    oppTest->debugAddOpp(glitches, oppSpan);
                    oppSegment->debugValidate();
                    goto checkNextSpan;
                }
        tryNextSpan:
                ;
            } while (oppTest != oppLast && (oppTest = oppTest->upCast()->next()));
        } while ((testPtT = testPtT->next()) != startPtT);
checkNextSpan:
        ;
    } while ((test = test->final() ? nullptr : test->upCast()->next()));
   debugValidate();
   return;
}

// commented-out lines keep this in sync with moveNearby()
// Move nearby t values and pts so they all hang off the same span. Alignment happens later.
void SkOpSegment::debugMoveNearby(SkPathOpsDebug::GlitchLog* glitches) const {
    debugValidate();
    // release undeleted spans pointing to this seg that are linked to the primary span
    const SkOpSpanBase* spanBase = &fHead;
    do {
        const SkOpPtT* ptT = spanBase->ptT();
        const SkOpPtT* headPtT = ptT;
        while ((ptT = ptT->next()) != headPtT) {
              const SkOpSpanBase* test = ptT->span();
            if (ptT->segment() == this && !ptT->deleted() && test != spanBase
                    && test->ptT() == ptT) {
                if (test->final()) {
                    if (spanBase == &fHead) {
                        glitches->record(SkPathOpsDebug::kMoveNearbyClearAll_Glitch, this);
//                        return;
                    }
                    glitches->record(SkPathOpsDebug::kMoveNearbyReleaseFinal_Glitch, spanBase, ptT);
                } else if (test->prev()) {
                    glitches->record(SkPathOpsDebug::kMoveNearbyRelease_Glitch, test, headPtT);
                }
//                break;
            }
        }
        spanBase = spanBase->upCast()->next();
    } while (!spanBase->final());

    // This loop looks for adjacent spans which are near by
    spanBase = &fHead;
    do {  // iterate through all spans associated with start
        const SkOpSpanBase* test = spanBase->upCast()->next();
        bool found;
        if (!this->spansNearby(spanBase, test, &found)) {
            glitches->record(SkPathOpsDebug::kMoveNearbyMergeFinal_Glitch, test);
        }
        if (found) {
            if (test->final()) {
                if (spanBase->prev()) {
                    glitches->record(SkPathOpsDebug::kMoveNearbyMergeFinal_Glitch, test);
                } else {
                    glitches->record(SkPathOpsDebug::kMoveNearbyClearAll2_Glitch, this);
                    // return
                }
            } else {
                glitches->record(SkPathOpsDebug::kMoveNearbyMerge_Glitch, spanBase);
            }
        }
        spanBase = test;
    } while (!spanBase->final());
    debugValidate();
}
#endif

void SkOpSegment::debugReset() {
    this->init(this->fPts, this->fWeight, this->contour(), this->verb());
}

#if DEBUG_COINCIDENCE_ORDER
void SkOpSegment::debugSetCoinT(int index, SkScalar t) const {
    if (fDebugBaseMax < 0 || fDebugBaseIndex == index) {
        fDebugBaseIndex = index;
        fDebugBaseMin = SkTMin(t, fDebugBaseMin);
        fDebugBaseMax = SkTMax(t, fDebugBaseMax);
        return;
    }
    SkASSERT(fDebugBaseMin >= t || t >= fDebugBaseMax);
    if (fDebugLastMax < 0 || fDebugLastIndex == index) {
        fDebugLastIndex = index;
        fDebugLastMin = SkTMin(t, fDebugLastMin);
        fDebugLastMax = SkTMax(t, fDebugLastMax);
        return;
    }
    SkASSERT(fDebugLastMin >= t || t >= fDebugLastMax);
    SkASSERT((t - fDebugBaseMin > 0) == (fDebugLastMin - fDebugBaseMin > 0));
}
#endif

#if DEBUG_ACTIVE_SPANS
void SkOpSegment::debugShowActiveSpans(SkString* str) const {
    debugValidate();
    if (done()) {
        return;
    }
    int lastId = -1;
    double lastT = -1;
    const SkOpSpan* span = &fHead;
    do {
        if (span->done()) {
            continue;
        }
        if (lastId == this->debugID() && lastT == span->t()) {
            continue;
        }
        lastId = this->debugID();
        lastT = span->t();
        str->appendf("%s id=%d", __FUNCTION__, this->debugID());
        // since endpoints may have be adjusted, show actual computed curves
        SkDCurve curvePart;
        this->subDivide(span, span->next(), &curvePart);
        const SkDPoint* pts = curvePart.fCubic.fPts;
        str->appendf(" (%1.9g,%1.9g", pts[0].fX, pts[0].fY);
        for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
            str->appendf(" %1.9g,%1.9g", pts[vIndex].fX, pts[vIndex].fY);
        }
        if (SkPath::kConic_Verb == fVerb) {
            str->appendf(" %1.9gf", curvePart.fConic.fWeight);
        }
        str->appendf(") t=%1.9g tEnd=%1.9g", span->t(), span->next()->t());
        if (span->windSum() == SK_MinS32) {
            str->appendf(" windSum=?");
        } else {
            str->appendf(" windSum=%d", span->windSum());
        }
        if (span->oppValue() && span->oppSum() == SK_MinS32) {
            str->appendf(" oppSum=?");
        } else if (span->oppValue() || span->oppSum() != SK_MinS32) {
            str->appendf(" oppSum=%d", span->oppSum());
        }
        str->appendf(" windValue=%d", span->windValue());
        if (span->oppValue() || span->oppSum() != SK_MinS32) {
            str->appendf(" oppValue=%d", span->oppValue());
        }
        str->appendf("\n");
   } while ((span = span->next()->upCastable()));
}
#endif

#if DEBUG_MARK_DONE
void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding) {
    const SkPoint& pt = span->ptT()->fPt;
    SkDebugf("%s id=%d", fun, this->debugID());
    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
    }
    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
            span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t());
    if (winding == SK_MinS32) {
        SkDebugf("?");
    } else {
        SkDebugf("%d", winding);
    }
    SkDebugf(" windSum=");
    if (span->windSum() == SK_MinS32) {
        SkDebugf("?");
    } else {
        SkDebugf("%d", span->windSum());
    }
    SkDebugf(" windValue=%d\n", span->windValue());
}

void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding,
                                      int oppWinding) {
    const SkPoint& pt = span->ptT()->fPt;
    SkDebugf("%s id=%d", fun, this->debugID());
    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
    }
    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
            span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t(), winding, oppWinding);
    if (winding == SK_MinS32) {
        SkDebugf("?");
    } else {
        SkDebugf("%d", winding);
    }
    SkDebugf(" newOppSum=");
    if (oppWinding == SK_MinS32) {
        SkDebugf("?");
    } else {
        SkDebugf("%d", oppWinding);
    }
    SkDebugf(" oppSum=");
    if (span->oppSum() == SK_MinS32) {
        SkDebugf("?");
    } else {
        SkDebugf("%d", span->oppSum());
    }
    SkDebugf(" windSum=");
    if (span->windSum() == SK_MinS32) {
        SkDebugf("?");
    } else {
        SkDebugf("%d", span->windSum());
    }
    SkDebugf(" windValue=%d oppValue=%d\n", span->windValue(), span->oppValue());
}

#endif

// loop looking for a pair of angle parts that are too close to be sorted
/* This is called after other more simple intersection and angle sorting tests have been exhausted.
   This should be rarely called -- the test below is thorough and time consuming.
   This checks the distance between start points; the distance between
*/
#if DEBUG_ANGLE
void SkOpAngle::debugCheckNearCoincidence() const {
    const SkOpAngle* test = this;
    do {
        const SkOpSegment* testSegment = test->segment();
        double testStartT = test->start()->t();
        SkDPoint testStartPt = testSegment->dPtAtT(testStartT);
        double testEndT = test->end()->t();
        SkDPoint testEndPt = testSegment->dPtAtT(testEndT);
        double testLenSq = testStartPt.distanceSquared(testEndPt);
        SkDebugf("%s testLenSq=%1.9g id=%d\n", __FUNCTION__, testLenSq, testSegment->debugID());
        double testMidT = (testStartT + testEndT) / 2;
        const SkOpAngle* next = test;
        while ((next = next->fNext) != this) {
            SkOpSegment* nextSegment = next->segment();
            double testMidDistSq = testSegment->distSq(testMidT, next);
            double testEndDistSq = testSegment->distSq(testEndT, next);
            double nextStartT = next->start()->t();
            SkDPoint nextStartPt = nextSegment->dPtAtT(nextStartT);
            double distSq = testStartPt.distanceSquared(nextStartPt);
            double nextEndT = next->end()->t();
            double nextMidT = (nextStartT + nextEndT) / 2;
            double nextMidDistSq = nextSegment->distSq(nextMidT, test);
            double nextEndDistSq = nextSegment->distSq(nextEndT, test);
            SkDebugf("%s distSq=%1.9g testId=%d nextId=%d\n", __FUNCTION__, distSq,
                    testSegment->debugID(), nextSegment->debugID());
            SkDebugf("%s testMidDistSq=%1.9g\n", __FUNCTION__, testMidDistSq);
            SkDebugf("%s testEndDistSq=%1.9g\n", __FUNCTION__, testEndDistSq);
            SkDebugf("%s nextMidDistSq=%1.9g\n", __FUNCTION__, nextMidDistSq);
            SkDebugf("%s nextEndDistSq=%1.9g\n", __FUNCTION__, nextEndDistSq);
            SkDPoint nextEndPt = nextSegment->dPtAtT(nextEndT);
            double nextLenSq = nextStartPt.distanceSquared(nextEndPt);
            SkDebugf("%s nextLenSq=%1.9g\n", __FUNCTION__, nextLenSq);
            SkDebugf("\n");
        }
        test = test->fNext;
    } while (test->fNext != this);
}
#endif

#if DEBUG_ANGLE
SkString SkOpAngle::debugPart() const {
    SkString result;
    switch (this->segment()->verb()) {
        case SkPath::kLine_Verb:
            result.printf(LINE_DEBUG_STR " id=%d", LINE_DEBUG_DATA(fPart.fCurve),
                    this->segment()->debugID());
            break;
        case SkPath::kQuad_Verb:
            result.printf(QUAD_DEBUG_STR " id=%d", QUAD_DEBUG_DATA(fPart.fCurve),
                    this->segment()->debugID());
            break;
        case SkPath::kConic_Verb:
            result.printf(CONIC_DEBUG_STR " id=%d",
                    CONIC_DEBUG_DATA(fPart.fCurve, fPart.fCurve.fConic.fWeight),
                    this->segment()->debugID());
            break;
        case SkPath::kCubic_Verb:
            result.printf(CUBIC_DEBUG_STR " id=%d", CUBIC_DEBUG_DATA(fPart.fCurve),
                    this->segment()->debugID());
            break;
        default:
            SkASSERT(0);
    }
    return result;
}
#endif

#if DEBUG_SORT
void SkOpAngle::debugLoop() const {
    const SkOpAngle* first = this;
    const SkOpAngle* next = this;
    do {
        next->dumpOne(true);
        SkDebugf("\n");
        next = next->fNext;
    } while (next && next != first);
    next = first;
    do {
        next->debugValidate();
        next = next->fNext;
    } while (next && next != first);
}
#endif

void SkOpAngle::debugValidate() const {
#if DEBUG_COINCIDENCE
    if (this->globalState()->debugCheckHealth()) {
        return;
    }
#endif
#if DEBUG_VALIDATE
    const SkOpAngle* first = this;
    const SkOpAngle* next = this;
    int wind = 0;
    int opp = 0;
    int lastXor = -1;
    int lastOppXor = -1;
    do {
        if (next->unorderable()) {
            return;
        }
        const SkOpSpan* minSpan = next->start()->starter(next->end());
        if (minSpan->windValue() == SK_MinS32) {
            return;
        }
        bool op = next->segment()->operand();
        bool isXor = next->segment()->isXor();
        bool oppXor = next->segment()->oppXor();
        SkASSERT(!DEBUG_LIMIT_WIND_SUM || between(0, minSpan->windValue(), DEBUG_LIMIT_WIND_SUM));
        SkASSERT(!DEBUG_LIMIT_WIND_SUM
                || between(-DEBUG_LIMIT_WIND_SUM, minSpan->oppValue(), DEBUG_LIMIT_WIND_SUM));
        bool useXor = op ? oppXor : isXor;
        SkASSERT(lastXor == -1 || lastXor == (int) useXor);
        lastXor = (int) useXor;
        wind += next->debugSign() * (op ? minSpan->oppValue() : minSpan->windValue());
        if (useXor) {
            wind &= 1;
        }
        useXor = op ? isXor : oppXor;
        SkASSERT(lastOppXor == -1 || lastOppXor == (int) useXor);
        lastOppXor = (int) useXor;
        opp += next->debugSign() * (op ? minSpan->windValue() : minSpan->oppValue());
        if (useXor) {
            opp &= 1;
        }
        next = next->fNext;
    } while (next && next != first);
    SkASSERT(wind == 0 || !SkPathOpsDebug::gRunFail);
    SkASSERT(opp == 0 || !SkPathOpsDebug::gRunFail);
#endif
}

void SkOpAngle::debugValidateNext() const {
#if !FORCE_RELEASE
    const SkOpAngle* first = this;
    const SkOpAngle* next = first;
    SkTDArray<const SkOpAngle*>(angles);
    do {
//        SkASSERT_RELEASE(next->fSegment->debugContains(next));
        angles.push(next);
        next = next->next();
        if (next == first) {
            break;
        }
        SkASSERT_RELEASE(!angles.contains(next));
        if (!next) {
            return;
        }
    } while (true);
#endif
}

#ifdef SK_DEBUG
void SkCoincidentSpans::debugStartCheck(const SkOpSpanBase* outer, const SkOpSpanBase* over,
        const SkOpGlobalState* debugState) const {
    SkASSERT(coinPtTEnd()->span() == over || !SkOpGlobalState::DebugRunFail());
    SkASSERT(oppPtTEnd()->span() == outer || !SkOpGlobalState::DebugRunFail());
}
#endif

#if DEBUG_COIN
// sets the span's end to the ptT referenced by the previous-next
void SkCoincidentSpans::debugCorrectOneEnd(SkPathOpsDebug::GlitchLog* log,
        const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
        void (SkCoincidentSpans::*setEnd)(const SkOpPtT* ptT) const ) const {
    const SkOpPtT* origPtT = (this->*getEnd)();
    const SkOpSpanBase* origSpan = origPtT->span();
    const SkOpSpan* prev = origSpan->prev();
    const SkOpPtT* testPtT = prev ? prev->next()->ptT()
            : origSpan->upCast()->next()->prev()->ptT();
    if (origPtT != testPtT) {
        log->record(SkPathOpsDebug::kCorrectEnd_Glitch, this, origPtT, testPtT);
    }
}


/* Commented-out lines keep this in sync with correctEnds */
// FIXME: member pointers have fallen out of favor and can be replaced with
// an alternative approach.
// makes all span ends agree with the segment's spans that define them
void SkCoincidentSpans::debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const {
    this->debugCorrectOneEnd(log, &SkCoincidentSpans::coinPtTStart, nullptr);
    this->debugCorrectOneEnd(log, &SkCoincidentSpans::coinPtTEnd, nullptr);
    this->debugCorrectOneEnd(log, &SkCoincidentSpans::oppPtTStart, nullptr);
    this->debugCorrectOneEnd(log, &SkCoincidentSpans::oppPtTEnd, nullptr);
}

/* Commented-out lines keep this in sync with expand */
// expand the range by checking adjacent spans for coincidence
bool SkCoincidentSpans::debugExpand(SkPathOpsDebug::GlitchLog* log) const {
    bool expanded = false;
    const SkOpSegment* segment = coinPtTStart()->segment();
    const SkOpSegment* oppSegment = oppPtTStart()->segment();
    do {
        const SkOpSpan* start = coinPtTStart()->span()->upCast();
        const SkOpSpan* prev = start->prev();
        const SkOpPtT* oppPtT;
        if (!prev || !(oppPtT = prev->contains(oppSegment))) {
            break;
        }
        double midT = (prev->t() + start->t()) / 2;
        if (!segment->isClose(midT, oppSegment)) {
            break;
        }
        if (log) log->record(SkPathOpsDebug::kExpandCoin_Glitch, this, prev->ptT(), oppPtT);
        expanded = true;
    } while (false);  // actual continues while expansion is possible
    do {
        const SkOpSpanBase* end = coinPtTEnd()->span();
        SkOpSpanBase* next = end->final() ? nullptr : end->upCast()->next();
        if (next && next->deleted()) {
            break;
        }
        const SkOpPtT* oppPtT;
        if (!next || !(oppPtT = next->contains(oppSegment))) {
            break;
        }
        double midT = (end->t() + next->t()) / 2;
        if (!segment->isClose(midT, oppSegment)) {
            break;
        }
        if (log) log->record(SkPathOpsDebug::kExpandCoin_Glitch, this, next->ptT(), oppPtT);
        expanded = true;
    } while (false);  // actual continues while expansion is possible
    return expanded;
}

// description below
void SkOpCoincidence::debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* log, const SkOpSpan* base, const SkOpSpanBase* testSpan) const {
    const SkOpPtT* testPtT = testSpan->ptT();
    const SkOpPtT* stopPtT = testPtT;
    const SkOpSegment* baseSeg = base->segment();
    while ((testPtT = testPtT->next()) != stopPtT) {
        const SkOpSegment* testSeg = testPtT->segment();
        if (testPtT->deleted()) {
            continue;
        }
        if (testSeg == baseSeg) {
            continue;
        }
        if (testPtT->span()->ptT() != testPtT) {
            continue;
        }
        if (this->contains(baseSeg, testSeg, testPtT->fT)) {
            continue;
        }
        // intersect perp with base->ptT() with testPtT->segment()
        SkDVector dxdy = baseSeg->dSlopeAtT(base->t());
        const SkPoint& pt = base->pt();
        SkDLine ray = {{{pt.fX, pt.fY}, {pt.fX + dxdy.fY, pt.fY - dxdy.fX}}};
        SkIntersections i;
        (*CurveIntersectRay[testSeg->verb()])(testSeg->pts(), testSeg->weight(), ray, &i);
        for (int index = 0; index < i.used(); ++index) {
            double t = i[0][index];
            if (!between(0, t, 1)) {
                continue;
            }
            SkDPoint oppPt = i.pt(index);
            if (!oppPt.approximatelyEqual(pt)) {
                continue;
            }
            SkOpSegment* writableSeg = const_cast<SkOpSegment*>(testSeg);
            SkOpPtT* oppStart = writableSeg->addT(t);
            if (oppStart == testPtT) {
                continue;
            }
            SkOpSpan* writableBase = const_cast<SkOpSpan*>(base);
            oppStart->span()->addOpp(writableBase);
            if (oppStart->deleted()) {
                continue;
            }
            SkOpSegment* coinSeg = base->segment();
            SkOpSegment* oppSeg = oppStart->segment();
            double coinTs, coinTe, oppTs, oppTe;
            if (Ordered(coinSeg, oppSeg)) {
                coinTs = base->t();
                coinTe = testSpan->t();
                oppTs = oppStart->fT;
                oppTe = testPtT->fT;
            } else {
                using std::swap;
                swap(coinSeg, oppSeg);
                coinTs = oppStart->fT;
                coinTe = testPtT->fT;
                oppTs = base->t();
                oppTe = testSpan->t();
            }
            if (coinTs > coinTe) {
                using std::swap;
                swap(coinTs, coinTe);
                swap(oppTs, oppTe);
            }
            bool added;
            if (this->debugAddOrOverlap(log, coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe, &added), false) {
                return;
            }
        }
    }
    return;
}

// description below
void SkOpCoincidence::debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* log, const SkOpPtT* ptT) const {
    FAIL_IF(!ptT->span()->upCastable(), ptT->span());
    const SkOpSpan* base = ptT->span()->upCast();
    const SkOpSpan* prev = base->prev();
    FAIL_IF(!prev, ptT->span());
    if (!prev->isCanceled()) {
        if (this->debugAddEndMovedSpans(log, base, base->prev()), false) {
            return;
        }
    }
    if (!base->isCanceled()) {
        if (this->debugAddEndMovedSpans(log, base, base->next()), false) {
            return;
        }
    }
    return;
}

/*  If A is coincident with B and B includes an endpoint, and A's matching point
    is not the endpoint (i.e., there's an implied line connecting B-end and A)
    then assume that the same implied line may intersect another curve close to B.
    Since we only care about coincidence that was undetected, look at the
    ptT list on B-segment adjacent to the B-end/A ptT loop (not in the loop, but
    next door) and see if the A matching point is close enough to form another
    coincident pair. If so, check for a new coincident span between B-end/A ptT loop
    and the adjacent ptT loop.
*/
void SkOpCoincidence::debugAddEndMovedSpans(SkPathOpsDebug::GlitchLog* log) const {
    const SkCoincidentSpans* span = fHead;
    if (!span) {
        return;
    }
//    fTop = span;
//    fHead = nullptr;
    do {
        if (span->coinPtTStart()->fPt != span->oppPtTStart()->fPt) {
            FAIL_IF(1 == span->coinPtTStart()->fT, span);
            bool onEnd = span->coinPtTStart()->fT == 0;
            bool oOnEnd = zero_or_one(span->oppPtTStart()->fT);
            if (onEnd) {
                if (!oOnEnd) {  // if both are on end, any nearby intersect was already found
                    if (this->debugAddEndMovedSpans(log, span->oppPtTStart()), false) {
                        return;
                    }
                }
            } else if (oOnEnd) {
                if (this->debugAddEndMovedSpans(log, span->coinPtTStart()), false) {
                    return;
                }
            }
        }
        if (span->coinPtTEnd()->fPt != span->oppPtTEnd()->fPt) {
            bool onEnd = span->coinPtTEnd()->fT == 1;
            bool oOnEnd = zero_or_one(span->oppPtTEnd()->fT);
            if (onEnd) {
                if (!oOnEnd) {
                    if (this->debugAddEndMovedSpans(log, span->oppPtTEnd()), false) {
                        return;
                    }
                }
            } else if (oOnEnd) {
                if (this->debugAddEndMovedSpans(log, span->coinPtTEnd()), false) {
                    return;
                }
            }
        }
    } while ((span = span->next()));
//    this->restoreHead();
    return;
}

/* Commented-out lines keep this in sync with addExpanded */
// for each coincident pair, match the spans
// if the spans don't match, add the mssing pt to the segment and loop it in the opposite span
void SkOpCoincidence::debugAddExpanded(SkPathOpsDebug::GlitchLog* log) const {
//    DEBUG_SET_PHASE();
    const SkCoincidentSpans* coin = this->fHead;
    if (!coin) {
        return;
    }
    do {
        const SkOpPtT* startPtT = coin->coinPtTStart();
        const SkOpPtT* oStartPtT = coin->oppPtTStart();
        double priorT = startPtT->fT;
        double oPriorT = oStartPtT->fT;
        FAIL_IF(!startPtT->contains(oStartPtT), coin);
        SkOPASSERT(coin->coinPtTEnd()->contains(coin->oppPtTEnd()));
        const SkOpSpanBase* start = startPtT->span();
        const SkOpSpanBase* oStart = oStartPtT->span();
        const SkOpSpanBase* end = coin->coinPtTEnd()->span();
        const SkOpSpanBase* oEnd = coin->oppPtTEnd()->span();
        FAIL_IF(oEnd->deleted(), coin);
        FAIL_IF(!start->upCastable(), coin);
        const SkOpSpanBase* test = start->upCast()->next();
        FAIL_IF(!coin->flipped() && !oStart->upCastable(), coin);
        const SkOpSpanBase* oTest = coin->flipped() ? oStart->prev() : oStart->upCast()->next();
        FAIL_IF(!oTest, coin);
        const SkOpSegment* seg = start->segment();
        const SkOpSegment* oSeg = oStart->segment();
        while (test != end || oTest != oEnd) {
            const SkOpPtT* containedOpp = test->ptT()->contains(oSeg);
            const SkOpPtT* containedThis = oTest->ptT()->contains(seg);
            if (!containedOpp || !containedThis) {
                // choose the ends, or the first common pt-t list shared by both
                double nextT, oNextT;
                if (containedOpp) {
                    nextT = test->t();
                    oNextT = containedOpp->fT;
                } else if (containedThis) {
                    nextT = containedThis->fT;
                    oNextT = oTest->t();
                } else {
                    // iterate through until a pt-t list found that contains the other
                    const SkOpSpanBase* walk = test;
                    const SkOpPtT* walkOpp;
                    do {
                        FAIL_IF(!walk->upCastable(), coin);
                        walk = walk->upCast()->next();
                    } while (!(walkOpp = walk->ptT()->contains(oSeg))
                            && walk != coin->coinPtTEnd()->span());
                    FAIL_IF(!walkOpp, coin);
                    nextT = walk->t();
                    oNextT = walkOpp->fT;
                }
                // use t ranges to guess which one is missing
                double startRange = nextT - priorT;
                FAIL_IF(!startRange, coin);
                double startPart = (test->t() - priorT) / startRange;
                double oStartRange = oNextT - oPriorT;
                FAIL_IF(!oStartRange, coin);
                double oStartPart = (oTest->t() - oStartPtT->fT) / oStartRange;
                FAIL_IF(startPart == oStartPart, coin);
                bool addToOpp = !containedOpp && !containedThis ? startPart < oStartPart
                        : !!containedThis;
                bool startOver = false;
                addToOpp ? log->record(SkPathOpsDebug::kAddExpandedCoin_Glitch,
                        oPriorT + oStartRange * startPart, test)
                        : log->record(SkPathOpsDebug::kAddExpandedCoin_Glitch,
                        priorT + startRange * oStartPart, oTest);
         //       FAIL_IF(!success, coin);
                if (startOver) {
                    test = start;
                    oTest = oStart;
                }
                end = coin->coinPtTEnd()->span();
                oEnd = coin->oppPtTEnd()->span();
            }
            if (test != end) {
                FAIL_IF(!test->upCastable(), coin);
                priorT = test->t();
                test = test->upCast()->next();
            }
            if (oTest != oEnd) {
                oPriorT = oTest->t();
                oTest = coin->flipped() ? oTest->prev() : oTest->upCast()->next();
                FAIL_IF(!oTest, coin);
            }
        }
    } while ((coin = coin->next()));
    return;
}

/* Commented-out lines keep this in sync addIfMissing() */
// note that over1s, over1e, over2s, over2e are ordered
void SkOpCoincidence::debugAddIfMissing(SkPathOpsDebug::GlitchLog* log, const SkOpPtT* over1s, const SkOpPtT* over2s,
        double tStart, double tEnd, const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, bool* added,
        const SkOpPtT* over1e, const SkOpPtT* over2e) const {
    SkASSERT(tStart < tEnd);
    SkASSERT(over1s->fT < over1e->fT);
    SkASSERT(between(over1s->fT, tStart, over1e->fT));
    SkASSERT(between(over1s->fT, tEnd, over1e->fT));
    SkASSERT(over2s->fT < over2e->fT);
    SkASSERT(between(over2s->fT, tStart, over2e->fT));
    SkASSERT(between(over2s->fT, tEnd, over2e->fT));
    SkASSERT(over1s->segment() == over1e->segment());
    SkASSERT(over2s->segment() == over2e->segment());
    SkASSERT(over1s->segment() == over2s->segment());
    SkASSERT(over1s->segment() != coinSeg);
    SkASSERT(over1s->segment() != oppSeg);
    SkASSERT(coinSeg != oppSeg);
    double coinTs, coinTe, oppTs, oppTe;
    coinTs = TRange(over1s, tStart, coinSeg  SkDEBUGPARAMS(over1e));
    coinTe = TRange(over1s, tEnd, coinSeg  SkDEBUGPARAMS(over1e));
    SkOpSpanBase::Collapsed result = coinSeg->collapsed(coinTs, coinTe);
    if (SkOpSpanBase::Collapsed::kNo != result) {
        return log->record(SkPathOpsDebug::kAddIfCollapsed_Glitch, coinSeg);
    }
    oppTs = TRange(over2s, tStart, oppSeg  SkDEBUGPARAMS(over2e));
    oppTe = TRange(over2s, tEnd, oppSeg  SkDEBUGPARAMS(over2e));
    result = oppSeg->collapsed(oppTs, oppTe);
    if (SkOpSpanBase::Collapsed::kNo != result) {
        return log->record(SkPathOpsDebug::kAddIfCollapsed_Glitch, oppSeg);
    }
    if (coinTs > coinTe) {
        using std::swap;
        swap(coinTs, coinTe);
        swap(oppTs, oppTe);
    }
    this->debugAddOrOverlap(log, coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe, added);
    return;
}

/* Commented-out lines keep this in sync addOrOverlap() */
// If this is called by addEndMovedSpans(), a returned false propogates out to an abort.
// If this is called by AddIfMissing(), a returned false indicates there was nothing to add
void SkOpCoincidence::debugAddOrOverlap(SkPathOpsDebug::GlitchLog* log,
        const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
        double coinTs, double coinTe, double oppTs, double oppTe, bool* added) const {
    SkTDArray<SkCoincidentSpans*> overlaps;
    SkOPASSERT(!fTop);   // this is (correctly) reversed in addifMissing()
    if (fTop && !this->checkOverlap(fTop, coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe,
            &overlaps)) {
        return;
    }
    if (fHead && !this->checkOverlap(fHead, coinSeg, oppSeg, coinTs,
            coinTe, oppTs, oppTe, &overlaps)) {
        return;
    }
    const SkCoincidentSpans* overlap = overlaps.count() ? overlaps[0] : nullptr;
    for (int index = 1; index < overlaps.count(); ++index) { // combine overlaps before continuing
        const SkCoincidentSpans* test = overlaps[index];
        if (overlap->coinPtTStart()->fT > test->coinPtTStart()->fT) {
            log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->coinPtTStart());
        }
        if (overlap->coinPtTEnd()->fT < test->coinPtTEnd()->fT) {
            log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->coinPtTEnd());
        }
        if (overlap->flipped()
                ? overlap->oppPtTStart()->fT < test->oppPtTStart()->fT
                : overlap->oppPtTStart()->fT > test->oppPtTStart()->fT) {
            log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->oppPtTStart());
        }
        if (overlap->flipped()
                ? overlap->oppPtTEnd()->fT > test->oppPtTEnd()->fT
                : overlap->oppPtTEnd()->fT < test->oppPtTEnd()->fT) {
            log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->oppPtTEnd());
        }
        if (!fHead) { this->debugRelease(log, fHead, test);
            this->debugRelease(log, fTop, test);
        }
    }
    const SkOpPtT* cs = coinSeg->existing(coinTs, oppSeg);
    const SkOpPtT* ce = coinSeg->existing(coinTe, oppSeg);
    RETURN_FALSE_IF(overlap && cs && ce && overlap->contains(cs, ce), coinSeg);
    RETURN_FALSE_IF(cs != ce || !cs, coinSeg);
    const SkOpPtT* os = oppSeg->existing(oppTs, coinSeg);
    const SkOpPtT* oe = oppSeg->existing(oppTe, coinSeg);
    RETURN_FALSE_IF(overlap && os && oe && overlap->contains(os, oe), oppSeg);
    SkASSERT(true || !cs || !cs->deleted());
    SkASSERT(true || !os || !os->deleted());
    SkASSERT(true || !ce || !ce->deleted());
    SkASSERT(true || !oe || !oe->deleted());
    const SkOpPtT* csExisting = !cs ? coinSeg->existing(coinTs, nullptr) : nullptr;
    const SkOpPtT* ceExisting = !ce ? coinSeg->existing(coinTe, nullptr) : nullptr;
    RETURN_FALSE_IF(csExisting && csExisting == ceExisting, coinSeg);
    RETURN_FALSE_IF(csExisting && (csExisting == ce ||
            csExisting->contains(ceExisting ? ceExisting : ce)), coinSeg);
    RETURN_FALSE_IF(ceExisting && (ceExisting == cs ||
            ceExisting->contains(csExisting ? csExisting : cs)), coinSeg);
    const SkOpPtT* osExisting = !os ? oppSeg->existing(oppTs, nullptr) : nullptr;
    const SkOpPtT* oeExisting = !oe ? oppSeg->existing(oppTe, nullptr) : nullptr;
    RETURN_FALSE_IF(osExisting && osExisting == oeExisting, oppSeg);
    RETURN_FALSE_IF(osExisting && (osExisting == oe ||
            osExisting->contains(oeExisting ? oeExisting : oe)), oppSeg);
    RETURN_FALSE_IF(oeExisting && (oeExisting == os ||
            oeExisting->contains(osExisting ? osExisting : os)), oppSeg);
    bool csDeleted = false, osDeleted = false, ceDeleted = false,  oeDeleted = false;
    this->debugValidate();
    if (!cs || !os) {
        if (!cs)
            cs = coinSeg->debugAddT(coinTs, log);
        if (!os)
            os = oppSeg->debugAddT(oppTs, log);
//      RETURN_FALSE_IF(callerAborts, !csWritable || !osWritable);
        if (cs && os) cs->span()->debugAddOpp(log, os->span());
//         cs = csWritable;
//         os = osWritable->active();
        RETURN_FALSE_IF((ce && ce->deleted()) || (oe && oe->deleted()), coinSeg);
    }
    if (!ce || !oe) {
        if (!ce)
            ce = coinSeg->debugAddT(coinTe, log);
        if (!oe)
            oe = oppSeg->debugAddT(oppTe, log);
        if (ce && oe) ce->span()->debugAddOpp(log, oe->span());
//         ce = ceWritable;
//         oe = oeWritable;
    }
    this->debugValidate();
    RETURN_FALSE_IF(csDeleted, coinSeg);
    RETURN_FALSE_IF(osDeleted, oppSeg);
    RETURN_FALSE_IF(ceDeleted, coinSeg);
    RETURN_FALSE_IF(oeDeleted, oppSeg);
    RETURN_FALSE_IF(!cs || !ce || cs == ce || cs->contains(ce) || !os || !oe || os == oe || os->contains(oe), coinSeg);
    bool result = true;
    if (overlap) {
        if (overlap->coinPtTStart()->segment() == coinSeg) {
                log->record(SkPathOpsDebug::kAddMissingExtend_Glitch, coinSeg, coinTs, coinTe, oppSeg, oppTs, oppTe);
        } else {
            if (oppTs > oppTe) {
                using std::swap;
                swap(coinTs, coinTe);
                swap(oppTs, oppTe);
            }
            log->record(SkPathOpsDebug::kAddMissingExtend_Glitch, oppSeg, oppTs, oppTe, coinSeg, coinTs, coinTe);
        }
#if 0 && DEBUG_COINCIDENCE_VERBOSE
        if (result) {
             overlap->debugShow();
        }
#endif
    } else {
        log->record(SkPathOpsDebug::kAddMissingCoin_Glitch, coinSeg, coinTs, coinTe, oppSeg, oppTs, oppTe);
#if 0 && DEBUG_COINCIDENCE_VERBOSE
        fHead->debugShow();
#endif
    }
    this->debugValidate();
    return (void) result;
}

// Extra commented-out lines keep this in sync with addMissing()
/* detects overlaps of different coincident runs on same segment */
/* does not detect overlaps for pairs without any segments in common */
// returns true if caller should loop again
void SkOpCoincidence::debugAddMissing(SkPathOpsDebug::GlitchLog* log, bool* added) const {
    const SkCoincidentSpans* outer = fHead;
    *added = false;
    if (!outer) {
        return;
    }
    // fTop = outer;
    // fHead = nullptr;
    do {
    // addifmissing can modify the list that this is walking
    // save head so that walker can iterate over old data unperturbed
    // addifmissing adds to head freely then add saved head in the end
        const SkOpPtT* ocs = outer->coinPtTStart();
        SkASSERT(!ocs->deleted());
        const SkOpSegment* outerCoin = ocs->segment();
        SkASSERT(!outerCoin->done());  // if it's done, should have already been removed from list
        const SkOpPtT* oos = outer->oppPtTStart();
        if (oos->deleted()) {
            return;
        }
        const SkOpSegment* outerOpp = oos->segment();
        SkASSERT(!outerOpp->done());
//        SkOpSegment* outerCoinWritable = const_cast<SkOpSegment*>(outerCoin);
//        SkOpSegment* outerOppWritable = const_cast<SkOpSegment*>(outerOpp);
        const SkCoincidentSpans* inner = outer;
        while ((inner = inner->next())) {
            this->debugValidate();
            double overS, overE;
            const SkOpPtT* ics = inner->coinPtTStart();
            SkASSERT(!ics->deleted());
            const SkOpSegment* innerCoin = ics->segment();
            SkASSERT(!innerCoin->done());
            const SkOpPtT* ios = inner->oppPtTStart();
            SkASSERT(!ios->deleted());
            const SkOpSegment* innerOpp = ios->segment();
            SkASSERT(!innerOpp->done());
//            SkOpSegment* innerCoinWritable = const_cast<SkOpSegment*>(innerCoin);
//            SkOpSegment* innerOppWritable = const_cast<SkOpSegment*>(innerOpp);
            if (outerCoin == innerCoin) {
                const SkOpPtT* oce = outer->coinPtTEnd();
                if (oce->deleted()) {
                    return;
                }
                const SkOpPtT* ice = inner->coinPtTEnd();
                SkASSERT(!ice->deleted());
                if (outerOpp != innerOpp && this->overlap(ocs, oce, ics, ice, &overS, &overE)) {
                    this->debugAddIfMissing(log, ocs->starter(oce), ics->starter(ice),
                            overS, overE, outerOpp, innerOpp, added,
                            ocs->debugEnder(oce),
                            ics->debugEnder(ice));
                }
            } else if (outerCoin == innerOpp) {
                const SkOpPtT* oce = outer->coinPtTEnd();
                SkASSERT(!oce->deleted());
                const SkOpPtT* ioe = inner->oppPtTEnd();
                SkASSERT(!ioe->deleted());
                if (outerOpp != innerCoin && this->overlap(ocs, oce, ios, ioe, &overS, &overE)) {
                    this->debugAddIfMissing(log, ocs->starter(oce), ios->starter(ioe),
                            overS, overE, outerOpp, innerCoin, added,
                            ocs->debugEnder(oce),
                            ios->debugEnder(ioe));
                }
            } else if (outerOpp == innerCoin) {
                const SkOpPtT* ooe = outer->oppPtTEnd();
                SkASSERT(!ooe->deleted());
                const SkOpPtT* ice = inner->coinPtTEnd();
                SkASSERT(!ice->deleted());
                SkASSERT(outerCoin != innerOpp);
                if (this->overlap(oos, ooe, ics, ice, &overS, &overE)) {
                    this->debugAddIfMissing(log, oos->starter(ooe), ics->starter(ice),
                            overS, overE, outerCoin, innerOpp, added,
                            oos->debugEnder(ooe),
                            ics->debugEnder(ice));
                }
            } else if (outerOpp == innerOpp) {
                const SkOpPtT* ooe = outer->oppPtTEnd();
                SkASSERT(!ooe->deleted());
                const SkOpPtT* ioe = inner->oppPtTEnd();
                if (ioe->deleted()) {
                    return;
                }
                SkASSERT(outerCoin != innerCoin);
                if (this->overlap(oos, ooe, ios, ioe, &overS, &overE)) {
                    this->debugAddIfMissing(log, oos->starter(ooe), ios->starter(ioe),
                            overS, overE, outerCoin, innerCoin, added,
                            oos->debugEnder(ooe),
                            ios->debugEnder(ioe));
                }
            }
            this->debugValidate();
        }
    } while ((outer = outer->next()));
    // this->restoreHead();
    return;
}

// Commented-out lines keep this in sync with release()
void SkOpCoincidence::debugRelease(SkPathOpsDebug::GlitchLog* log, const SkCoincidentSpans* coin, const SkCoincidentSpans* remove) const {
    const SkCoincidentSpans* head = coin;
    const SkCoincidentSpans* prev = nullptr;
    const SkCoincidentSpans* next;
    do {
        next = coin->next();
        if (coin == remove) {
            if (prev) {
//                prev->setNext(next);
            } else if (head == fHead) {
//                fHead = next;
            } else {
//                fTop = next;
            }
            log->record(SkPathOpsDebug::kReleasedSpan_Glitch, coin);
        }
        prev = coin;
    } while ((coin = next));
    return;
}

void SkOpCoincidence::debugRelease(SkPathOpsDebug::GlitchLog* log, const SkOpSegment* deleted) const {
    const SkCoincidentSpans* coin = fHead;
    if (!coin) {
        return;
    }
    do {
        if (coin->coinPtTStart()->segment() == deleted
                || coin->coinPtTEnd()->segment() == deleted
                || coin->oppPtTStart()->segment() == deleted
                || coin->oppPtTEnd()->segment() == deleted) {
            log->record(SkPathOpsDebug::kReleasedSpan_Glitch, coin);
        }
    } while ((coin = coin->next()));
}

// Commented-out lines keep this in sync with expand()
// expand the range by checking adjacent spans for coincidence
bool SkOpCoincidence::debugExpand(SkPathOpsDebug::GlitchLog* log) const {
    const SkCoincidentSpans* coin = fHead;
    if (!coin) {
        return false;
    }
    bool expanded = false;
    do {
        if (coin->debugExpand(log)) {
            // check to see if multiple spans expanded so they are now identical
            const SkCoincidentSpans* test = fHead;
            do {
                if (coin == test) {
                    continue;
                }
                if (coin->coinPtTStart() == test->coinPtTStart()
                        && coin->oppPtTStart() == test->oppPtTStart()) {
                    if (log) log->record(SkPathOpsDebug::kExpandCoin_Glitch, fHead, test->coinPtTStart());
                    break;
                }
            } while ((test = test->next()));
            expanded = true;
        }
    } while ((coin = coin->next()));
    return expanded;
}

// Commented-out lines keep this in sync with mark()
/* this sets up the coincidence links in the segments when the coincidence crosses multiple spans */
void SkOpCoincidence::debugMark(SkPathOpsDebug::GlitchLog* log) const {
    const SkCoincidentSpans* coin = fHead;
    if (!coin) {
        return;
    }
    do {
        FAIL_IF(!coin->coinPtTStartWritable()->span()->upCastable(), coin);
        const SkOpSpan* start = coin->coinPtTStartWritable()->span()->upCast();
//         SkASSERT(start->deleted());
        const SkOpSpanBase* end = coin->coinPtTEndWritable()->span();
//         SkASSERT(end->deleted());
        const SkOpSpanBase* oStart = coin->oppPtTStartWritable()->span();
//         SkASSERT(oStart->deleted());
        const SkOpSpanBase* oEnd = coin->oppPtTEndWritable()->span();
//         SkASSERT(oEnd->deleted());
        bool flipped = coin->flipped();
        if (flipped) {
            using std::swap;
            swap(oStart, oEnd);
        }
        /* coin and opp spans may not match up. Mark the ends, and then let the interior
           get marked as many times as the spans allow */
        start->debugInsertCoincidence(log, oStart->upCast());
        end->debugInsertCoinEnd(log, oEnd);
        const SkOpSegment* segment = start->segment();
        const SkOpSegment* oSegment = oStart->segment();
        const SkOpSpanBase* next = start;
        const SkOpSpanBase* oNext = oStart;
        bool ordered;
        FAIL_IF(!coin->ordered(&ordered), coin);
        while ((next = next->upCast()->next()) != end) {
            FAIL_IF(!next->upCastable(), coin);
            if (next->upCast()->debugInsertCoincidence(log, oSegment, flipped, ordered), false) {
                return;
            }
        }
        while ((oNext = oNext->upCast()->next()) != oEnd) {
            FAIL_IF(!oNext->upCastable(), coin);
            if (oNext->upCast()->debugInsertCoincidence(log, segment, flipped, ordered), false) {
                return;
            }
        }
    } while ((coin = coin->next()));
    return;
}
#endif

#if DEBUG_COIN
// Commented-out lines keep this in sync with markCollapsed()
void SkOpCoincidence::debugMarkCollapsed(SkPathOpsDebug::GlitchLog* log, const SkCoincidentSpans* coin, const SkOpPtT* test) const {
    const SkCoincidentSpans* head = coin;
    while (coin) {
        if (coin->collapsed(test)) {
            if (zero_or_one(coin->coinPtTStart()->fT) && zero_or_one(coin->coinPtTEnd()->fT)) {
                log->record(SkPathOpsDebug::kCollapsedCoin_Glitch, coin);
            }
            if (zero_or_one(coin->oppPtTStart()->fT) && zero_or_one(coin->oppPtTEnd()->fT)) {
                log->record(SkPathOpsDebug::kCollapsedCoin_Glitch, coin);
            }
            this->debugRelease(log, head, coin);
        }
        coin = coin->next();
    }
}

// Commented-out lines keep this in sync with markCollapsed()
void SkOpCoincidence::debugMarkCollapsed(SkPathOpsDebug::GlitchLog* log, const SkOpPtT* test) const {
    this->debugMarkCollapsed(log, fHead, test);
    this->debugMarkCollapsed(log, fTop, test);
}
#endif

void SkCoincidentSpans::debugShow() const {
    SkDebugf("coinSpan - id=%d t=%1.9g tEnd=%1.9g\n", coinPtTStart()->segment()->debugID(),
            coinPtTStart()->fT, coinPtTEnd()->fT);
    SkDebugf("coinSpan + id=%d t=%1.9g tEnd=%1.9g\n", oppPtTStart()->segment()->debugID(),
            oppPtTStart()->fT, oppPtTEnd()->fT);
}

void SkOpCoincidence::debugShowCoincidence() const {
#if DEBUG_COINCIDENCE
    const SkCoincidentSpans* span = fHead;
    while (span) {
        span->debugShow();
        span = span->next();
    }
#endif
}

#if DEBUG_COIN
static void DebugCheckBetween(const SkOpSpanBase* next, const SkOpSpanBase* end,
        double oStart, double oEnd, const SkOpSegment* oSegment,
        SkPathOpsDebug::GlitchLog* log) {
    SkASSERT(next != end);
    SkASSERT(!next->contains(end) || log);
    if (next->t() > end->t()) {
        using std::swap;
        swap(next, end);
    }
    do {
        const SkOpPtT* ptT = next->ptT();
        int index = 0;
        bool somethingBetween = false;
        do {
            ++index;
            ptT = ptT->next();
            const SkOpPtT* checkPtT = next->ptT();
            if (ptT == checkPtT) {
                break;
            }
            bool looped = false;
            for (int check = 0; check < index; ++check) {
                if ((looped = checkPtT == ptT)) {
                    break;
                }
                checkPtT = checkPtT->next();
            }
            if (looped) {
                SkASSERT(0);
                break;
            }
            if (ptT->deleted()) {
                continue;
            }
            if (ptT->segment() != oSegment) {
                continue;
            }
            somethingBetween |= between(oStart, ptT->fT, oEnd);
        } while (true);
        SkASSERT(somethingBetween);
    } while (next != end && (next = next->upCast()->next()));
}

static void DebugCheckOverlap(const SkCoincidentSpans* test, const SkCoincidentSpans* list,
        SkPathOpsDebug::GlitchLog* log) {
    if (!list) {
        return;
    }
    const SkOpSegment* coinSeg = test->coinPtTStart()->segment();
    SkASSERT(coinSeg == test->coinPtTEnd()->segment());
    const SkOpSegment* oppSeg = test->oppPtTStart()->segment();
    SkASSERT(oppSeg == test->oppPtTEnd()->segment());
    SkASSERT(coinSeg != test->oppPtTStart()->segment());
    SkDEBUGCODE(double tcs = test->coinPtTStart()->fT);
    SkASSERT(between(0, tcs, 1));
    SkDEBUGCODE(double tce = test->coinPtTEnd()->fT);
    SkASSERT(between(0, tce, 1));
    SkASSERT(tcs < tce);
    double tos = test->oppPtTStart()->fT;
    SkASSERT(between(0, tos, 1));
    double toe = test->oppPtTEnd()->fT;
    SkASSERT(between(0, toe, 1));
    SkASSERT(tos != toe);
    if (tos > toe) {
        using std::swap;
        swap(tos, toe);
    }
    do {
        double lcs, lce, los, loe;
        if (coinSeg == list->coinPtTStart()->segment()) {
            if (oppSeg != list->oppPtTStart()->segment()) {
                continue;
            }
            lcs = list->coinPtTStart()->fT;
            lce = list->coinPtTEnd()->fT;
            los = list->oppPtTStart()->fT;
            loe = list->oppPtTEnd()->fT;
            if (los > loe) {
                using std::swap;
                swap(los, loe);
            }
        } else if (coinSeg == list->oppPtTStart()->segment()) {
            if (oppSeg != list->coinPtTStart()->segment()) {
                continue;
            }
            lcs = list->oppPtTStart()->fT;
            lce = list->oppPtTEnd()->fT;
            if (lcs > lce) {
                using std::swap;
                swap(lcs, lce);
            }
            los = list->coinPtTStart()->fT;
            loe = list->coinPtTEnd()->fT;
        } else {
            continue;
        }
        SkASSERT(tce < lcs || lce < tcs);
        SkASSERT(toe < los || loe < tos);
    } while ((list = list->next()));
}


static void DebugCheckOverlapTop(const SkCoincidentSpans* head, const SkCoincidentSpans* opt,
        SkPathOpsDebug::GlitchLog* log) {
    // check for overlapping coincident spans
    const SkCoincidentSpans* test = head;
    while (test) {
        const SkCoincidentSpans* next = test->next();
        DebugCheckOverlap(test, next, log);
        DebugCheckOverlap(test, opt, log);
        test = next;
    }
}

static void DebugValidate(const SkCoincidentSpans* head, const SkCoincidentSpans* opt,
        SkPathOpsDebug::GlitchLog* log) {
    // look for pts inside coincident spans that are not inside the opposite spans
    const SkCoincidentSpans* coin = head;
    while (coin) {
        SkASSERT(SkOpCoincidence::Ordered(coin->coinPtTStart()->segment(),
                coin->oppPtTStart()->segment()));
        SkASSERT(coin->coinPtTStart()->span()->ptT() == coin->coinPtTStart());
        SkASSERT(coin->coinPtTEnd()->span()->ptT() == coin->coinPtTEnd());
        SkASSERT(coin->oppPtTStart()->span()->ptT() == coin->oppPtTStart());
        SkASSERT(coin->oppPtTEnd()->span()->ptT() == coin->oppPtTEnd());
        coin = coin->next();
    }
    DebugCheckOverlapTop(head, opt, log);
}
#endif

void SkOpCoincidence::debugValidate() const {
#if DEBUG_COINCIDENCE
    DebugValidate(fHead, fTop, nullptr);
    DebugValidate(fTop, nullptr, nullptr);
#endif
}

#if DEBUG_COIN
static void DebugCheckBetween(const SkCoincidentSpans* head, const SkCoincidentSpans* opt,
        SkPathOpsDebug::GlitchLog* log) {
    // look for pts inside coincident spans that are not inside the opposite spans
    const SkCoincidentSpans* coin = head;
    while (coin) {
        DebugCheckBetween(coin->coinPtTStart()->span(), coin->coinPtTEnd()->span(),
                coin->oppPtTStart()->fT, coin->oppPtTEnd()->fT, coin->oppPtTStart()->segment(),
                log);
        DebugCheckBetween(coin->oppPtTStart()->span(), coin->oppPtTEnd()->span(),
                coin->coinPtTStart()->fT, coin->coinPtTEnd()->fT, coin->coinPtTStart()->segment(),
                log);
        coin = coin->next();
    }
    DebugCheckOverlapTop(head, opt, log);
}
#endif

void SkOpCoincidence::debugCheckBetween() const {
#if DEBUG_COINCIDENCE
    if (fGlobalState->debugCheckHealth()) {
        return;
    }
    DebugCheckBetween(fHead, fTop, nullptr);
    DebugCheckBetween(fTop, nullptr, nullptr);
#endif
}

#if DEBUG_COIN
void SkOpContour::debugCheckHealth(SkPathOpsDebug::GlitchLog* log) const {
    const SkOpSegment* segment = &fHead;
    do {
        segment->debugCheckHealth(log);
    } while ((segment = segment->next()));
}

void SkOpCoincidence::debugCheckValid(SkPathOpsDebug::GlitchLog* log) const {
#if DEBUG_VALIDATE
    DebugValidate(fHead, fTop, log);
    DebugValidate(fTop, nullptr, log);
#endif
}

void SkOpCoincidence::debugCorrectEnds(SkPathOpsDebug::GlitchLog* log) const {
    const SkCoincidentSpans* coin = fHead;
    if (!coin) {
        return;
    }
    do {
        coin->debugCorrectEnds(log);
    } while ((coin = coin->next()));
}

// commmented-out lines keep this aligned with missingCoincidence()
void SkOpContour::debugMissingCoincidence(SkPathOpsDebug::GlitchLog* log) const {
//    SkASSERT(fCount > 0);
    const SkOpSegment* segment = &fHead;
//    bool result = false;
    do {
        if (segment->debugMissingCoincidence(log), false) {
//          result = true;
        }
        segment = segment->next();
    } while (segment);
    return;
}

void SkOpContour::debugMoveMultiples(SkPathOpsDebug::GlitchLog* log) const {
    SkASSERT(fCount > 0);
    const SkOpSegment* segment = &fHead;
    do {
        if (segment->debugMoveMultiples(log), false) {
            return;
        }
    } while ((segment = segment->next()));
    return;
}

void SkOpContour::debugMoveNearby(SkPathOpsDebug::GlitchLog* log) const {
    SkASSERT(fCount > 0);
    const SkOpSegment* segment = &fHead;
    do {
        segment->debugMoveNearby(log);
    } while ((segment = segment->next()));
}
#endif

#if DEBUG_COINCIDENCE_ORDER
void SkOpSegment::debugResetCoinT() const {
    fDebugBaseIndex = -1;
    fDebugBaseMin = 1;
    fDebugBaseMax = -1;
    fDebugLastIndex = -1;
    fDebugLastMin = 1;
    fDebugLastMax = -1;
}
#endif

void SkOpSegment::debugValidate() const {
#if DEBUG_COINCIDENCE_ORDER
    {
        const SkOpSpanBase* span = &fHead;
        do {
            span->debugResetCoinT();
        } while (!span->final() && (span = span->upCast()->next()));
        span = &fHead;
        int index = 0;
        do {
            span->debugSetCoinT(index++);
        } while (!span->final() && (span = span->upCast()->next()));
    }
#endif
#if DEBUG_COINCIDENCE
    if (this->globalState()->debugCheckHealth()) {
        return;
    }
#endif
#if DEBUG_VALIDATE
    const SkOpSpanBase* span = &fHead;
    double lastT = -1;
    const SkOpSpanBase* prev = nullptr;
    int count = 0;
    int done = 0;
    do {
        if (!span->final()) {
            ++count;
            done += span->upCast()->done() ? 1 : 0;
        }
        SkASSERT(span->segment() == this);
        SkASSERT(!prev || prev->upCast()->next() == span);
        SkASSERT(!prev || prev == span->prev());
        prev = span;
        double t = span->ptT()->fT;
        SkASSERT(lastT < t);
        lastT = t;
        span->debugValidate();
    } while (!span->final() && (span = span->upCast()->next()));
    SkASSERT(count == fCount);
    SkASSERT(done == fDoneCount);
    SkASSERT(count >= fDoneCount);
    SkASSERT(span->final());
    span->debugValidate();
#endif
}

#if DEBUG_COIN

// Commented-out lines keep this in sync with addOpp()
void SkOpSpanBase::debugAddOpp(SkPathOpsDebug::GlitchLog* log, const SkOpSpanBase* opp) const {
    const SkOpPtT* oppPrev = this->ptT()->oppPrev(opp->ptT());
    if (!oppPrev) {
        return;
    }
    this->debugMergeMatches(log, opp);
    this->ptT()->debugAddOpp(opp->ptT(), oppPrev);
    this->debugCheckForCollapsedCoincidence(log);
}

// Commented-out lines keep this in sync with checkForCollapsedCoincidence()
void SkOpSpanBase::debugCheckForCollapsedCoincidence(SkPathOpsDebug::GlitchLog* log) const {
    const SkOpCoincidence* coins = this->globalState()->coincidence();
    if (coins->isEmpty()) {
        return;
    }
// the insert above may have put both ends of a coincident run in the same span
// for each coincident ptT in loop; see if its opposite in is also in the loop
// this implementation is the motivation for marking that a ptT is referenced by a coincident span
    const SkOpPtT* head = this->ptT();
    const SkOpPtT* test = head;
    do {
        if (!test->coincident()) {
            continue;
        }
        coins->debugMarkCollapsed(log, test);
    } while ((test = test->next()) != head);
}
#endif

bool SkOpSpanBase::debugCoinEndLoopCheck() const {
    int loop = 0;
    const SkOpSpanBase* next = this;
    SkOpSpanBase* nextCoin;
    do {
        nextCoin = next->fCoinEnd;
        SkASSERT(nextCoin == this || nextCoin->fCoinEnd != nextCoin);
        for (int check = 1; check < loop - 1; ++check) {
            const SkOpSpanBase* checkCoin = this->fCoinEnd;
            const SkOpSpanBase* innerCoin = checkCoin;
            for (int inner = check + 1; inner < loop; ++inner) {
                innerCoin = innerCoin->fCoinEnd;
                if (checkCoin == innerCoin) {
                    SkDebugf("*** bad coincident end loop ***\n");
                    return false;
                }
            }
        }
        ++loop;
    } while ((next = nextCoin) && next != this);
    return true;
}

#if DEBUG_COIN
// Commented-out lines keep this in sync with insertCoinEnd()
void SkOpSpanBase::debugInsertCoinEnd(SkPathOpsDebug::GlitchLog* log, const SkOpSpanBase* coin) const {
    if (containsCoinEnd(coin)) {
//         SkASSERT(coin->containsCoinEnd(this));
        return;
    }
    debugValidate();
//     SkASSERT(this != coin);
    log->record(SkPathOpsDebug::kMarkCoinEnd_Glitch, this, coin);
//     coin->fCoinEnd = this->fCoinEnd;
//     this->fCoinEnd = coinNext;
    debugValidate();
}

// Commented-out lines keep this in sync with mergeMatches()
// Look to see if pt-t linked list contains same segment more than once
// if so, and if each pt-t is directly pointed to by spans in that segment,
// merge them
// keep the points, but remove spans so that the segment doesn't have 2 or more
// spans pointing to the same pt-t loop at different loop elements
void SkOpSpanBase::debugMergeMatches(SkPathOpsDebug::GlitchLog* log, const SkOpSpanBase* opp) const {
    const SkOpPtT* test = &fPtT;
    const SkOpPtT* testNext;
    const SkOpPtT* stop = test;
    do {
        testNext = test->next();
        if (test->deleted()) {
            continue;
        }
        const SkOpSpanBase* testBase = test->span();
        SkASSERT(testBase->ptT() == test);
        const SkOpSegment* segment = test->segment();
        if (segment->done()) {
            continue;
        }
        const SkOpPtT* inner = opp->ptT();
        const SkOpPtT* innerStop = inner;
        do {
            if (inner->segment() != segment) {
                continue;
            }
            if (inner->deleted()) {
                continue;
            }
            const SkOpSpanBase* innerBase = inner->span();
            SkASSERT(innerBase->ptT() == inner);
            // when the intersection is first detected, the span base is marked if there are
            // more than one point in the intersection.
//            if (!innerBase->hasMultipleHint() && !testBase->hasMultipleHint()) {
                if (!zero_or_one(inner->fT)) {
                    log->record(SkPathOpsDebug::kMergeMatches_Glitch, innerBase, test);
                } else {
                    SkASSERT(inner->fT != test->fT);
                    if (!zero_or_one(test->fT)) {
                        log->record(SkPathOpsDebug::kMergeMatches_Glitch, testBase, inner);
                    } else {
                        log->record(SkPathOpsDebug::kMergeMatches_Glitch, segment);
//                        SkDEBUGCODE(testBase->debugSetDeleted());
//                        test->setDeleted();
//                        SkDEBUGCODE(innerBase->debugSetDeleted());
//                        inner->setDeleted();
                    }
                }
#ifdef SK_DEBUG   // assert if another undeleted entry points to segment
                const SkOpPtT* debugInner = inner;
                while ((debugInner = debugInner->next()) != innerStop) {
                    if (debugInner->segment() != segment) {
                        continue;
                    }
                    if (debugInner->deleted()) {
                        continue;
                    }
                    SkOPASSERT(0);
                }
#endif
                break;
//            }
            break;
        } while ((inner = inner->next()) != innerStop);
    } while ((test = testNext) != stop);
    this->debugCheckForCollapsedCoincidence(log);
}

#endif

void SkOpSpanBase::debugResetCoinT() const {
#if DEBUG_COINCIDENCE_ORDER
    const SkOpPtT* ptT = &fPtT;
    do {
        ptT->debugResetCoinT();
        ptT = ptT->next();
    } while (ptT != &fPtT);
#endif
}

void SkOpSpanBase::debugSetCoinT(int index) const {
#if DEBUG_COINCIDENCE_ORDER
    const SkOpPtT* ptT = &fPtT;
    do {
        if (!ptT->deleted()) {
            ptT->debugSetCoinT(index);
        }
        ptT = ptT->next();
    } while (ptT != &fPtT);
#endif
}

const SkOpSpan* SkOpSpanBase::debugStarter(SkOpSpanBase const** endPtr) const {
    const SkOpSpanBase* end = *endPtr;
    SkASSERT(this->segment() == end->segment());
    const SkOpSpanBase* result;
    if (t() < end->t()) {
        result = this;
    } else {
        result = end;
        *endPtr = this;
    }
    return result->upCast();
}

void SkOpSpanBase::debugValidate() const {
#if DEBUG_COINCIDENCE
    if (this->globalState()->debugCheckHealth()) {
        return;
    }
#endif
#if DEBUG_VALIDATE
    const SkOpPtT* ptT = &fPtT;
    SkASSERT(ptT->span() == this);
    do {
//        SkASSERT(SkDPoint::RoughlyEqual(fPtT.fPt, ptT->fPt));
        ptT->debugValidate();
        ptT = ptT->next();
    } while (ptT != &fPtT);
    SkASSERT(this->debugCoinEndLoopCheck());
    if (!this->final()) {
        SkASSERT(this->upCast()->debugCoinLoopCheck());
    }
    if (fFromAngle) {
        fFromAngle->debugValidate();
    }
    if (!this->final() && this->upCast()->toAngle()) {
        this->upCast()->toAngle()->debugValidate();
    }
#endif
}

bool SkOpSpan::debugCoinLoopCheck() const {
    int loop = 0;
    const SkOpSpan* next = this;
    SkOpSpan* nextCoin;
    do {
        nextCoin = next->fCoincident;
        SkASSERT(nextCoin == this || nextCoin->fCoincident != nextCoin);
        for (int check = 1; check < loop - 1; ++check) {
            const SkOpSpan* checkCoin = this->fCoincident;
            const SkOpSpan* innerCoin = checkCoin;
            for (int inner = check + 1; inner < loop; ++inner) {
                innerCoin = innerCoin->fCoincident;
                if (checkCoin == innerCoin) {
                    SkDebugf("*** bad coincident loop ***\n");
                    return false;
                }
            }
        }
        ++loop;
    } while ((next = nextCoin) && next != this);
    return true;
}

#if DEBUG_COIN
// Commented-out lines keep this in sync with insertCoincidence() in header
void SkOpSpan::debugInsertCoincidence(SkPathOpsDebug::GlitchLog* log, const SkOpSpan* coin) const {
    if (containsCoincidence(coin)) {
//         SkASSERT(coin->containsCoincidence(this));
        return;
    }
    debugValidate();
//     SkASSERT(this != coin);
    log->record(SkPathOpsDebug::kMarkCoinStart_Glitch, this, coin);
//     coin->fCoincident = this->fCoincident;
//     this->fCoincident = coinNext;
    debugValidate();
}

// Commented-out lines keep this in sync with insertCoincidence()
void SkOpSpan::debugInsertCoincidence(SkPathOpsDebug::GlitchLog* log, const SkOpSegment* segment, bool flipped, bool ordered) const {
    if (this->containsCoincidence(segment)) {
        return;
    }
    const SkOpPtT* next = &fPtT;
    while ((next = next->next()) != &fPtT) {
        if (next->segment() == segment) {
            const SkOpSpan* span;
            const SkOpSpanBase* base = next->span();
            if (!ordered) {
                const SkOpSpanBase* spanEnd = fNext->contains(segment)->span();
                const SkOpPtT* start = base->ptT()->starter(spanEnd->ptT());
                FAIL_IF(!start->span()->upCastable(), this);
                span = const_cast<SkOpSpan*>(start->span()->upCast());
            }
            else if (flipped) {
                span = base->prev();
                FAIL_IF(!span, this);
            }
            else {
                FAIL_IF(!base->upCastable(), this);
                span = base->upCast();
            }
            log->record(SkPathOpsDebug::kMarkCoinInsert_Glitch, span);
            return;
        }
    }
#if DEBUG_COIN
    log->record(SkPathOpsDebug::kMarkCoinMissing_Glitch, segment, this);
#endif
    return;
}
#endif

// called only by test code
int SkIntersections::debugCoincidentUsed() const {
    if (!fIsCoincident[0]) {
        SkASSERT(!fIsCoincident[1]);
        return 0;
    }
    int count = 0;
    SkDEBUGCODE(int count2 = 0;)
    for (int index = 0; index < fUsed; ++index) {
        if (fIsCoincident[0] & (1 << index)) {
            ++count;
        }
#ifdef SK_DEBUG
        if (fIsCoincident[1] & (1 << index)) {
            ++count2;
        }
#endif
    }
    SkASSERT(count == count2);
    return count;
}

#include "SkOpContour.h"

// Commented-out lines keep this in sync with addOpp()
void SkOpPtT::debugAddOpp(const SkOpPtT* opp, const SkOpPtT* oppPrev) const {
    SkDEBUGCODE(const SkOpPtT* oldNext = this->fNext);
    SkASSERT(this != opp);
//    this->fNext = opp;
    SkASSERT(oppPrev != oldNext);
//    oppPrev->fNext = oldNext;
}

bool SkOpPtT::debugContains(const SkOpPtT* check) const {
    SkASSERT(this != check);
    const SkOpPtT* ptT = this;
    int links = 0;
    do {
        ptT = ptT->next();
        if (ptT == check) {
            return true;
        }
        ++links;
        const SkOpPtT* test = this;
        for (int index = 0; index < links; ++index) {
            if (ptT == test) {
                return false;
            }
            test = test->next();
        }
    } while (true);
}

const SkOpPtT* SkOpPtT::debugContains(const SkOpSegment* check) const {
    SkASSERT(this->segment() != check);
    const SkOpPtT* ptT = this;
    int links = 0;
    do {
        ptT = ptT->next();
        if (ptT->segment() == check) {
            return ptT;
        }
        ++links;
        const SkOpPtT* test = this;
        for (int index = 0; index < links; ++index) {
            if (ptT == test) {
                return nullptr;
            }
            test = test->next();
        }
    } while (true);
}

const SkOpPtT* SkOpPtT::debugEnder(const SkOpPtT* end) const {
    return fT < end->fT ? end : this;
}

int SkOpPtT::debugLoopLimit(bool report) const {
    int loop = 0;
    const SkOpPtT* next = this;
    do {
        for (int check = 1; check < loop - 1; ++check) {
            const SkOpPtT* checkPtT = this->fNext;
            const SkOpPtT* innerPtT = checkPtT;
            for (int inner = check + 1; inner < loop; ++inner) {
                innerPtT = innerPtT->fNext;
                if (checkPtT == innerPtT) {
                    if (report) {
                        SkDebugf("*** bad ptT loop ***\n");
                    }
                    return loop;
                }
            }
        }
        // there's nothing wrong with extremely large loop counts -- but this may appear to hang
        // by taking a very long time to figure out that no loop entry is a duplicate
        // -- and it's likely that a large loop count is indicative of a bug somewhere
        if (++loop > 1000) {
            SkDebugf("*** loop count exceeds 1000 ***\n");
            return 1000;
        }
    } while ((next = next->fNext) && next != this);
    return 0;
}

const SkOpPtT* SkOpPtT::debugOppPrev(const SkOpPtT* opp) const {
    return this->oppPrev(const_cast<SkOpPtT*>(opp));
}

void SkOpPtT::debugResetCoinT() const {
#if DEBUG_COINCIDENCE_ORDER
    this->segment()->debugResetCoinT();
#endif
}

void SkOpPtT::debugSetCoinT(int index) const {
#if DEBUG_COINCIDENCE_ORDER
    this->segment()->debugSetCoinT(index, fT);
#endif
}

void SkOpPtT::debugValidate() const {
#if DEBUG_COINCIDENCE
    if (this->globalState()->debugCheckHealth()) {
        return;
    }
#endif
#if DEBUG_VALIDATE
    SkOpPhase phase = contour()->globalState()->phase();
    if (phase == SkOpPhase::kIntersecting || phase == SkOpPhase::kFixWinding) {
        return;
    }
    SkASSERT(fNext);
    SkASSERT(fNext != this);
    SkASSERT(fNext->fNext);
    SkASSERT(debugLoopLimit(false) == 0);
#endif
}

static void output_scalar(SkScalar num) {
    if (num == (int) num) {
        SkDebugf("%d", (int) num);
    } else {
        SkString str;
        str.printf("%1.9g", num);
        int width = (int) str.size();
        const char* cStr = str.c_str();
        while (cStr[width - 1] == '0') {
            --width;
        }
        str.resize(width);
        SkDebugf("%sf", str.c_str());
    }
}

static void output_points(const SkPoint* pts, int count) {
    for (int index = 0; index < count; ++index) {
        output_scalar(pts[index].fX);
        SkDebugf(", ");
        output_scalar(pts[index].fY);
        if (index + 1 < count) {
            SkDebugf(", ");
        }
    }
}

static void showPathContours(SkPath::RawIter& iter, const char* pathName) {
    uint8_t verb;
    SkPoint pts[4];
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kMove_Verb:
                SkDebugf("    %s.moveTo(", pathName);
                output_points(&pts[0], 1);
                SkDebugf(");\n");
                continue;
            case SkPath::kLine_Verb:
                SkDebugf("    %s.lineTo(", pathName);
                output_points(&pts[1], 1);
                SkDebugf(");\n");
                break;
            case SkPath::kQuad_Verb:
                SkDebugf("    %s.quadTo(", pathName);
                output_points(&pts[1], 2);
                SkDebugf(");\n");
                break;
            case SkPath::kConic_Verb:
                SkDebugf("    %s.conicTo(", pathName);
                output_points(&pts[1], 2);
                SkDebugf(", %1.9gf);\n", iter.conicWeight());
                break;
            case SkPath::kCubic_Verb:
                SkDebugf("    %s.cubicTo(", pathName);
                output_points(&pts[1], 3);
                SkDebugf(");\n");
                break;
            case SkPath::kClose_Verb:
                SkDebugf("    %s.close();\n", pathName);
                break;
            default:
                SkDEBUGFAIL("bad verb");
                return;
        }
    }
}

static const char* gFillTypeStr[] = {
    "kWinding_FillType",
    "kEvenOdd_FillType",
    "kInverseWinding_FillType",
    "kInverseEvenOdd_FillType"
};

void SkPathOpsDebug::ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration) {
    SkPath::RawIter iter(path);
#define SUPPORT_RECT_CONTOUR_DETECTION 0
#if SUPPORT_RECT_CONTOUR_DETECTION
    int rectCount = path.isRectContours() ? path.rectContours(nullptr, nullptr) : 0;
    if (rectCount > 0) {
        SkTDArray<SkRect> rects;
        SkTDArray<SkPath::Direction> directions;
        rects.setCount(rectCount);
        directions.setCount(rectCount);
        path.rectContours(rects.begin(), directions.begin());
        for (int contour = 0; contour < rectCount; ++contour) {
            const SkRect& rect = rects[contour];
            SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
                    rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
                    ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
        }
        return;
    }
#endif
    SkPath::FillType fillType = path.getFillType();
    SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
    if (includeDeclaration) {
        SkDebugf("    SkPath %s;\n", name);
    }
    SkDebugf("    %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
    iter.setPath(path);
    showPathContours(iter, name);
}

#if DEBUG_DUMP_VERIFY
#include "SkData.h"
#include "SkStream.h"

static void dump_path(FILE* file, const SkPath& path, bool force, bool dumpAsHex) {
    SkDynamicMemoryWStream wStream;
    path.dump(&wStream, force, dumpAsHex);
    sk_sp<SkData> data(wStream.detachAsData());
    fprintf(file, "%.*s\n", (int) data->size(), (char*) data->data());
}

static int dumpID = 0;

void SkPathOpsDebug::DumpOp(const SkPath& one, const SkPath& two, SkPathOp op,
        const char* testName) {
    FILE* file = sk_fopen("op_dump.txt", kWrite_SkFILE_Flag);
    DumpOp(file, one, two, op, testName);
}

void SkPathOpsDebug::DumpOp(FILE* file, const SkPath& one, const SkPath& two, SkPathOp op,
        const char* testName) {
    const char* name = testName ? testName : "op";
    fprintf(file,
            "\nstatic void %s_%d(skiatest::Reporter* reporter, const char* filename) {\n",
            name, ++dumpID);
    fprintf(file, "    SkPath path;\n");
    fprintf(file, "    path.setFillType((SkPath::FillType) %d);\n", one.getFillType());
    dump_path(file, one, false, true);
    fprintf(file, "    SkPath path1(path);\n");
    fprintf(file, "    path.reset();\n");
    fprintf(file, "    path.setFillType((SkPath::FillType) %d);\n", two.getFillType());
    dump_path(file, two, false, true);
    fprintf(file, "    SkPath path2(path);\n");
    fprintf(file, "    testPathOp(reporter, path1, path2, (SkPathOp) %d, filename);\n", op);
    fprintf(file, "}\n\n");
    fclose(file);
}

void SkPathOpsDebug::DumpSimplify(const SkPath& path, const char* testName) {
    FILE* file = sk_fopen("simplify_dump.txt", kWrite_SkFILE_Flag);
    DumpSimplify(file, path, testName);
}

void SkPathOpsDebug::DumpSimplify(FILE* file, const SkPath& path, const char* testName) {
    const char* name = testName ? testName : "simplify";
    fprintf(file,
            "\nstatic void %s_%d(skiatest::Reporter* reporter, const char* filename) {\n",
            name, ++dumpID);
    fprintf(file, "    SkPath path;\n");
    fprintf(file, "    path.setFillType((SkPath::FillType) %d);\n", path.getFillType());
    dump_path(file, path, false, true);
    fprintf(file, "    testSimplify(reporter, path, filename);\n");
    fprintf(file, "}\n\n");
    fclose(file);
}

#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkPaint.h"

const int bitWidth = 64;
const int bitHeight = 64;

static void debug_scale_matrix(const SkPath& one, const SkPath* two, SkMatrix& scale) {
    SkRect larger = one.getBounds();
    if (two) {
        larger.join(two->getBounds());
    }
    SkScalar largerWidth = larger.width();
    if (largerWidth < 4) {
        largerWidth = 4;
    }
    SkScalar largerHeight = larger.height();
    if (largerHeight < 4) {
        largerHeight = 4;
    }
    SkScalar hScale = (bitWidth - 2) / largerWidth;
    SkScalar vScale = (bitHeight - 2) / largerHeight;
    scale.reset();
    scale.preScale(hScale, vScale);
    larger.fLeft *= hScale;
    larger.fRight *= hScale;
    larger.fTop *= vScale;
    larger.fBottom *= vScale;
    SkScalar dx = -16000 > larger.fLeft ? -16000 - larger.fLeft
            : 16000 < larger.fRight ? 16000 - larger.fRight : 0;
    SkScalar dy = -16000 > larger.fTop ? -16000 - larger.fTop
            : 16000 < larger.fBottom ? 16000 - larger.fBottom : 0;
    scale.preTranslate(dx, dy);
}

static int debug_paths_draw_the_same(const SkPath& one, const SkPath& two, SkBitmap& bits) {
    if (bits.width() == 0) {
        bits.allocN32Pixels(bitWidth * 2, bitHeight);
    }
    SkCanvas canvas(bits);
    canvas.drawColor(SK_ColorWHITE);
    SkPaint paint;
    canvas.save();
    const SkRect& bounds1 = one.getBounds();
    canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
    canvas.drawPath(one, paint);
    canvas.restore();
    canvas.save();
    canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
    canvas.drawPath(two, paint);
    canvas.restore();
    int errors = 0;
    for (int y = 0; y < bitHeight - 1; ++y) {
        uint32_t* addr1 = bits.getAddr32(0, y);
        uint32_t* addr2 = bits.getAddr32(0, y + 1);
        uint32_t* addr3 = bits.getAddr32(bitWidth, y);
        uint32_t* addr4 = bits.getAddr32(bitWidth, y + 1);
        for (int x = 0; x < bitWidth - 1; ++x) {
            // count 2x2 blocks
            bool err = addr1[x] != addr3[x];
            if (err) {
                errors += addr1[x + 1] != addr3[x + 1]
                        && addr2[x] != addr4[x] && addr2[x + 1] != addr4[x + 1];
            }
        }
    }
    return errors;
}

void SkPathOpsDebug::ReportOpFail(const SkPath& one, const SkPath& two, SkPathOp op) {
    SkDebugf("// Op did not expect failure\n");
    DumpOp(stderr, one, two, op, "opTest");
    fflush(stderr);
}

void SkPathOpsDebug::VerifyOp(const SkPath& one, const SkPath& two, SkPathOp op,
        const SkPath& result) {
    SkPath pathOut, scaledPathOut;
    SkRegion rgnA, rgnB, openClip, rgnOut;
    openClip.setRect(-16000, -16000, 16000, 16000);
    rgnA.setPath(one, openClip);
    rgnB.setPath(two, openClip);
    rgnOut.op(rgnA, rgnB, (SkRegion::Op) op);
    rgnOut.getBoundaryPath(&pathOut);
    SkMatrix scale;
    debug_scale_matrix(one, &two, scale);
    SkRegion scaledRgnA, scaledRgnB, scaledRgnOut;
    SkPath scaledA, scaledB;
    scaledA.addPath(one, scale);
    scaledA.setFillType(one.getFillType());
    scaledB.addPath(two, scale);
    scaledB.setFillType(two.getFillType());
    scaledRgnA.setPath(scaledA, openClip);
    scaledRgnB.setPath(scaledB, openClip);
    scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) op);
    scaledRgnOut.getBoundaryPath(&scaledPathOut);
    SkBitmap bitmap;
    SkPath scaledOut;
    scaledOut.addPath(result, scale);
    scaledOut.setFillType(result.getFillType());
    int errors = debug_paths_draw_the_same(scaledPathOut, scaledOut, bitmap);
    const int MAX_ERRORS = 9;
    if (errors > MAX_ERRORS) {
        fprintf(stderr, "// Op did not expect errors=%d\n", errors);
        DumpOp(stderr, one, two, op, "opTest");
        fflush(stderr);
    }
}

void SkPathOpsDebug::ReportSimplifyFail(const SkPath& path) {
    SkDebugf("// Simplify did not expect failure\n");
    DumpSimplify(stderr, path, "simplifyTest");
    fflush(stderr);
}

void SkPathOpsDebug::VerifySimplify(const SkPath& path, const SkPath& result) {
    SkPath pathOut, scaledPathOut;
    SkRegion rgnA, openClip, rgnOut;
    openClip.setRect(-16000, -16000, 16000, 16000);
    rgnA.setPath(path, openClip);
    rgnOut.getBoundaryPath(&pathOut);
    SkMatrix scale;
    debug_scale_matrix(path, nullptr, scale);
    SkRegion scaledRgnA;
    SkPath scaledA;
    scaledA.addPath(path, scale);
    scaledA.setFillType(path.getFillType());
    scaledRgnA.setPath(scaledA, openClip);
    scaledRgnA.getBoundaryPath(&scaledPathOut);
    SkBitmap bitmap;
    SkPath scaledOut;
    scaledOut.addPath(result, scale);
    scaledOut.setFillType(result.getFillType());
    int errors = debug_paths_draw_the_same(scaledPathOut, scaledOut, bitmap);
    const int MAX_ERRORS = 9;
    if (errors > MAX_ERRORS) {
        fprintf(stderr, "// Simplify did not expect errors=%d\n", errors);
        DumpSimplify(stderr, path, "simplifyTest");
        fflush(stderr);
    }
}

#endif

// global path dumps for msvs Visual Studio 17 to use from Immediate Window
void Dump(const SkPath& path) {
    path.dump();
}

void DumpHex(const SkPath& path) {
    path.dumpHex();
}
