SkPathOpsDebug.cpp revision 03b03cad01628146bbb8d4f33c073bd0c77ee558
107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/*
207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Copyright 2013 Google Inc.
307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com *
407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Use of this source code is governed by a BSD-style license that can be
507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * found in the LICENSE file.
607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com */
707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkPathOpsDebug.h"
9a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com#include "SkPath.h"
1054359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkString.h"
111049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#include "SkThread.h"
1254359294a7c9dc54802d512a5d891a35c1663392caryclark
1354359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_VALIDATE
1454359294a7c9dc54802d512a5d891a35c1663392caryclarkextern bool FLAGS_runFail;
1554359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
1607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
1707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#if defined SK_DEBUG || !FORCE_RELEASE
1807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
19570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comconst char* SkPathOpsDebug::kLVerbStr[] = {"", "line", "quad", "cubic"};
208cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org
218cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org#if defined(SK_DEBUG) || !FORCE_RELEASE
22fe41b8ffff3463a1b062c4fd7315b44e278ba390commit-bot@chromium.orgint SkPathOpsDebug::gContourID = 0;
23fe41b8ffff3463a1b062c4fd7315b44e278ba390commit-bot@chromium.orgint SkPathOpsDebug::gSegmentID = 0;
248cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org#endif
25570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
26570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com#if DEBUG_SORT || DEBUG_SWAP_TOP
27570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comint SkPathOpsDebug::gSortCountDefault = SK_MaxS32;
28570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comint SkPathOpsDebug::gSortCount;
29570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com#endif
30570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
31570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com#if DEBUG_ACTIVE_OP
32570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comconst char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor"};
33570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com#endif
34570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
3554359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpanBase* >& chaseArray,
3654359294a7c9dc54802d512a5d891a35c1663392caryclark        const SkOpSpanBase* span) {
374431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    for (int index = 0; index < chaseArray.count(); ++index) {
3854359294a7c9dc54802d512a5d891a35c1663392caryclark        const SkOpSpanBase* entry = chaseArray[index];
394431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        if (entry == span) {
404431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            return true;
414431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
424431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
434431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return false;
444431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
454431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
46570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comvoid SkPathOpsDebug::MathematicaIze(char* str, size_t bufferLen) {
4707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    size_t len = strlen(str);
4807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    bool num = false;
4907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (size_t idx = 0; idx < len; ++idx) {
5007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        if (num && str[idx] == 'e') {
5107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            if (len + 2 >= bufferLen) {
5207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                return;
5307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            }
5407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            memmove(&str[idx + 2], &str[idx + 1], len - idx);
5507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            str[idx] = '*';
5607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            str[idx + 1] = '^';
5707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            ++len;
5807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        }
5907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        num = str[idx] >= '0' && str[idx] <= '9';
6007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
6107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
6207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
63570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.combool SkPathOpsDebug::ValidWind(int wind) {
6407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
6507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
6607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
67570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comvoid SkPathOpsDebug::WindingPrintf(int wind) {
6807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (wind == SK_MinS32) {
6907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("?");
7007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    } else {
7107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%d", wind);
7207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
7307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
7454359294a7c9dc54802d512a5d891a35c1663392caryclark#endif //  defined SK_DEBUG || !FORCE_RELEASE
7554359294a7c9dc54802d512a5d891a35c1663392caryclark
76a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com
7707e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com#if DEBUG_SHOW_TEST_NAME
78570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comvoid* SkPathOpsDebug::CreateNameStr() {
7907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    return SkNEW_ARRAY(char, DEBUG_FILENAME_STRING_LENGTH);
80cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com}
81cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
82570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comvoid SkPathOpsDebug::DeleteNameStr(void* v) {
8307e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    SkDELETE_ARRAY(reinterpret_cast<char* >(v));
84a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com}
85a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com
86570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comvoid SkPathOpsDebug::BumpTestName(char* test) {
8707e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    char* num = test + strlen(test);
8807e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    while (num[-1] >= '0' && num[-1] <= '9') {
8907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com        --num;
9007e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
9107e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    if (num[0] == '\0') {
9207e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com        return;
9307e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
9407e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    int dec = atoi(num);
9507e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    if (dec == 0) {
9607e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com        return;
9707e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
9807e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    ++dec;
9907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    SK_SNPRINTF(num, DEBUG_FILENAME_STRING_LENGTH - (num - test), "%d", dec);
100a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com}
101a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com#endif
102570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
1031049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstatic void show_function_header(const char* functionName) {
1041049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName);
1051049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    if (strcmp("skphealth_com76", functionName) == 0) {
1061049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDebugf("found it\n");
1071049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
1081049f1246e7be4ccb68001361efceb8933e6f81ccaryclark}
1091049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1101049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstatic const char* gOpStrs[] = {
1111049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kDifference_SkPathOp",
1121049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kIntersect_SkPathOp",
1131049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kUnion_SkPathOp",
1141049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kXor_PathOp",
1151049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kReverseDifference_SkPathOp",
1161049f1246e7be4ccb68001361efceb8933e6f81ccaryclark};
1171049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
11803b03cad01628146bbb8d4f33c073bd0c77ee558caryclarkconst char* SkPathOpsDebug::OpStr(SkPathOp op) {
11903b03cad01628146bbb8d4f33c073bd0c77ee558caryclark    return gOpStrs[op];
12003b03cad01628146bbb8d4f33c073bd0c77ee558caryclark}
12103b03cad01628146bbb8d4f33c073bd0c77ee558caryclark
1221049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstatic void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) {
1231049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDebugf("    testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]);
1241049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDebugf("}\n");
1251049f1246e7be4ccb68001361efceb8933e6f81ccaryclark}
1261049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1271049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkSK_DECLARE_STATIC_MUTEX(gTestMutex);
1281049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1291049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkvoid SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp,
1301049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        const char* testName) {
1311049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkAutoMutexAcquire ac(gTestMutex);
1321049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    show_function_header(testName);
1331049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    ShowOnePath(a, "path", true);
1341049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    ShowOnePath(b, "pathB", true);
1351049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    show_op(shapeOp, "path", "pathB");
1364431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
1374431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
1384431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#include "SkOpAngle.h"
139570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com#include "SkOpSegment.h"
140570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
1414431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if DEBUG_SWAP_TOP
14254359294a7c9dc54802d512a5d891a35c1663392caryclarkint SkOpSegment::debugInflections(const SkOpSpanBase* start, const SkOpSpanBase* end) const {
1434431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (fVerb != SkPath::kCubic_Verb) {
1444431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return false;
1454431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
14654359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDCubic dst = SkDCubic::SubDivide(fPts, start->t(), end->t());
1478cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org    double inflections[2];
1488cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org    return dst.findInflections(inflections);
1498cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org}
1508cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org#endif
1518cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org
15254359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpAngle* SkOpSegment::debugLastAngle() {
15354359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpAngle* result = NULL;
15454359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpSpan* span = this->head();
15554359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
15654359294a7c9dc54802d512a5d891a35c1663392caryclark        if (span->toAngle()) {
157dac1d17027dcaa5596885a9f333979418b35001ccaryclark            SkASSERT(!result);
15854359294a7c9dc54802d512a5d891a35c1663392caryclark            result = span->toAngle();
159dac1d17027dcaa5596885a9f333979418b35001ccaryclark        }
16054359294a7c9dc54802d512a5d891a35c1663392caryclark    } while ((span = span->next()->upCastable()));
161dac1d17027dcaa5596885a9f333979418b35001ccaryclark    SkASSERT(result);
162dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return result;
163dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
164dac1d17027dcaa5596885a9f333979418b35001ccaryclark
1654431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgvoid SkOpSegment::debugReset() {
1661049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    this->init(this->fPts, this->fWeight, this->contour(), this->verb());
1674431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
1684431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
16954359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_ACTIVE_SPANS
1704431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgvoid SkOpSegment::debugShowActiveSpans() const {
1714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    debugValidate();
1724431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (done()) {
1734431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return;
1744431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
1754431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int lastId = -1;
1764431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    double lastT = -1;
17754359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpSpan* span = &fHead;
17854359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
17954359294a7c9dc54802d512a5d891a35c1663392caryclark        if (span->done()) {
1804431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            continue;
1814431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
1821049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        if (lastId == this->debugID() && lastT == span->t()) {
1834431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            continue;
1844431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
1851049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        lastId = this->debugID();
18654359294a7c9dc54802d512a5d891a35c1663392caryclark        lastT = span->t();
1871049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDebugf("%s id=%d", __FUNCTION__, this->debugID());
1884431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
1894431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
1904431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
1914431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
1921049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        if (SkPath::kConic_Verb == fVerb) {
1931049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            SkDebugf(" %1.9gf", fWeight);
1941049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        }
19554359294a7c9dc54802d512a5d891a35c1663392caryclark        const SkOpPtT* ptT = span->ptT();
19654359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf(") t=%1.9g (%1.9g,%1.9g)", ptT->fT, ptT->fPt.fX, ptT->fPt.fY);
19754359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf(" tEnd=%1.9g", span->next()->t());
19854359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf(" windSum=");
19954359294a7c9dc54802d512a5d891a35c1663392caryclark        if (span->windSum() == SK_MinS32) {
2004431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            SkDebugf("?");
2014431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        } else {
20254359294a7c9dc54802d512a5d891a35c1663392caryclark            SkDebugf("%d", span->windSum());
2034431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
20454359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf(" windValue=%d oppValue=%d", span->windValue(), span->oppValue());
20554359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("\n");
20654359294a7c9dc54802d512a5d891a35c1663392caryclark   } while ((span = span->next()->upCastable()));
2074431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
2084431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#endif
2094431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
21054359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_MARK_DONE
21154359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding) {
21254359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkPoint& pt = span->ptT()->fPt;
2131049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDebugf("%s id=%d", fun, this->debugID());
2144431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
2154431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
2164431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
2174431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
21854359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
21954359294a7c9dc54802d512a5d891a35c1663392caryclark            span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t());
22054359294a7c9dc54802d512a5d891a35c1663392caryclark    if (winding == SK_MinS32) {
2214431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        SkDebugf("?");
2224431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    } else {
22354359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("%d", winding);
2244431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
22554359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDebugf(" windSum=");
22654359294a7c9dc54802d512a5d891a35c1663392caryclark    if (span->windSum() == SK_MinS32) {
22754359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("?");
22854359294a7c9dc54802d512a5d891a35c1663392caryclark    } else {
22954359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("%d", span->windSum());
23054359294a7c9dc54802d512a5d891a35c1663392caryclark    }
23154359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDebugf(" windValue=%d\n", span->windValue());
2324431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
2334431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
23454359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding,
2354431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org                                      int oppWinding) {
23654359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkPoint& pt = span->ptT()->fPt;
2371049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDebugf("%s id=%d", fun, this->debugID());
2384431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
2394431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
2404431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
2414431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
24254359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
24354359294a7c9dc54802d512a5d891a35c1663392caryclark            span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t(), winding, oppWinding);
24454359294a7c9dc54802d512a5d891a35c1663392caryclark    if (winding == SK_MinS32) {
24554359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("?");
24654359294a7c9dc54802d512a5d891a35c1663392caryclark    } else {
24754359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("%d", winding);
24854359294a7c9dc54802d512a5d891a35c1663392caryclark    }
24954359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDebugf(" newOppSum=");
25054359294a7c9dc54802d512a5d891a35c1663392caryclark    if (oppWinding == SK_MinS32) {
25154359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("?");
25254359294a7c9dc54802d512a5d891a35c1663392caryclark    } else {
25354359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("%d", oppWinding);
25454359294a7c9dc54802d512a5d891a35c1663392caryclark    }
25554359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDebugf(" oppSum=");
25654359294a7c9dc54802d512a5d891a35c1663392caryclark    if (span->oppSum() == SK_MinS32) {
2574431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        SkDebugf("?");
2584431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    } else {
25954359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("%d", span->oppSum());
2604431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
2614431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkDebugf(" windSum=");
26254359294a7c9dc54802d512a5d891a35c1663392caryclark    if (span->windSum() == SK_MinS32) {
2634431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        SkDebugf("?");
2644431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    } else {
26554359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("%d", span->windSum());
2664431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
26754359294a7c9dc54802d512a5d891a35c1663392caryclark    SkDebugf(" windValue=%d oppValue=%d\n", span->windValue(), span->oppValue());
2684431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
26954359294a7c9dc54802d512a5d891a35c1663392caryclark
2704431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#endif
2714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
27254359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_ANGLE
27354359294a7c9dc54802d512a5d891a35c1663392caryclarkSkString SkOpAngle::debugPart() const {
27454359294a7c9dc54802d512a5d891a35c1663392caryclark    SkString result;
27554359294a7c9dc54802d512a5d891a35c1663392caryclark    switch (this->segment()->verb()) {
27654359294a7c9dc54802d512a5d891a35c1663392caryclark        case SkPath::kLine_Verb:
27754359294a7c9dc54802d512a5d891a35c1663392caryclark            result.printf(LINE_DEBUG_STR " id=%d", LINE_DEBUG_DATA(fCurvePart),
27854359294a7c9dc54802d512a5d891a35c1663392caryclark                    this->segment()->debugID());
27954359294a7c9dc54802d512a5d891a35c1663392caryclark            break;
28054359294a7c9dc54802d512a5d891a35c1663392caryclark        case SkPath::kQuad_Verb:
28154359294a7c9dc54802d512a5d891a35c1663392caryclark            result.printf(QUAD_DEBUG_STR " id=%d", QUAD_DEBUG_DATA(fCurvePart),
28254359294a7c9dc54802d512a5d891a35c1663392caryclark                    this->segment()->debugID());
28354359294a7c9dc54802d512a5d891a35c1663392caryclark            break;
2841049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        case SkPath::kConic_Verb:
2851049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            result.printf(CONIC_DEBUG_STR " id=%d",
2861049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                    CONIC_DEBUG_DATA(fCurvePart, fCurvePart.fConic.fWeight),
2871049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                    this->segment()->debugID());
2881049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            break;
28954359294a7c9dc54802d512a5d891a35c1663392caryclark        case SkPath::kCubic_Verb:
29054359294a7c9dc54802d512a5d891a35c1663392caryclark            result.printf(CUBIC_DEBUG_STR " id=%d", CUBIC_DEBUG_DATA(fCurvePart),
29154359294a7c9dc54802d512a5d891a35c1663392caryclark                    this->segment()->debugID());
29254359294a7c9dc54802d512a5d891a35c1663392caryclark            break;
29354359294a7c9dc54802d512a5d891a35c1663392caryclark        default:
29454359294a7c9dc54802d512a5d891a35c1663392caryclark            SkASSERT(0);
29554359294a7c9dc54802d512a5d891a35c1663392caryclark    }
29654359294a7c9dc54802d512a5d891a35c1663392caryclark    return result;
29754359294a7c9dc54802d512a5d891a35c1663392caryclark}
29854359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
29954359294a7c9dc54802d512a5d891a35c1663392caryclark
30003b03cad01628146bbb8d4f33c073bd0c77ee558caryclark#if DEBUG_SORT || DEBUG_SWAP_TOP
30154359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpAngle::debugLoop() const {
30254359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpAngle* first = this;
30354359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpAngle* next = this;
30454359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
30554359294a7c9dc54802d512a5d891a35c1663392caryclark        next->dumpOne(true);
30654359294a7c9dc54802d512a5d891a35c1663392caryclark        SkDebugf("\n");
30754359294a7c9dc54802d512a5d891a35c1663392caryclark        next = next->fNext;
30854359294a7c9dc54802d512a5d891a35c1663392caryclark    } while (next && next != first);
30954359294a7c9dc54802d512a5d891a35c1663392caryclark    next = first;
31054359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
31154359294a7c9dc54802d512a5d891a35c1663392caryclark        next->debugValidate();
31254359294a7c9dc54802d512a5d891a35c1663392caryclark        next = next->fNext;
31354359294a7c9dc54802d512a5d891a35c1663392caryclark    } while (next && next != first);
314ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark}
315ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark#endif
316ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark
31754359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpAngle::debugValidate() const {
31854359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_VALIDATE
31954359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpAngle* first = this;
32054359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpAngle* next = this;
32154359294a7c9dc54802d512a5d891a35c1663392caryclark    int wind = 0;
32254359294a7c9dc54802d512a5d891a35c1663392caryclark    int opp = 0;
32354359294a7c9dc54802d512a5d891a35c1663392caryclark    int lastXor = -1;
32454359294a7c9dc54802d512a5d891a35c1663392caryclark    int lastOppXor = -1;
32554359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
32654359294a7c9dc54802d512a5d891a35c1663392caryclark        if (next->unorderable()) {
32754359294a7c9dc54802d512a5d891a35c1663392caryclark            return;
32854359294a7c9dc54802d512a5d891a35c1663392caryclark        }
32954359294a7c9dc54802d512a5d891a35c1663392caryclark        const SkOpSpan* minSpan = next->start()->starter(next->end());
33054359294a7c9dc54802d512a5d891a35c1663392caryclark        if (minSpan->windValue() == SK_MinS32) {
33154359294a7c9dc54802d512a5d891a35c1663392caryclark            return;
33254359294a7c9dc54802d512a5d891a35c1663392caryclark        }
33354359294a7c9dc54802d512a5d891a35c1663392caryclark        bool op = next->segment()->operand();
33454359294a7c9dc54802d512a5d891a35c1663392caryclark        bool isXor = next->segment()->isXor();
33554359294a7c9dc54802d512a5d891a35c1663392caryclark        bool oppXor = next->segment()->oppXor();
33654359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(!DEBUG_LIMIT_WIND_SUM || between(0, minSpan->windValue(), DEBUG_LIMIT_WIND_SUM));
33754359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(!DEBUG_LIMIT_WIND_SUM
33854359294a7c9dc54802d512a5d891a35c1663392caryclark                || between(-DEBUG_LIMIT_WIND_SUM, minSpan->oppValue(), DEBUG_LIMIT_WIND_SUM));
33954359294a7c9dc54802d512a5d891a35c1663392caryclark        bool useXor = op ? oppXor : isXor;
34054359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(lastXor == -1 || lastXor == (int) useXor);
34154359294a7c9dc54802d512a5d891a35c1663392caryclark        lastXor = (int) useXor;
34254359294a7c9dc54802d512a5d891a35c1663392caryclark        wind += next->sign() * (op ? minSpan->oppValue() : minSpan->windValue());
34354359294a7c9dc54802d512a5d891a35c1663392caryclark        if (useXor) {
34454359294a7c9dc54802d512a5d891a35c1663392caryclark            wind &= 1;
34554359294a7c9dc54802d512a5d891a35c1663392caryclark        }
34654359294a7c9dc54802d512a5d891a35c1663392caryclark        useXor = op ? isXor : oppXor;
34754359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(lastOppXor == -1 || lastOppXor == (int) useXor);
34854359294a7c9dc54802d512a5d891a35c1663392caryclark        lastOppXor = (int) useXor;
34954359294a7c9dc54802d512a5d891a35c1663392caryclark        opp += next->sign() * (op ? minSpan->windValue() : minSpan->oppValue());
35054359294a7c9dc54802d512a5d891a35c1663392caryclark        if (useXor) {
35154359294a7c9dc54802d512a5d891a35c1663392caryclark            opp &= 1;
35254359294a7c9dc54802d512a5d891a35c1663392caryclark        }
35354359294a7c9dc54802d512a5d891a35c1663392caryclark        next = next->fNext;
35454359294a7c9dc54802d512a5d891a35c1663392caryclark    } while (next && next != first);
35554359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(wind == 0);
35654359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(opp == 0 || !FLAGS_runFail);
35754359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
35854359294a7c9dc54802d512a5d891a35c1663392caryclark}
35954359294a7c9dc54802d512a5d891a35c1663392caryclark
36054359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpAngle::debugValidateNext() const {
36154359294a7c9dc54802d512a5d891a35c1663392caryclark#if !FORCE_RELEASE
36254359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpAngle* first = this;
36354359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpAngle* next = first;
36454359294a7c9dc54802d512a5d891a35c1663392caryclark    SkTDArray<const SkOpAngle*>(angles);
36554359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
36654359294a7c9dc54802d512a5d891a35c1663392caryclark//        SK_ALWAYSBREAK(next->fSegment->debugContains(next));
36754359294a7c9dc54802d512a5d891a35c1663392caryclark        angles.push(next);
36854359294a7c9dc54802d512a5d891a35c1663392caryclark        next = next->next();
36954359294a7c9dc54802d512a5d891a35c1663392caryclark        if (next == first) {
37054359294a7c9dc54802d512a5d891a35c1663392caryclark            break;
37154359294a7c9dc54802d512a5d891a35c1663392caryclark        }
37254359294a7c9dc54802d512a5d891a35c1663392caryclark        SK_ALWAYSBREAK(!angles.contains(next));
37354359294a7c9dc54802d512a5d891a35c1663392caryclark        if (!next) {
37454359294a7c9dc54802d512a5d891a35c1663392caryclark            return;
37554359294a7c9dc54802d512a5d891a35c1663392caryclark        }
37654359294a7c9dc54802d512a5d891a35c1663392caryclark    } while (true);
37754359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
37854359294a7c9dc54802d512a5d891a35c1663392caryclark}
37954359294a7c9dc54802d512a5d891a35c1663392caryclark
3804431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgvoid SkOpSegment::debugValidate() const {
3814431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if DEBUG_VALIDATE
38254359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpSpanBase* span = &fHead;
38354359294a7c9dc54802d512a5d891a35c1663392caryclark    double lastT = -1;
38454359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpSpanBase* prev = NULL;
38554359294a7c9dc54802d512a5d891a35c1663392caryclark    int count = 0;
3864431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int done = 0;
38754359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
38854359294a7c9dc54802d512a5d891a35c1663392caryclark        if (!span->final()) {
38954359294a7c9dc54802d512a5d891a35c1663392caryclark            ++count;
39054359294a7c9dc54802d512a5d891a35c1663392caryclark            done += span->upCast()->done() ? 1 : 0;
39154359294a7c9dc54802d512a5d891a35c1663392caryclark        }
39254359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(span->segment() == this);
39354359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(!prev || prev->upCast()->next() == span);
39454359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(!prev || prev == span->prev());
39554359294a7c9dc54802d512a5d891a35c1663392caryclark        prev = span;
39654359294a7c9dc54802d512a5d891a35c1663392caryclark        double t = span->ptT()->fT;
39754359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(lastT < t);
39854359294a7c9dc54802d512a5d891a35c1663392caryclark        lastT = t;
39954359294a7c9dc54802d512a5d891a35c1663392caryclark        span->debugValidate();
40054359294a7c9dc54802d512a5d891a35c1663392caryclark    } while (!span->final() && (span = span->upCast()->next()));
40154359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(count == fCount);
40254359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(done == fDoneCount);
40354359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(span->final());
40454359294a7c9dc54802d512a5d891a35c1663392caryclark    span->debugValidate();
40554359294a7c9dc54802d512a5d891a35c1663392caryclark#endif
40654359294a7c9dc54802d512a5d891a35c1663392caryclark}
40754359294a7c9dc54802d512a5d891a35c1663392caryclark
40854359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkOpSpanBase::debugCoinEndLoopCheck() const {
40954359294a7c9dc54802d512a5d891a35c1663392caryclark    int loop = 0;
41054359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpSpanBase* next = this;
41154359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpSpanBase* nextCoin;
41254359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
41354359294a7c9dc54802d512a5d891a35c1663392caryclark        nextCoin = next->fCoinEnd;
41454359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(nextCoin == this || nextCoin->fCoinEnd != nextCoin);
41554359294a7c9dc54802d512a5d891a35c1663392caryclark        for (int check = 1; check < loop - 1; ++check) {
41654359294a7c9dc54802d512a5d891a35c1663392caryclark            const SkOpSpanBase* checkCoin = this->fCoinEnd;
41754359294a7c9dc54802d512a5d891a35c1663392caryclark            const SkOpSpanBase* innerCoin = checkCoin;
41854359294a7c9dc54802d512a5d891a35c1663392caryclark            for (int inner = check + 1; inner < loop; ++inner) {
41954359294a7c9dc54802d512a5d891a35c1663392caryclark                innerCoin = innerCoin->fCoinEnd;
42054359294a7c9dc54802d512a5d891a35c1663392caryclark                if (checkCoin == innerCoin) {
42154359294a7c9dc54802d512a5d891a35c1663392caryclark                    SkDebugf("*** bad coincident end loop ***\n");
42254359294a7c9dc54802d512a5d891a35c1663392caryclark                    return false;
42354359294a7c9dc54802d512a5d891a35c1663392caryclark                }
42454359294a7c9dc54802d512a5d891a35c1663392caryclark            }
42554359294a7c9dc54802d512a5d891a35c1663392caryclark        }
42654359294a7c9dc54802d512a5d891a35c1663392caryclark        ++loop;
42754359294a7c9dc54802d512a5d891a35c1663392caryclark    } while ((next = nextCoin) && next != this);
42854359294a7c9dc54802d512a5d891a35c1663392caryclark    return true;
42954359294a7c9dc54802d512a5d891a35c1663392caryclark}
43054359294a7c9dc54802d512a5d891a35c1663392caryclark
43154359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpanBase::debugValidate() const {
43254359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_VALIDATE
43354359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpPtT* ptT = &fPtT;
43454359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(ptT->span() == this);
43554359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
43654359294a7c9dc54802d512a5d891a35c1663392caryclark//        SkASSERT(SkDPoint::RoughlyEqual(fPtT.fPt, ptT->fPt));
43754359294a7c9dc54802d512a5d891a35c1663392caryclark        ptT->debugValidate();
43854359294a7c9dc54802d512a5d891a35c1663392caryclark        ptT = ptT->next();
43954359294a7c9dc54802d512a5d891a35c1663392caryclark    } while (ptT != &fPtT);
44054359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(this->debugCoinEndLoopCheck());
44154359294a7c9dc54802d512a5d891a35c1663392caryclark    if (!this->final()) {
44254359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(this->upCast()->debugCoinLoopCheck());
44354359294a7c9dc54802d512a5d891a35c1663392caryclark    }
44454359294a7c9dc54802d512a5d891a35c1663392caryclark    if (fFromAngle) {
44554359294a7c9dc54802d512a5d891a35c1663392caryclark        fFromAngle->debugValidate();
44654359294a7c9dc54802d512a5d891a35c1663392caryclark    }
44754359294a7c9dc54802d512a5d891a35c1663392caryclark    if (!this->final() && this->upCast()->toAngle()) {
44854359294a7c9dc54802d512a5d891a35c1663392caryclark        this->upCast()->toAngle()->debugValidate();
44954359294a7c9dc54802d512a5d891a35c1663392caryclark    }
4504431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#endif
45154359294a7c9dc54802d512a5d891a35c1663392caryclark}
45254359294a7c9dc54802d512a5d891a35c1663392caryclark
45354359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkOpSpan::debugCoinLoopCheck() const {
45454359294a7c9dc54802d512a5d891a35c1663392caryclark    int loop = 0;
45554359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpSpan* next = this;
45654359294a7c9dc54802d512a5d891a35c1663392caryclark    SkOpSpan* nextCoin;
45754359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
45854359294a7c9dc54802d512a5d891a35c1663392caryclark        nextCoin = next->fCoincident;
45954359294a7c9dc54802d512a5d891a35c1663392caryclark        SkASSERT(nextCoin == this || nextCoin->fCoincident != nextCoin);
46054359294a7c9dc54802d512a5d891a35c1663392caryclark        for (int check = 1; check < loop - 1; ++check) {
46154359294a7c9dc54802d512a5d891a35c1663392caryclark            const SkOpSpan* checkCoin = this->fCoincident;
46254359294a7c9dc54802d512a5d891a35c1663392caryclark            const SkOpSpan* innerCoin = checkCoin;
46354359294a7c9dc54802d512a5d891a35c1663392caryclark            for (int inner = check + 1; inner < loop; ++inner) {
46454359294a7c9dc54802d512a5d891a35c1663392caryclark                innerCoin = innerCoin->fCoincident;
46554359294a7c9dc54802d512a5d891a35c1663392caryclark                if (checkCoin == innerCoin) {
46654359294a7c9dc54802d512a5d891a35c1663392caryclark                    SkDebugf("*** bad coincident loop ***\n");
46754359294a7c9dc54802d512a5d891a35c1663392caryclark                    return false;
46854359294a7c9dc54802d512a5d891a35c1663392caryclark                }
46954359294a7c9dc54802d512a5d891a35c1663392caryclark            }
47054359294a7c9dc54802d512a5d891a35c1663392caryclark        }
47154359294a7c9dc54802d512a5d891a35c1663392caryclark        ++loop;
47254359294a7c9dc54802d512a5d891a35c1663392caryclark    } while ((next = nextCoin) && next != this);
47354359294a7c9dc54802d512a5d891a35c1663392caryclark    return true;
47454359294a7c9dc54802d512a5d891a35c1663392caryclark}
47554359294a7c9dc54802d512a5d891a35c1663392caryclark
47654359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkOpContour.h"
47754359294a7c9dc54802d512a5d891a35c1663392caryclark
47854359294a7c9dc54802d512a5d891a35c1663392caryclarkint SkOpPtT::debugLoopLimit(bool report) const {
47954359294a7c9dc54802d512a5d891a35c1663392caryclark    int loop = 0;
48054359294a7c9dc54802d512a5d891a35c1663392caryclark    const SkOpPtT* next = this;
48154359294a7c9dc54802d512a5d891a35c1663392caryclark    do {
48254359294a7c9dc54802d512a5d891a35c1663392caryclark        for (int check = 1; check < loop - 1; ++check) {
48354359294a7c9dc54802d512a5d891a35c1663392caryclark            const SkOpPtT* checkPtT = this->fNext;
48454359294a7c9dc54802d512a5d891a35c1663392caryclark            const SkOpPtT* innerPtT = checkPtT;
48554359294a7c9dc54802d512a5d891a35c1663392caryclark            for (int inner = check + 1; inner < loop; ++inner) {
48654359294a7c9dc54802d512a5d891a35c1663392caryclark                innerPtT = innerPtT->fNext;
48754359294a7c9dc54802d512a5d891a35c1663392caryclark                if (checkPtT == innerPtT) {
48854359294a7c9dc54802d512a5d891a35c1663392caryclark                    if (report) {
48954359294a7c9dc54802d512a5d891a35c1663392caryclark                        SkDebugf("*** bad ptT loop ***\n");
49054359294a7c9dc54802d512a5d891a35c1663392caryclark                    }
49154359294a7c9dc54802d512a5d891a35c1663392caryclark                    return loop;
49254359294a7c9dc54802d512a5d891a35c1663392caryclark                }
4934431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            }
4944431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
49554359294a7c9dc54802d512a5d891a35c1663392caryclark        ++loop;
49654359294a7c9dc54802d512a5d891a35c1663392caryclark    } while ((next = next->fNext) && next != this);
49754359294a7c9dc54802d512a5d891a35c1663392caryclark    return 0;
49854359294a7c9dc54802d512a5d891a35c1663392caryclark}
49954359294a7c9dc54802d512a5d891a35c1663392caryclark
50054359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpPtT::debugValidate() const {
50154359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_VALIDATE
50254359294a7c9dc54802d512a5d891a35c1663392caryclark    if (contour()->globalState()->phase() == SkOpGlobalState::kIntersecting) {
50354359294a7c9dc54802d512a5d891a35c1663392caryclark        return;
5044431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
50554359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(fNext);
50654359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(fNext != this);
50754359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(fNext->fNext);
50854359294a7c9dc54802d512a5d891a35c1663392caryclark    SkASSERT(debugLoopLimit(false) == 0);
5094431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#endif
5104431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org}
5111049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
5121049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstatic void output_scalar(SkScalar num) {
5131049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    if (num == (int) num) {
5141049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDebugf("%d", (int) num);
5151049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    } else {
5161049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkString str;
5171049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        str.printf("%1.9g", num);
5181049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        int width = (int) str.size();
5191049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        const char* cStr = str.c_str();
5201049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        while (cStr[width - 1] == '0') {
5211049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            --width;
5221049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        }
5231049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        str.resize(width);
5241049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDebugf("%sf", str.c_str());
5251049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
5261049f1246e7be4ccb68001361efceb8933e6f81ccaryclark}
5271049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
5281049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstatic void output_points(const SkPoint* pts, int count) {
5291049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    for (int index = 0; index < count; ++index) {
5301049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        output_scalar(pts[index].fX);
5311049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDebugf(", ");
5321049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        output_scalar(pts[index].fY);
5331049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        if (index + 1 < count) {
5341049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            SkDebugf(", ");
5351049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        }
5361049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
5371049f1246e7be4ccb68001361efceb8933e6f81ccaryclark}
5381049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
5391049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstatic void showPathContours(SkPath::RawIter& iter, const char* pathName) {
5401049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    uint8_t verb;
5411049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkPoint pts[4];
5421049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
5431049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        switch (verb) {
5441049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            case SkPath::kMove_Verb:
5451049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf("    %s.moveTo(", pathName);
5461049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                output_points(&pts[0], 1);
5471049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf(");\n");
5481049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                continue;
5491049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            case SkPath::kLine_Verb:
5501049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf("    %s.lineTo(", pathName);
5511049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                output_points(&pts[1], 1);
5521049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf(");\n");
5531049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                break;
5541049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            case SkPath::kQuad_Verb:
5551049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf("    %s.quadTo(", pathName);
5561049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                output_points(&pts[1], 2);
5571049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf(");\n");
5581049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                break;
5591049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            case SkPath::kConic_Verb:
5601049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf("    %s.conicTo(", pathName);
5611049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                output_points(&pts[1], 2);
5621049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf(", %1.9gf);\n", iter.conicWeight());
5631049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                break;
5641049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            case SkPath::kCubic_Verb:
5651049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf("    %s.cubicTo(", pathName);
5661049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                output_points(&pts[1], 3);
5671049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf(");\n");
5681049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                break;
5691049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            case SkPath::kClose_Verb:
5701049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDebugf("    %s.close();\n", pathName);
5711049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                break;
5721049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            default:
5731049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                SkDEBUGFAIL("bad verb");
5741049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                return;
5751049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        }
5761049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
5771049f1246e7be4ccb68001361efceb8933e6f81ccaryclark}
5781049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
5791049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstatic const char* gFillTypeStr[] = {
5801049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kWinding_FillType",
5811049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kEvenOdd_FillType",
5821049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kInverseWinding_FillType",
5831049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    "kInverseEvenOdd_FillType"
5841049f1246e7be4ccb68001361efceb8933e6f81ccaryclark};
5851049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
5861049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkvoid SkPathOpsDebug::ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration) {
5871049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkPath::RawIter iter(path);
5881049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#define SUPPORT_RECT_CONTOUR_DETECTION 0
5891049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#if SUPPORT_RECT_CONTOUR_DETECTION
5901049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
5911049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    if (rectCount > 0) {
5921049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkTDArray<SkRect> rects;
5931049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkTDArray<SkPath::Direction> directions;
5941049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        rects.setCount(rectCount);
5951049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        directions.setCount(rectCount);
5961049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        path.rectContours(rects.begin(), directions.begin());
5971049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        for (int contour = 0; contour < rectCount; ++contour) {
5981049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            const SkRect& rect = rects[contour];
5991049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
6001049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                    rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
6011049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                    ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
6021049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        }
6031049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return;
6041049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
6051049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#endif
6061049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkPath::FillType fillType = path.getFillType();
6071049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
6081049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    if (includeDeclaration) {
6091049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDebugf("    SkPath %s;\n", name);
6101049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
6111049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDebugf("    %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
6121049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    iter.setPath(path);
6131049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    showPathContours(iter, name);
6141049f1246e7be4ccb68001361efceb8933e6f81ccaryclark}
615