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

#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/pathops/SkPathOps.h"
#include "include/utils/SkParsePath.h"
#include "src/core/SkPathPriv.h"
#include "tests/Test.h"

#include <initializer_list>
#include <string>

static SkPath build_squircle(SkPath::Verb verb, const SkRect& rect, SkPathDirection dir) {
    SkPathBuilder builder;
    bool reverse = SkPathDirection::kCCW == dir;
    switch (verb) {
        case SkPath::kLine_Verb:
            builder.addRect(rect, dir);
            reverse = false;
            break;
        case SkPath::kQuad_Verb:
            builder.moveTo(rect.centerX(), rect.fTop);
            builder.quadTo(rect.fRight, rect.fTop, rect.fRight, rect.centerY());
            builder.quadTo(rect.fRight, rect.fBottom, rect.centerX(), rect.fBottom);
            builder.quadTo(rect.fLeft, rect.fBottom, rect.fLeft, rect.centerY());
            builder.quadTo(rect.fLeft, rect.fTop, rect.centerX(), rect.fTop);
            break;
        case SkPath::kConic_Verb:
            builder.addCircle(rect.centerX(), rect.centerY(), rect.width() / 2, dir);
            reverse = false;
            break;
        case SkPath::kCubic_Verb: {
            SkScalar aX14 = rect.fLeft + rect.width() * 1 / 4;
            SkScalar aX34 = rect.fLeft + rect.width() * 3 / 4;
            SkScalar aY14 = rect.fTop + rect.height() * 1 / 4;
            SkScalar aY34 = rect.fTop + rect.height() * 3 / 4;
            builder.moveTo(rect.centerX(), rect.fTop);
            builder.cubicTo(aX34, rect.fTop, rect.fRight, aY14, rect.fRight, rect.centerY());
            builder.cubicTo(rect.fRight, aY34, aX34, rect.fBottom, rect.centerX(), rect.fBottom);
            builder.cubicTo(aX14, rect.fBottom, rect.fLeft, aY34, rect.fLeft, rect.centerY());
            builder.cubicTo(rect.fLeft, aY14, aX14, rect.fTop, rect.centerX(), rect.fTop);
            } break;
        default:
            SkASSERT(0);
    }
    SkPath path = builder.detach();
    if (reverse) {
        SkPathPriv::ReverseAddPath(&builder, path);
        path = builder.detach();
    }
    return path;
}

void bug12040_1(skiatest::Reporter* reporter) {
    SkPath path = SkPathBuilder(SkPathFillType::kWinding)
                  .moveTo(375, -30)
                  .cubicTo(578, -30, 749, 176, 749, 422)
                  .cubicTo(749, 583, 666, 706, 518, 765)
                  .lineTo(163, 611)
                  .lineTo(163, 579)
                  .lineTo(405, 684)
                  .cubicTo(551, 609, 645, 468, 645, 322)
                  .cubicTo(645, 183, 563, 82, 450, 82)
                  .cubicTo(303, 82, 179, 249, 179, 446)
                  .cubicTo(179, 579, 235, 689, 341, 768)
                  .lineTo(327, 786)
                  .cubicTo(165, 717, 56, 536, 56, 335)
                  .cubicTo(56, 125, 192, -30, 375, -30)
                  .close()
                  .moveTo(214, 225)
                  .cubicTo(333, 248, 396, 311, 396, 405)
                  .lineTo(396, 695)
                  .lineTo(267, 641)
                  .lineTo(267, 395)
                  .cubicTo(267, 324, 249, 285, 201, 254)
                  .cubicTo(201, 254, 214, 225, 214, 225)
                  .close()
                  .moveTo(682, -106)
                  .lineTo(832, 12)
                  .lineTo(813, 33)
                  .lineTo(772, 0)
                  .cubicTo(716, 29, 668, 76, 628, 140)
                  .lineTo(527, 44)
                  .cubicTo(575, -26, 628, -77, 682, -106)
                  .close()
                  .moveTo(450, 59)
                  .lineTo(480, 59)
                  .lineTo(480, 678)
                  .lineTo(450, 678)
                  .cubicTo(450, 678, 450, 59, 450, 59)
                  .close()
                  .moveTo(463, 374)
                  .lineTo(633, 459)
                  .lineTo(633, 490)
                  .lineTo(463, 406)
                  .cubicTo(463, 406, 463, 374, 463, 374)
                  .close()
                  .moveTo(463, 269)
                  .lineTo(667, 372)
                  .lineTo(667, 403)
                  .lineTo(463, 301)
                  .cubicTo(463, 301, 463, 269, 463, 269)
                  .close()
                  .detach();

    SkPath path2 = SkPathBuilder(SkPathFillType::kWinding)
                   .moveTo(-83.5464f, 188)
                   .cubicTo(-83.5464f, 184.285f, -84.8599f, 181.114f, -87.4868f, 178.487f)
                   .cubicTo(-90.1138f, 175.86f, -93.2849f, 174.546f, -97, 174.546f)
                   .cubicTo(-100.715f, 174.546f, -103.886f, 175.86f, -106.513f, 178.487f)
                   .cubicTo(-109.14f, 181.114f, -110.454f, 184.285f, -110.454f, 188)
                   .cubicTo(-110.454f, 191.715f, -109.14f, 194.886f, -106.513f, 197.513f)
                   .cubicTo(-103.886f, 200.14f, -100.715f, 201.454f, -97, 201.454f)
                   .cubicTo(-93.2849f, 201.454f, -90.1138f, 200.14f, -87.4868f, 197.513f)
                   .cubicTo(-84.8599f, 194.886f, -83.5464f, 191.715f, -83.5464f, 188)
                   .close()
                   .detach();

    SkPath opResult = Op(path, path2, kDifference_SkPathOp).value_or(SkPath());

    auto winding = AsWinding(opResult);
    REPORTER_ASSERT(reporter, winding.has_value());
    REPORTER_ASSERT(reporter, winding->getFillType() == SkPathFillType::kWinding);

    SkPath difference = Op(*winding, opResult, kXOR_SkPathOp).value_or(SkPath());
    REPORTER_ASSERT(reporter, difference.isEmpty());
}

void bug12040_2(skiatest::Reporter* reporter) {
    SkPath path = SkPathBuilder(SkPathFillType::kWinding)
                  .moveTo(375, -30)
                  .cubicTo(578, -30, 749, 176, 749, 422)
                  .cubicTo(749, 583, 666, 706, 518, 765)
                  .lineTo(163, 611)
                  .lineTo(163, 579)
                  .lineTo(405, 684)
                  .cubicTo(551, 609, 645, 468, 645, 322)
                  .cubicTo(645, 183, 563, 82, 450, 82)
                  .cubicTo(303, 82, 179, 249, 179, 446)
                  .cubicTo(179, 579, 235, 689, 341, 768)
                  .lineTo(327, 786)
                  .cubicTo(165, 717, 56, 536, 56, 335)
                  .cubicTo(56, 125, 192, -30, 375, -30)
                  .close()
                  .moveTo(214, 225)
                  .cubicTo(333, 248, 396, 311, 396, 405)
                  .lineTo(396, 695)
                  .lineTo(267, 641)
                  .lineTo(267, 395)
                  .cubicTo(267, 324, 249, 285, 201, 254)
                  .cubicTo(201, 254, 214, 225, 214, 225)
                  .close()
                  .moveTo(682, -106)
                  .lineTo(832, 12)
                  .lineTo(813, 33)
                  .lineTo(772, 0)
                  .cubicTo(716, 29, 668, 76, 628, 140)
                  .lineTo(527, 44)
                  .cubicTo(575, -26, 628, -77, 682, -106)
                  .close()
                  .moveTo(450, 59)
                  .lineTo(480, 59)
                  .lineTo(480, 678)
                  .lineTo(450, 678)
                  .cubicTo(450, 678, 450, 59, 450, 59)
                  .close()
                  .moveTo(463, 374)
                  .lineTo(633, 459)
                  .lineTo(633, 490)
                  .lineTo(463, 406)
                  .cubicTo(463, 406, 463, 374, 463, 374)
                  .close()
                  .moveTo(463, 269)
                  .lineTo(667, 372)
                  .lineTo(667, 403)
                  .lineTo(463, 301)
                  .cubicTo(463, 301, 463, 269, 463, 269)
                  .close()
                  .detach();

    SkPath path2 = SkPathBuilder(SkPathFillType::kWinding)
                   .moveTo(269.134f, 71.3392f)
                   .cubicTo(269.134f, 67.6241f, 267.82f, 64.453f, 265.193f, 61.826f)
                   .cubicTo(262.566f, 59.1991f, 259.395f, 57.8856f, 255.68f, 57.8856f)
                   .cubicTo(251.965f, 57.8856f, 248.794f, 59.1991f, 246.167f, 61.826f)
                   .cubicTo(243.54f, 64.453f, 242.226f, 67.6241f, 242.226f, 71.3392f)
                   .cubicTo(242.226f, 75.0543f, 243.54f, 78.2255f, 246.167f, 80.8524f)
                   .cubicTo(248.794f, 83.4794f, 251.965f, 84.7928f, 255.68f, 84.7928f)
                   .cubicTo(259.395f, 84.7928f, 262.566f, 83.4794f, 265.193f, 80.8524f)
                   .cubicTo(267.82f, 78.2255f, 269.134f, 75.0543f, 269.134f, 71.3392f)
                   .close()
                   .detach();

    SkPath opResult = Op(path, path2, kDifference_SkPathOp).value_or(SkPath());

    // This produces the correct result in all the cases I've tried.
    // So it appears to be a winding issue.
    // canvas->drawPath(opResult, p);

    auto winding = AsWinding(opResult);
    path2.setFillType(SkPathFillType::kWinding);
    REPORTER_ASSERT(reporter, winding.has_value());
    REPORTER_ASSERT(reporter, winding->getFillType() == SkPathFillType::kWinding);

    SkPath difference = Op(*winding, opResult, kXOR_SkPathOp).value_or(SkPath());
    REPORTER_ASSERT(reporter, difference.isEmpty());
}

void bug12040_3(skiatest::Reporter* reporter) {
    SkPath path = SkPathBuilder(SkPathFillType::kWinding)
                  .moveTo(375, -30)
                  .cubicTo(578, -30, 749, 176, 749, 422)
                  .cubicTo(749, 583, 666, 706, 518, 765)
                  .lineTo(163, 611)
                  .lineTo(163, 579)
                  .lineTo(405, 684)
                  .cubicTo(551, 609, 645, 468, 645, 322)
                  .cubicTo(645, 183, 563, 82, 450, 82)
                  .cubicTo(303, 82, 179, 249, 179, 446)
                  .cubicTo(179, 579, 235, 689, 341, 768)
                  .lineTo(327, 786)
                  .cubicTo(165, 717, 56, 536, 56, 335)
                  .cubicTo(56, 125, 192, -30, 375, -30)
                  .close()
                  .moveTo(214, 225)
                  .cubicTo(333, 248, 396, 311, 396, 405)
                  .lineTo(396, 695)
                  .lineTo(267, 641)
                  .lineTo(267, 395)
                  .cubicTo(267, 324, 249, 285, 201, 254)
                  .cubicTo(201, 254, 214, 225, 214, 225)
                  .close()
                  .moveTo(682, -106)
                  .lineTo(832, 12)
                  .lineTo(813, 33)
                  .lineTo(772, 0)
                  .cubicTo(716, 29, 668, 76, 628, 140)
                  .lineTo(527, 44)
                  .cubicTo(575, -26, 628, -77, 682, -106)
                  .close()
                  .moveTo(450, 59)
                  .lineTo(480, 59)
                  .lineTo(480, 678)
                  .lineTo(450, 678)
                  .cubicTo(450, 678, 450, 59, 450, 59)
                  .close()
                  .moveTo(463, 374)
                  .lineTo(633, 459)
                  .lineTo(633, 490)
                  .lineTo(463, 406)
                  .cubicTo(463, 406, 463, 374, 463, 374)
                  .close()
                  .moveTo(463, 269)
                  .lineTo(667, 372)
                  .lineTo(667, 403)
                  .lineTo(463, 301)
                  .cubicTo(463, 301, 463, 269, 463, 269)
                  .close()
                  .detach();

    SkPath path2 = SkPathBuilder(SkPathFillType::kWinding)
                   .moveTo(492.041f, 525.339f)
                   .cubicTo(492.041f, 521.624f, 490.727f, 518.453f, 488.1f, 515.826f)
                   .cubicTo(485.473f, 513.199f, 482.302f, 511.886f, 478.587f, 511.886f)
                   .cubicTo(474.872f, 511.886f, 471.701f, 513.199f, 469.074f, 515.826f)
                   .cubicTo(466.447f, 518.453f, 465.134f, 521.624f, 465.134f, 525.339f)
                   .cubicTo(465.134f, 529.054f, 466.447f, 532.226f, 469.074f, 534.853f)
                   .cubicTo(471.701f, 537.479f, 474.872f, 538.793f, 478.587f, 538.793f)
                   .cubicTo(482.302f, 538.793f, 485.473f, 537.479f, 488.1f, 534.853f)
                   .cubicTo(490.727f, 532.226f, 492.041f, 529.054f, 492.041f, 525.339f)
                   .close()
                   .detach();

    SkPath opResult = Op(path, path2, kDifference_SkPathOp).value_or(SkPath());

    auto winding = AsWinding(opResult);
    path2.setFillType(SkPathFillType::kWinding);
    REPORTER_ASSERT(reporter, winding.has_value());
    REPORTER_ASSERT(reporter, winding->getFillType() == SkPathFillType::kWinding);

    SkPath difference = Op(*winding, opResult, kXOR_SkPathOp).value_or(SkPath());
    REPORTER_ASSERT(reporter, difference.isEmpty());
}

void bug12040_4(skiatest::Reporter* reporter) {
    for (int moveX = 199; moveX <= 201; ++moveX) {
        for (int moveY = 299; moveY <= 301; ++moveY) {
            for (int lineX = 199; lineX <= 201; ++lineX) {
                for (int lineY = 199; lineY <= 201; ++lineY) {
                    SkPath path = SkPath::Circle(250, 250, 150);

                    SkPath path2 = SkPathBuilder(SkPathFillType::kWinding)
                                   .moveTo(moveX, moveY)  // 200, 300 works... But not 200, 301!!
                                   .lineTo(lineX, lineY)  // 200, 200 works... But not 199, 200!!
                                   .lineTo(300, 300)
                                   .close()
                                   .detach();

                    SkPath opResult = Op(path, path2, kDifference_SkPathOp).value_or(SkPath());

                    auto winding = AsWinding(opResult);
                    REPORTER_ASSERT(reporter, winding.has_value());
                    REPORTER_ASSERT(reporter, winding->getFillType() == SkPathFillType::kWinding);

                    SkPath difference = Op(*winding, opResult, kXOR_SkPathOp).value_or(SkPath());
                    REPORTER_ASSERT(reporter, difference.isEmpty());
                }
            }
        }
    }
}

void bug12040_5(skiatest::Reporter* reporter) {
    for (int moveX = 199; moveX <= 201; ++moveX) {
        for (int moveY = 299; moveY <= 301; ++moveY) {
            for (int lineX = 199; lineX <= 201; ++lineX) {
                for (int lineY = 199; lineY <= 201; ++lineY) {
                    SkPath path = SkPath::Rect({100, 100, 400, 400});

                    SkPath path2 = SkPathBuilder(SkPathFillType::kWinding)
                                   .moveTo(moveX, moveY)
                                   .lineTo(lineX, lineY)  // 200, 200 works... But not 199, 200!!
                                   .lineTo(300, 300)
                                   .close()
                                   .detach();

                    SkPath opResult = Op(path, path2, kDifference_SkPathOp).value_or(SkPath());

                    auto winding = AsWinding(opResult);
                    REPORTER_ASSERT(reporter, winding.has_value());
                    REPORTER_ASSERT(reporter, winding->getFillType() == SkPathFillType::kWinding);

                    SkPath difference = Op(*winding, opResult, kXOR_SkPathOp).value_or(SkPath());
                    REPORTER_ASSERT(reporter, difference.isEmpty());
                }
            }
        }
    }
}

void bug13496_1(skiatest::Reporter* reporter) {
    std::string originalPathStr =
            "M5.93 -3.12C5.93 -5.03 4.73 -6.06 3.5 -6.06C2.67 -6.06 1.98 -5.59 1.76 -5.34L1.67 "
            "-5.93L0.75 -5.93L0.75 2.23L1.87 2.04L1.87 -0.12C2.12 -0.03 2.62 0.07 3.18 0.07C4.57 "
            "0.07 5.93 -1.06 5.93 -3.12ZM4.81 -3.09C4.81 -1.51 4.18 -0.85 3.17 -0.85C2.57 -0.85 "
            "2.15 -0.98 1.87 -1.12L1.87 -4.15C2.34 -4.73 2.75 -5.09 3.42 -5.09C4.31 -5.09 4.81 "
            "-4.46 4.81 -3.09Z";

    SkPath path = SkParsePath::FromSVGString(originalPathStr.c_str()).value_or(SkPath());

    SkPath simplifiedPath = Simplify(path).value_or(SkPath());

    auto windingPath = AsWinding(simplifiedPath);
    REPORTER_ASSERT(reporter, windingPath.has_value());
    REPORTER_ASSERT(reporter, windingPath->getFillType() == SkPathFillType::kWinding);

    SkPath difference = Op(*windingPath, simplifiedPath, kXOR_SkPathOp).value_or(SkPath());
    REPORTER_ASSERT(reporter, difference.isEmpty());
}

void bug13496_2(skiatest::Reporter* reporter) {
    std::string originalPathStr =
            "M4 0"
            "L0 0"
            "L0 5"
            "L4 4"
            "Z"
            "M3 3"
            "L1 3"
            "L1 1"
            "L3 1"
            "Z";

    SkPath path = SkParsePath::FromSVGString(originalPathStr.c_str()).value_or(SkPath());

    SkPath simplifiedPath = Simplify(path).value_or(SkPath());

    auto windingPath = AsWinding(simplifiedPath);
    REPORTER_ASSERT(reporter, windingPath.has_value());
    REPORTER_ASSERT(reporter, windingPath->getFillType() == SkPathFillType::kWinding);

    SkPath difference = Op(*windingPath, simplifiedPath, kXOR_SkPathOp).value_or(SkPath());
    REPORTER_ASSERT(reporter, difference.isEmpty());
}

void bug13496_3(skiatest::Reporter* reporter) {
    std::string originalPathStr =
            "M4 0"
            "L0 0"
            "L0 4"
            "L4 4"
            "Z"
            "M3 3"
            "L1 3"
            "L1 1"
            "L3 1"
            "Z";

    SkPath path = SkParsePath::FromSVGString(originalPathStr.c_str()).value_or(SkPath());

    SkPath simplifiedPath = Simplify(path).value_or(SkPath());

    auto windingPath = AsWinding(simplifiedPath);
    REPORTER_ASSERT(reporter, windingPath.has_value());
    REPORTER_ASSERT(reporter, windingPath->getFillType() == SkPathFillType::kWinding);

    SkPath difference = Op(*windingPath, simplifiedPath, kXOR_SkPathOp).value_or(SkPath());
    REPORTER_ASSERT(reporter, difference.isEmpty());
}

DEF_TEST(PathOpsAsWinding, reporter) {
    SkPath test;
    test.addRect({1, 2, 3, 4});
    // if test is winding
    auto result = AsWinding(test);
    REPORTER_ASSERT(reporter, result.has_value());
    REPORTER_ASSERT(reporter, test == *result);
    // if test is empty
    test.reset();
    test.setFillType(SkPathFillType::kEvenOdd);
    result = AsWinding(test);
    REPORTER_ASSERT(reporter, result.has_value());
    REPORTER_ASSERT(reporter, result->isEmpty());
    REPORTER_ASSERT(reporter, result->getFillType() == SkPathFillType::kWinding);
    // if test is convex
    test.addCircle(5, 5, 10);
    result = AsWinding(test);
    REPORTER_ASSERT(reporter, result.has_value());
    REPORTER_ASSERT(reporter, result->isConvex());
    test.setFillType(SkPathFillType::kWinding);
    REPORTER_ASSERT(reporter, test == *result);
    // if test has infinity
    test.reset();
    test.addRect({1, 2, 3, SK_ScalarInfinity});
    test.setFillType(SkPathFillType::kEvenOdd);
    result = AsWinding(test);
    REPORTER_ASSERT(reporter, !result.has_value());
    // if test has only one contour
    test.reset();
    SkPoint ell[] = {{0, 0}, {4, 0}, {4, 1}, {1, 1}, {1, 4}, {0, 4}};
    test.addPoly(ell, true);
    test.setFillType(SkPathFillType::kEvenOdd);
    result = AsWinding(test);
    REPORTER_ASSERT(reporter, result.has_value());
    REPORTER_ASSERT(reporter, !result->isConvex());
    test.setFillType(SkPathFillType::kWinding);
    REPORTER_ASSERT(reporter, test == *result);
    // test two contours that do not overlap or share bounds
    test.addRect({5, 2, 6, 3});
    test.setFillType(SkPathFillType::kEvenOdd);
    result = AsWinding(test);
    REPORTER_ASSERT(reporter, result.has_value());
    REPORTER_ASSERT(reporter, !result->isConvex());
    test.setFillType(SkPathFillType::kWinding);
    REPORTER_ASSERT(reporter, test == *result);
    // test two contours that do not overlap but share bounds
    test.reset();
    test.addPoly(ell, true);
    test.addRect({2, 2, 3, 3});
    test.setFillType(SkPathFillType::kEvenOdd);
    result = AsWinding(test);
    REPORTER_ASSERT(reporter, result.has_value());
    REPORTER_ASSERT(reporter, !result->isConvex());
    test.setFillType(SkPathFillType::kWinding);
    REPORTER_ASSERT(reporter, test == *result);
    // test two contours that partially overlap
    test.reset();
    test.addRect({0, 0, 3, 3});
    test.addRect({1, 1, 4, 4});
    test.setFillType(SkPathFillType::kEvenOdd);
    result = AsWinding(test);
    REPORTER_ASSERT(reporter, result.has_value());
    REPORTER_ASSERT(reporter, !result->isConvex());
    test.setFillType(SkPathFillType::kWinding);
    REPORTER_ASSERT(reporter, test == *result);

    // test a in b, b in a, cw/ccw
    constexpr SkRect rectA = {0, 0, 3, 3};
    constexpr SkRect rectB = {1, 1, 2, 2};
    const std::initializer_list<SkPoint> revBccw = {{1, 2}, {2, 2}, {2, 1}, {1, 1}};
    const std::initializer_list<SkPoint> revBcw  = {{2, 1}, {2, 2}, {1, 2}, {1, 1}};
    for (bool aFirst : {false, true}) {
        for (auto dirA : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
            for (auto dirB : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
                test.reset();
                test.setFillType(SkPathFillType::kEvenOdd);
                if (aFirst) {
                    test.addRect(rectA, dirA);
                    test.addRect(rectB, dirB);
                } else {
                    test.addRect(rectB, dirB);
                    test.addRect(rectA, dirA);
                }
                SkPath original = test;
                result = AsWinding(test);
                REPORTER_ASSERT(reporter, result.has_value());
                REPORTER_ASSERT(reporter, result->getFillType() == SkPathFillType::kWinding);
                test.reset();
                if (aFirst) {
                    test.addRect(rectA, dirA);
                }
                if (dirA != dirB) {
                    test.addRect(rectB, dirB);
                } else {
                    test.addPoly(SkPathDirection::kCW == dirA ? revBccw : revBcw, true);
                }
                if (!aFirst) {
                    test.addRect(rectA, dirA);
                }
                REPORTER_ASSERT(reporter, test == *result);
            }
        }
    }
    // Test curve types with donuts. Create a donut with outer and hole in all directions.
    // After converting to winding, all donuts should have a hole in the middle.
    for (bool aFirst : {false, true}) {
        for (auto dirA : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
            for (auto dirB : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
                for (auto curveA : { SkPath::kLine_Verb, SkPath::kQuad_Verb,
                                     SkPath::kConic_Verb, SkPath::kCubic_Verb } ) {
                    SkPath pathA = build_squircle(curveA, rectA, dirA);
                    for (auto curveB : { SkPath::kLine_Verb, SkPath::kQuad_Verb,
                                     SkPath::kConic_Verb, SkPath::kCubic_Verb } ) {
                        test = aFirst ? pathA : SkPath();
                        test.addPath(build_squircle(curveB, rectB, dirB));
                        if (!aFirst) {
                            test.addPath(pathA);
                        }
                        test.setFillType(SkPathFillType::kEvenOdd);
                        result = AsWinding(test);
                        REPORTER_ASSERT(reporter, result.has_value());
                        REPORTER_ASSERT(reporter, result->getFillType() == SkPathFillType::kWinding);
                        for (SkScalar x = rectA.fLeft - 1; x <= rectA.fRight + 1; ++x) {
                            for (SkScalar y = rectA.fTop - 1; y <= rectA.fBottom + 1; ++y) {
                                bool evenOddContains = test.contains(x, y);
                                bool windingContains = result->contains(x, y);
                                REPORTER_ASSERT(reporter, evenOddContains == windingContains);
                            }
                        }
                    }
                }
            }
        }
    }
    // test https://bugs.chromium.org/p/skia/issues/detail?id=12040
    bug12040_1(reporter);
    bug12040_2(reporter);
    bug12040_3(reporter);
    bug12040_4(reporter);
    bug12040_5(reporter);
    // test https://bugs.chromium.org/p/skia/issues/detail?id=13496
    bug13496_1(reporter);
    bug13496_2(reporter);
    bug13496_3(reporter);
}
