123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579 |
- /*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "src/pathops/SkAddIntersections.h"
- #include "src/pathops/SkOpCoincidence.h"
- #include "src/pathops/SkPathOpsBounds.h"
- #include <utility>
- #if DEBUG_ADD_INTERSECTING_TS
- static void debugShowLineIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " LINE_DEBUG_STR " " LINE_DEBUG_STR "\n",
- __FUNCTION__, LINE_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " LINE_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], LINE_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
- if (pts == 2) {
- SkDebugf(" " T_DEBUG_STR(wtTs, 1) " " PT_DEBUG_STR, i[0][1], PT_DEBUG_DATA(i, 1));
- }
- SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
- if (pts == 2) {
- SkDebugf(" " T_DEBUG_STR(wnTs, 1), i[1][1]);
- }
- SkDebugf("\n");
- }
- static void debugShowQuadLineIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn,
- const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " QUAD_DEBUG_STR " " LINE_DEBUG_STR "\n",
- __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowQuadIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " QUAD_DEBUG_STR " " QUAD_DEBUG_STR "\n",
- __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowConicLineIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " CONIC_DEBUG_STR " " LINE_DEBUG_STR "\n",
- __FUNCTION__, CONIC_DEBUG_DATA(wt.pts(), wt.weight()), LINE_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CONIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], CONIC_DEBUG_DATA(wt.pts(), wt.weight()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowConicQuadIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " CONIC_DEBUG_STR " " QUAD_DEBUG_STR "\n",
- __FUNCTION__, CONIC_DEBUG_DATA(wt.pts(), wt.weight()), QUAD_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CONIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], CONIC_DEBUG_DATA(wt.pts(), wt.weight()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowConicIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " CONIC_DEBUG_STR " " CONIC_DEBUG_STR "\n",
- __FUNCTION__, CONIC_DEBUG_DATA(wt.pts(), wt.weight()),
- CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CONIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], CONIC_DEBUG_DATA(wt.pts(), wt.weight()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " CONIC_DEBUG_STR, i[1][0], CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowCubicLineIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " LINE_DEBUG_STR "\n",
- __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowCubicQuadIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " QUAD_DEBUG_STR "\n",
- __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowCubicConicIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " CONIC_DEBUG_STR "\n",
- __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " CONIC_DEBUG_STR, i[1][0], CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
- const SkIntersectionHelper& wn, const SkIntersections& i) {
- SkASSERT(i.used() == pts);
- if (!pts) {
- SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " CUBIC_DEBUG_STR "\n",
- __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), CUBIC_DEBUG_DATA(wn.pts()));
- return;
- }
- SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
- i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
- }
- SkDebugf(" wnTs[0]=%g " CUBIC_DEBUG_STR, i[1][0], CUBIC_DEBUG_DATA(wn.pts()));
- for (int n = 1; n < pts; ++n) {
- SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
- }
- SkDebugf("\n");
- }
- #else
- static void debugShowLineIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowQuadLineIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowQuadIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowConicLineIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowConicQuadIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowConicIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowCubicLineIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowCubicQuadIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowCubicConicIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
- const SkIntersectionHelper& , const SkIntersections& ) {
- }
- #endif
- bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coincidence) {
- if (test != next) {
- if (AlmostLessUlps(test->bounds().fBottom, next->bounds().fTop)) {
- return false;
- }
- // OPTIMIZATION: outset contour bounds a smidgen instead?
- if (!SkPathOpsBounds::Intersects(test->bounds(), next->bounds())) {
- return true;
- }
- }
- SkIntersectionHelper wt;
- wt.init(test);
- do {
- SkIntersectionHelper wn;
- wn.init(next);
- test->debugValidate();
- next->debugValidate();
- if (test == next && !wn.startAfter(wt)) {
- continue;
- }
- do {
- if (!SkPathOpsBounds::Intersects(wt.bounds(), wn.bounds())) {
- continue;
- }
- int pts = 0;
- SkIntersections ts { SkDEBUGCODE(test->globalState()) };
- bool swap = false;
- SkDQuad quad1, quad2;
- SkDConic conic1, conic2;
- SkDCubic cubic1, cubic2;
- switch (wt.segmentType()) {
- case SkIntersectionHelper::kHorizontalLine_Segment:
- swap = true;
- switch (wn.segmentType()) {
- case SkIntersectionHelper::kHorizontalLine_Segment:
- case SkIntersectionHelper::kVerticalLine_Segment:
- case SkIntersectionHelper::kLine_Segment:
- pts = ts.lineHorizontal(wn.pts(), wt.left(),
- wt.right(), wt.y(), wt.xFlipped());
- debugShowLineIntersection(pts, wn, wt, ts);
- break;
- case SkIntersectionHelper::kQuad_Segment:
- pts = ts.quadHorizontal(wn.pts(), wt.left(),
- wt.right(), wt.y(), wt.xFlipped());
- debugShowQuadLineIntersection(pts, wn, wt, ts);
- break;
- case SkIntersectionHelper::kConic_Segment:
- pts = ts.conicHorizontal(wn.pts(), wn.weight(), wt.left(),
- wt.right(), wt.y(), wt.xFlipped());
- debugShowConicLineIntersection(pts, wn, wt, ts);
- break;
- case SkIntersectionHelper::kCubic_Segment:
- pts = ts.cubicHorizontal(wn.pts(), wt.left(),
- wt.right(), wt.y(), wt.xFlipped());
- debugShowCubicLineIntersection(pts, wn, wt, ts);
- break;
- default:
- SkASSERT(0);
- }
- break;
- case SkIntersectionHelper::kVerticalLine_Segment:
- swap = true;
- switch (wn.segmentType()) {
- case SkIntersectionHelper::kHorizontalLine_Segment:
- case SkIntersectionHelper::kVerticalLine_Segment:
- case SkIntersectionHelper::kLine_Segment: {
- pts = ts.lineVertical(wn.pts(), wt.top(),
- wt.bottom(), wt.x(), wt.yFlipped());
- debugShowLineIntersection(pts, wn, wt, ts);
- break;
- }
- case SkIntersectionHelper::kQuad_Segment: {
- pts = ts.quadVertical(wn.pts(), wt.top(),
- wt.bottom(), wt.x(), wt.yFlipped());
- debugShowQuadLineIntersection(pts, wn, wt, ts);
- break;
- }
- case SkIntersectionHelper::kConic_Segment: {
- pts = ts.conicVertical(wn.pts(), wn.weight(), wt.top(),
- wt.bottom(), wt.x(), wt.yFlipped());
- debugShowConicLineIntersection(pts, wn, wt, ts);
- break;
- }
- case SkIntersectionHelper::kCubic_Segment: {
- pts = ts.cubicVertical(wn.pts(), wt.top(),
- wt.bottom(), wt.x(), wt.yFlipped());
- debugShowCubicLineIntersection(pts, wn, wt, ts);
- break;
- }
- default:
- SkASSERT(0);
- }
- break;
- case SkIntersectionHelper::kLine_Segment:
- switch (wn.segmentType()) {
- case SkIntersectionHelper::kHorizontalLine_Segment:
- pts = ts.lineHorizontal(wt.pts(), wn.left(),
- wn.right(), wn.y(), wn.xFlipped());
- debugShowLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kVerticalLine_Segment:
- pts = ts.lineVertical(wt.pts(), wn.top(),
- wn.bottom(), wn.x(), wn.yFlipped());
- debugShowLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kLine_Segment:
- pts = ts.lineLine(wt.pts(), wn.pts());
- debugShowLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kQuad_Segment:
- swap = true;
- pts = ts.quadLine(wn.pts(), wt.pts());
- debugShowQuadLineIntersection(pts, wn, wt, ts);
- break;
- case SkIntersectionHelper::kConic_Segment:
- swap = true;
- pts = ts.conicLine(wn.pts(), wn.weight(), wt.pts());
- debugShowConicLineIntersection(pts, wn, wt, ts);
- break;
- case SkIntersectionHelper::kCubic_Segment:
- swap = true;
- pts = ts.cubicLine(wn.pts(), wt.pts());
- debugShowCubicLineIntersection(pts, wn, wt, ts);
- break;
- default:
- SkASSERT(0);
- }
- break;
- case SkIntersectionHelper::kQuad_Segment:
- switch (wn.segmentType()) {
- case SkIntersectionHelper::kHorizontalLine_Segment:
- pts = ts.quadHorizontal(wt.pts(), wn.left(),
- wn.right(), wn.y(), wn.xFlipped());
- debugShowQuadLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kVerticalLine_Segment:
- pts = ts.quadVertical(wt.pts(), wn.top(),
- wn.bottom(), wn.x(), wn.yFlipped());
- debugShowQuadLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kLine_Segment:
- pts = ts.quadLine(wt.pts(), wn.pts());
- debugShowQuadLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kQuad_Segment: {
- pts = ts.intersect(quad1.set(wt.pts()), quad2.set(wn.pts()));
- debugShowQuadIntersection(pts, wt, wn, ts);
- break;
- }
- case SkIntersectionHelper::kConic_Segment: {
- swap = true;
- pts = ts.intersect(conic2.set(wn.pts(), wn.weight()),
- quad1.set(wt.pts()));
- debugShowConicQuadIntersection(pts, wn, wt, ts);
- break;
- }
- case SkIntersectionHelper::kCubic_Segment: {
- swap = true;
- pts = ts.intersect(cubic2.set(wn.pts()), quad1.set(wt.pts()));
- debugShowCubicQuadIntersection(pts, wn, wt, ts);
- break;
- }
- default:
- SkASSERT(0);
- }
- break;
- case SkIntersectionHelper::kConic_Segment:
- switch (wn.segmentType()) {
- case SkIntersectionHelper::kHorizontalLine_Segment:
- pts = ts.conicHorizontal(wt.pts(), wt.weight(), wn.left(),
- wn.right(), wn.y(), wn.xFlipped());
- debugShowConicLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kVerticalLine_Segment:
- pts = ts.conicVertical(wt.pts(), wt.weight(), wn.top(),
- wn.bottom(), wn.x(), wn.yFlipped());
- debugShowConicLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kLine_Segment:
- pts = ts.conicLine(wt.pts(), wt.weight(), wn.pts());
- debugShowConicLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kQuad_Segment: {
- pts = ts.intersect(conic1.set(wt.pts(), wt.weight()),
- quad2.set(wn.pts()));
- debugShowConicQuadIntersection(pts, wt, wn, ts);
- break;
- }
- case SkIntersectionHelper::kConic_Segment: {
- pts = ts.intersect(conic1.set(wt.pts(), wt.weight()),
- conic2.set(wn.pts(), wn.weight()));
- debugShowConicIntersection(pts, wt, wn, ts);
- break;
- }
- case SkIntersectionHelper::kCubic_Segment: {
- swap = true;
- pts = ts.intersect(cubic2.set(wn.pts()
- SkDEBUGPARAMS(ts.globalState())),
- conic1.set(wt.pts(), wt.weight()
- SkDEBUGPARAMS(ts.globalState())));
- debugShowCubicConicIntersection(pts, wn, wt, ts);
- break;
- }
- }
- break;
- case SkIntersectionHelper::kCubic_Segment:
- switch (wn.segmentType()) {
- case SkIntersectionHelper::kHorizontalLine_Segment:
- pts = ts.cubicHorizontal(wt.pts(), wn.left(),
- wn.right(), wn.y(), wn.xFlipped());
- debugShowCubicLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kVerticalLine_Segment:
- pts = ts.cubicVertical(wt.pts(), wn.top(),
- wn.bottom(), wn.x(), wn.yFlipped());
- debugShowCubicLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kLine_Segment:
- pts = ts.cubicLine(wt.pts(), wn.pts());
- debugShowCubicLineIntersection(pts, wt, wn, ts);
- break;
- case SkIntersectionHelper::kQuad_Segment: {
- pts = ts.intersect(cubic1.set(wt.pts()), quad2.set(wn.pts()));
- debugShowCubicQuadIntersection(pts, wt, wn, ts);
- break;
- }
- case SkIntersectionHelper::kConic_Segment: {
- pts = ts.intersect(cubic1.set(wt.pts()
- SkDEBUGPARAMS(ts.globalState())),
- conic2.set(wn.pts(), wn.weight()
- SkDEBUGPARAMS(ts.globalState())));
- debugShowCubicConicIntersection(pts, wt, wn, ts);
- break;
- }
- case SkIntersectionHelper::kCubic_Segment: {
- pts = ts.intersect(cubic1.set(wt.pts()), cubic2.set(wn.pts()));
- debugShowCubicIntersection(pts, wt, wn, ts);
- break;
- }
- default:
- SkASSERT(0);
- }
- break;
- default:
- SkASSERT(0);
- }
- #if DEBUG_T_SECT_LOOP_COUNT
- test->globalState()->debugAddLoopCount(&ts, wt, wn);
- #endif
- int coinIndex = -1;
- SkOpPtT* coinPtT[2];
- for (int pt = 0; pt < pts; ++pt) {
- SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1);
- SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1);
- wt.segment()->debugValidate();
- // if t value is used to compute pt in addT, error may creep in and
- // rect intersections may result in non-rects. if pt value from intersection
- // is passed in, current tests break. As a workaround, pass in pt
- // value from intersection only if pt.x and pt.y is integral
- SkPoint iPt = ts.pt(pt).asSkPoint();
- bool iPtIsIntegral = iPt.fX == floor(iPt.fX) && iPt.fY == floor(iPt.fY);
- SkOpPtT* testTAt = iPtIsIntegral ? wt.segment()->addT(ts[swap][pt], iPt)
- : wt.segment()->addT(ts[swap][pt]);
- wn.segment()->debugValidate();
- SkOpPtT* nextTAt = iPtIsIntegral ? wn.segment()->addT(ts[!swap][pt], iPt)
- : wn.segment()->addT(ts[!swap][pt]);
- if (!testTAt->contains(nextTAt)) {
- SkOpPtT* oppPrev = testTAt->oppPrev(nextTAt); // Returns nullptr if pair
- if (oppPrev) { // already share a pt-t loop.
- testTAt->span()->mergeMatches(nextTAt->span());
- testTAt->addOpp(nextTAt, oppPrev);
- }
- if (testTAt->fPt != nextTAt->fPt) {
- testTAt->span()->unaligned();
- nextTAt->span()->unaligned();
- }
- wt.segment()->debugValidate();
- wn.segment()->debugValidate();
- }
- if (!ts.isCoincident(pt)) {
- continue;
- }
- if (coinIndex < 0) {
- coinPtT[0] = testTAt;
- coinPtT[1] = nextTAt;
- coinIndex = pt;
- continue;
- }
- if (coinPtT[0]->span() == testTAt->span()) {
- coinIndex = -1;
- continue;
- }
- if (coinPtT[1]->span() == nextTAt->span()) {
- coinIndex = -1; // coincidence span collapsed
- continue;
- }
- if (swap) {
- using std::swap;
- swap(coinPtT[0], coinPtT[1]);
- swap(testTAt, nextTAt);
- }
- SkASSERT(coincidence->globalState()->debugSkipAssert()
- || coinPtT[0]->span()->t() < testTAt->span()->t());
- if (coinPtT[0]->span()->deleted()) {
- coinIndex = -1;
- continue;
- }
- if (testTAt->span()->deleted()) {
- coinIndex = -1;
- continue;
- }
- coincidence->add(coinPtT[0], testTAt, coinPtT[1], nextTAt);
- wt.segment()->debugValidate();
- wn.segment()->debugValidate();
- coinIndex = -1;
- }
- SkOPOBJASSERT(coincidence, coinIndex < 0); // expect coincidence to be paired
- } while (wn.advance());
- } while (wt.advance());
- return true;
- }
|