107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/*
207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Copyright 2012 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#include "SkAddIntersections.h"
807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkPathOpsBounds.h"
907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
1007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#if DEBUG_ADD_INTERSECTING_TS
1107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
1207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowLineIntersection(int pts, const SkIntersectionHelper& wt,
1307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                      const SkIntersectionHelper& wn, const SkIntersections& i) {
1407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkASSERT(i.used() == pts);
1507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (!pts) {
1607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%s no intersect " LINE_DEBUG_STR " " LINE_DEBUG_STR "\n",
1707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                __FUNCTION__, LINE_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
1807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return;
1907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
2007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " LINE_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
2107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            i[0][0], LINE_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
2207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (pts == 2) {
2307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " T_DEBUG_STR(wtTs, 1) " " PT_DEBUG_STR, i[0][1], PT_DEBUG_DATA(i, 1));
2407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
2507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
2607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (pts == 2) {
2707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " T_DEBUG_STR(wnTs, 1), i[1][1]);
2807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
2907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("\n");
3007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
3107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
3207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowQuadLineIntersection(int pts, const SkIntersectionHelper& wt,
3307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                          const SkIntersectionHelper& wn,
3407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                          const SkIntersections& i) {
3507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkASSERT(i.used() == pts);
3607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (!pts) {
3707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%s no intersect " QUAD_DEBUG_STR " " LINE_DEBUG_STR "\n",
3807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
3907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return;
4007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
4107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
4207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
4307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
4407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
4507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
4607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
4707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
4807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
4907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
5007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("\n");
5107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
5207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
5307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowQuadIntersection(int pts, const SkIntersectionHelper& wt,
5407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& wn, const SkIntersections& i) {
5507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkASSERT(i.used() == pts);
5607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (!pts) {
5707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%s no intersect " QUAD_DEBUG_STR " " QUAD_DEBUG_STR "\n",
5807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
5907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return;
6007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
6107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
6207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
6307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
6407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
6507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
6607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
6707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
6807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
6907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
7007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("\n");
7107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
7207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
7307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicLineIntersection(int pts, const SkIntersectionHelper& wt,
7407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& wn, const SkIntersections& i) {
7507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkASSERT(i.used() == pts);
7607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (!pts) {
7707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " LINE_DEBUG_STR "\n",
7807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
7907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return;
8007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
8107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
8207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
8307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
8407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
8507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
8607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
8707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
8807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
8907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
9007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("\n");
9107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
9207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
9307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicQuadIntersection(int pts, const SkIntersectionHelper& wt,
9407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& wn, const SkIntersections& i) {
9507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkASSERT(i.used() == pts);
9607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (!pts) {
9707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " QUAD_DEBUG_STR "\n",
9807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
9907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return;
10007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
10107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
10207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
10307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
10407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
10507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
10607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
10707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
10807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
10907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
11007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("\n");
11107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
11207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
11307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
11407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& wn, const SkIntersections& i) {
11507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkASSERT(i.used() == pts);
11607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (!pts) {
11707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " CUBIC_DEBUG_STR "\n",
11807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), CUBIC_DEBUG_DATA(wn.pts()));
11907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return;
12007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
12107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
12207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
12307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
12407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
12507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
12607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf(" wnTs[0]=%g " CUBIC_DEBUG_STR, i[1][0], CUBIC_DEBUG_DATA(wn.pts()));
12707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int n = 1; n < pts; ++n) {
12807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
12907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
13007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("\n");
13107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
13207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
13307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
13407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersections& i) {
13507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkASSERT(i.used() == pts);
13607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (!pts) {
13707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkDebugf("%s no self intersect " CUBIC_DEBUG_STR "\n", __FUNCTION__,
13807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                CUBIC_DEBUG_DATA(wt.pts()));
13907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return;
14007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
14107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
14207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
14307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf(" " T_DEBUG_STR(wtTs, 1), i[1][0]);
14407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkDebugf("\n");
14507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
14607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
14707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#else
14807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowLineIntersection(int , const SkIntersectionHelper& ,
14907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& , const SkIntersections& ) {
15007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
15107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
15207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowQuadLineIntersection(int , const SkIntersectionHelper& ,
15307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& , const SkIntersections& ) {
15407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
15507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
15607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowQuadIntersection(int , const SkIntersectionHelper& ,
15707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& , const SkIntersections& ) {
15807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
15907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
16007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicLineIntersection(int , const SkIntersectionHelper& ,
16107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& , const SkIntersections& ) {
16207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
16307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
16407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicQuadIntersection(int , const SkIntersectionHelper& ,
16507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& , const SkIntersections& ) {
16607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
16707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
16807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
16907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersectionHelper& , const SkIntersections& ) {
17007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
17107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
17207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstatic void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
17307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        const SkIntersections& ) {
17407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
17507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif
17607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
17707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.combool AddIntersectTs(SkOpContour* test, SkOpContour* next) {
17807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    if (test != next) {
179570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        if (AlmostLessUlps(test->bounds().fBottom, next->bounds().fTop)) {
18007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            return false;
18107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        }
182570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        // OPTIMIZATION: outset contour bounds a smidgen instead?
18307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        if (!SkPathOpsBounds::Intersects(test->bounds(), next->bounds())) {
18407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            return true;
18507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        }
18607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
18707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkIntersectionHelper wt;
18807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    wt.init(test);
18907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    bool foundCommonContour = test == next;
19007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    do {
19107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkIntersectionHelper wn;
19207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        wn.init(next);
19307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        if (test == next && !wn.startAfter(wt)) {
19407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            continue;
19507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        }
19607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        do {
19707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            if (!SkPathOpsBounds::Intersects(wt.bounds(), wn.bounds())) {
19807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                continue;
19907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            }
20007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            int pts = 0;
20107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            SkIntersections ts;
20207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            bool swap = false;
20307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            switch (wt.segmentType()) {
20407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                case SkIntersectionHelper::kHorizontalLine_Segment:
20507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    swap = true;
20607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    switch (wn.segmentType()) {
20707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kHorizontalLine_Segment:
20807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kVerticalLine_Segment:
20907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kLine_Segment: {
21007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.lineHorizontal(wn.pts(), wt.left(),
21107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wt.right(), wt.y(), wt.xFlipped());
212a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com                            debugShowLineIntersection(pts, wn, wt, ts);
21307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
21407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
21507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kQuad_Segment: {
21607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.quadHorizontal(wn.pts(), wt.left(),
21707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wt.right(), wt.y(), wt.xFlipped());
21807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowQuadLineIntersection(pts, wn, wt, ts);
21907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
22007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
22107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kCubic_Segment: {
22207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicHorizontal(wn.pts(), wt.left(),
22307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wt.right(), wt.y(), wt.xFlipped());
22407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicLineIntersection(pts, wn, wt, ts);
22507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
22607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
22707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        default:
22807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            SkASSERT(0);
22907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    }
23007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    break;
23107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                case SkIntersectionHelper::kVerticalLine_Segment:
23207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    swap = true;
23307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    switch (wn.segmentType()) {
23407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kHorizontalLine_Segment:
23507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kVerticalLine_Segment:
23607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kLine_Segment: {
23707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.lineVertical(wn.pts(), wt.top(),
23807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wt.bottom(), wt.x(), wt.yFlipped());
239a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com                            debugShowLineIntersection(pts, wn, wt, ts);
24007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
24107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
24207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kQuad_Segment: {
24307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.quadVertical(wn.pts(), wt.top(),
24407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wt.bottom(), wt.x(), wt.yFlipped());
24507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowQuadLineIntersection(pts, wn, wt, ts);
24607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
24707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
24807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kCubic_Segment: {
24907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicVertical(wn.pts(), wt.top(),
25007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wt.bottom(), wt.x(), wt.yFlipped());
25107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicLineIntersection(pts, wn, wt, ts);
25207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
25307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
25407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        default:
25507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            SkASSERT(0);
25607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    }
25707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    break;
25807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                case SkIntersectionHelper::kLine_Segment:
25907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    switch (wn.segmentType()) {
26007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kHorizontalLine_Segment:
26107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.lineHorizontal(wt.pts(), wn.left(),
26207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wn.right(), wn.y(), wn.xFlipped());
26307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowLineIntersection(pts, wt, wn, ts);
26407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
26507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kVerticalLine_Segment:
26607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.lineVertical(wt.pts(), wn.top(),
26707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wn.bottom(), wn.x(), wn.yFlipped());
26807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowLineIntersection(pts, wt, wn, ts);
26907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
27007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kLine_Segment: {
27107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.lineLine(wt.pts(), wn.pts());
27207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowLineIntersection(pts, wt, wn, ts);
27307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
27407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
27507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kQuad_Segment: {
27607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            swap = true;
27707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.quadLine(wn.pts(), wt.pts());
27807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowQuadLineIntersection(pts, wn, wt, ts);
27907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
28007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
28107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kCubic_Segment: {
28207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            swap = true;
28307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicLine(wn.pts(), wt.pts());
28407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicLineIntersection(pts, wn, wt,  ts);
28507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
28607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
28707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        default:
28807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            SkASSERT(0);
28907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    }
29007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    break;
29107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                case SkIntersectionHelper::kQuad_Segment:
29207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    switch (wn.segmentType()) {
29307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kHorizontalLine_Segment:
29407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.quadHorizontal(wt.pts(), wn.left(),
29507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wn.right(), wn.y(), wn.xFlipped());
29607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowQuadLineIntersection(pts, wt, wn, ts);
29707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
29807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kVerticalLine_Segment:
29907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.quadVertical(wt.pts(), wn.top(),
30007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wn.bottom(), wn.x(), wn.yFlipped());
30107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowQuadLineIntersection(pts, wt, wn, ts);
30207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
30307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kLine_Segment: {
30407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.quadLine(wt.pts(), wn.pts());
30507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowQuadLineIntersection(pts, wt, wn, ts);
30607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
30707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
30807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kQuad_Segment: {
30907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.quadQuad(wt.pts(), wn.pts());
31007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowQuadIntersection(pts, wt, wn, ts);
31107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
31207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
31307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kCubic_Segment: {
31407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            swap = true;
31507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicQuad(wn.pts(), wt.pts());
31607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicQuadIntersection(pts, wn, wt, ts);
31707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
31807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
31907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        default:
32007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            SkASSERT(0);
32107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    }
32207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    break;
32307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                case SkIntersectionHelper::kCubic_Segment:
32407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    switch (wn.segmentType()) {
32507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kHorizontalLine_Segment:
32607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicHorizontal(wt.pts(), wn.left(),
32707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wn.right(), wn.y(), wn.xFlipped());
32807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicLineIntersection(pts, wt, wn, ts);
32907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
33007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kVerticalLine_Segment:
33107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicVertical(wt.pts(), wn.top(),
33207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                                    wn.bottom(), wn.x(), wn.yFlipped());
33307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicLineIntersection(pts, wt, wn, ts);
33407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
33507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kLine_Segment: {
33607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicLine(wt.pts(), wn.pts());
33707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicLineIntersection(pts, wt, wn, ts);
33807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
33907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
34007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kQuad_Segment: {
34107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicQuad(wt.pts(), wn.pts());
34207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicQuadIntersection(pts, wt, wn, ts);
34307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
34407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
34507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        case SkIntersectionHelper::kCubic_Segment: {
34607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            pts = ts.cubicCubic(wt.pts(), wn.pts());
34707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            debugShowCubicIntersection(pts, wt, wn, ts);
34807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            break;
34907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        }
35007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        default:
35107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                            SkASSERT(0);
35207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    }
35307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    break;
35407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                default:
35507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    SkASSERT(0);
35607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            }
35707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            if (!foundCommonContour && pts > 0) {
35807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                test->addCross(next);
35907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                next->addCross(test);
36007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                foundCommonContour = true;
36107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            }
36207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            // in addition to recording T values, record matching segment
36307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            if (pts == 2) {
36407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                if (wn.segmentType() <= SkIntersectionHelper::kLine_Segment
36507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        && wt.segmentType() <= SkIntersectionHelper::kLine_Segment) {
3667eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    if (wt.addCoincident(wn, ts, swap)) {
3677eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                        continue;
3687eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    }
3697eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    ts.cleanUpCoincidence();  // prefer (t == 0 or t == 1)
3707eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    pts = 1;
3717eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                } else if (wn.segmentType() >= SkIntersectionHelper::kQuad_Segment
37207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        && wt.segmentType() >= SkIntersectionHelper::kQuad_Segment
37307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                        && ts.isCoincident(0)) {
37407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                    SkASSERT(ts.coincidentUsed() == 2);
3757eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    if (wt.addCoincident(wn, ts, swap)) {
3767eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                        continue;
3777eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    }
3787eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    ts.cleanUpCoincidence();  // prefer (t == 0 or t == 1)
3797eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                    pts = 1;
38007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                }
38107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            }
382570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com            if (pts >= 2) {
383570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com                for (int pt = 0; pt < pts - 1; ++pt) {
384570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com                    const SkDPoint& point = ts.pt(pt);
385570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com                    const SkDPoint& next = ts.pt(pt + 1);
386a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    if (wt.isPartial(ts[swap][pt], ts[swap][pt + 1], point, next)
387a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                            && wn.isPartial(ts[!swap][pt], ts[!swap][pt + 1], point, next)) {
3887eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                        if (!wt.addPartialCoincident(wn, ts, pt, swap)) {
3897eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                            // remove extra point if two map to same float values
3907eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                            ts.cleanUpCoincidence();  // prefer (t == 0 or t == 1)
3917eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                            pts = 1;
3927eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com                        }
393570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com                    }
394570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com                }
395570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com            }
39607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            for (int pt = 0; pt < pts; ++pt) {
39707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1);
39807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1);
39907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                SkPoint point = ts.pt(pt).asSkPoint();
400dac1d17027dcaa5596885a9f333979418b35001ccaryclark                wt.alignTPt(wn, swap, pt, &ts, &point);
401866f4e34a943c115ac372c22123a1520aa5f9b06commit-bot@chromium.org                int testTAt = wt.addT(wn, point, ts[swap][pt]);
402866f4e34a943c115ac372c22123a1520aa5f9b06commit-bot@chromium.org                int nextTAt = wn.addT(wt, point, ts[!swap][pt]);
40307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                wt.addOtherT(testTAt, ts[!swap][pt], nextTAt);
40407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com                wn.addOtherT(nextTAt, ts[swap][pt], testTAt);
40507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            }
40607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        } while (wn.advance());
40707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    } while (wt.advance());
40807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    return true;
40907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
41007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
41107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comvoid AddSelfIntersectTs(SkOpContour* test) {
41207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkIntersectionHelper wt;
41307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    wt.init(test);
41407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    do {
41507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        if (wt.segmentType() != SkIntersectionHelper::kCubic_Segment) {
41607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            continue;
41707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        }
41807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkIntersections ts;
41907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        int pts = ts.cubic(wt.pts());
42007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        debugShowCubicIntersection(pts, wt, ts);
42107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        if (!pts) {
42207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com            continue;
42307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        }
42407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkASSERT(pts == 1);
42507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkASSERT(ts[0][0] >= 0 && ts[0][0] <= 1);
42607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkASSERT(ts[1][0] >= 0 && ts[1][0] <= 1);
42707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkPoint point = ts.pt(0).asSkPoint();
4284431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        int testTAt = wt.addSelfT(point, ts[0][0]);
4294431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        int nextTAt = wt.addSelfT(point, ts[1][0]);
43007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        wt.addOtherT(testTAt, ts[1][0], nextTAt);
43107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        wt.addOtherT(nextTAt, ts[0][0], testTAt);
43207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    } while (wt.advance());
43307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
43407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
43507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// resolve any coincident pairs found while intersecting, and
43607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// see if coincidence is formed by clipping non-concident segments
437d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.comvoid CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
43807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    int contourCount = (*contourList).count();
43907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
44007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkOpContour* contour = (*contourList)[cIndex];
441dac1d17027dcaa5596885a9f333979418b35001ccaryclark        contour->resolveNearCoincidence();
442dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
443dac1d17027dcaa5596885a9f333979418b35001ccaryclark    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
444dac1d17027dcaa5596885a9f333979418b35001ccaryclark        SkOpContour* contour = (*contourList)[cIndex];
44507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        contour->addCoincidentPoints();
44607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
44707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
44807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkOpContour* contour = (*contourList)[cIndex];
44907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        contour->calcCoincidentWinding();
45007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
45107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
45207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        SkOpContour* contour = (*contourList)[cIndex];
453570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        contour->calcPartialCoincidentWinding();
45407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
45507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}
456