1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2012 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkAddIntersections.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkIntersectionHelper.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkIntersections.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkOpCoincidence.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkOpContour.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkOpSegment.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkOpSpan.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsBounds.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsConic.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsCubic.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsPoint.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsQuad.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsTypes.h"
25*c8dee2aaSAndroid Build Coastguard Worker
26*c8dee2aaSAndroid Build Coastguard Worker #include <cmath>
27*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_ADD_INTERSECTING_TS
30*c8dee2aaSAndroid Build Coastguard Worker
debugShowLineIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)31*c8dee2aaSAndroid Build Coastguard Worker static void debugShowLineIntersection(int pts, const SkIntersectionHelper& wt,
32*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
33*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
34*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
35*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " LINE_DEBUG_STR " " LINE_DEBUG_STR "\n",
36*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, LINE_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
37*c8dee2aaSAndroid Build Coastguard Worker return;
38*c8dee2aaSAndroid Build Coastguard Worker }
39*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " LINE_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
40*c8dee2aaSAndroid Build Coastguard Worker i[0][0], LINE_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
41*c8dee2aaSAndroid Build Coastguard Worker if (pts == 2) {
42*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " T_DEBUG_STR(wtTs, 1) " " PT_DEBUG_STR, i[0][1], PT_DEBUG_DATA(i, 1));
43*c8dee2aaSAndroid Build Coastguard Worker }
44*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
45*c8dee2aaSAndroid Build Coastguard Worker if (pts == 2) {
46*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " T_DEBUG_STR(wnTs, 1), i[1][1]);
47*c8dee2aaSAndroid Build Coastguard Worker }
48*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
49*c8dee2aaSAndroid Build Coastguard Worker }
50*c8dee2aaSAndroid Build Coastguard Worker
debugShowQuadLineIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)51*c8dee2aaSAndroid Build Coastguard Worker static void debugShowQuadLineIntersection(int pts, const SkIntersectionHelper& wt,
52*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn,
53*c8dee2aaSAndroid Build Coastguard Worker const SkIntersections& i) {
54*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
55*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
56*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " QUAD_DEBUG_STR " " LINE_DEBUG_STR "\n",
57*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
58*c8dee2aaSAndroid Build Coastguard Worker return;
59*c8dee2aaSAndroid Build Coastguard Worker }
60*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
61*c8dee2aaSAndroid Build Coastguard Worker i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
62*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
63*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
64*c8dee2aaSAndroid Build Coastguard Worker }
65*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
66*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
67*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
68*c8dee2aaSAndroid Build Coastguard Worker }
69*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
70*c8dee2aaSAndroid Build Coastguard Worker }
71*c8dee2aaSAndroid Build Coastguard Worker
debugShowQuadIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)72*c8dee2aaSAndroid Build Coastguard Worker static void debugShowQuadIntersection(int pts, const SkIntersectionHelper& wt,
73*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
74*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
75*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
76*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " QUAD_DEBUG_STR " " QUAD_DEBUG_STR "\n",
77*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
78*c8dee2aaSAndroid Build Coastguard Worker return;
79*c8dee2aaSAndroid Build Coastguard Worker }
80*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
81*c8dee2aaSAndroid Build Coastguard Worker i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
82*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
83*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
86*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
87*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
88*c8dee2aaSAndroid Build Coastguard Worker }
89*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker
debugShowConicLineIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)92*c8dee2aaSAndroid Build Coastguard Worker static void debugShowConicLineIntersection(int pts, const SkIntersectionHelper& wt,
93*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
94*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
95*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
96*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " CONIC_DEBUG_STR " " LINE_DEBUG_STR "\n",
97*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, CONIC_DEBUG_DATA(wt.pts(), wt.weight()), LINE_DEBUG_DATA(wn.pts()));
98*c8dee2aaSAndroid Build Coastguard Worker return;
99*c8dee2aaSAndroid Build Coastguard Worker }
100*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CONIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
101*c8dee2aaSAndroid Build Coastguard Worker i[0][0], CONIC_DEBUG_DATA(wt.pts(), wt.weight()), PT_DEBUG_DATA(i, 0));
102*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
103*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
104*c8dee2aaSAndroid Build Coastguard Worker }
105*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
106*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
107*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
110*c8dee2aaSAndroid Build Coastguard Worker }
111*c8dee2aaSAndroid Build Coastguard Worker
debugShowConicQuadIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)112*c8dee2aaSAndroid Build Coastguard Worker static void debugShowConicQuadIntersection(int pts, const SkIntersectionHelper& wt,
113*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
114*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
115*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
116*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " CONIC_DEBUG_STR " " QUAD_DEBUG_STR "\n",
117*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, CONIC_DEBUG_DATA(wt.pts(), wt.weight()), QUAD_DEBUG_DATA(wn.pts()));
118*c8dee2aaSAndroid Build Coastguard Worker return;
119*c8dee2aaSAndroid Build Coastguard Worker }
120*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CONIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
121*c8dee2aaSAndroid Build Coastguard Worker i[0][0], CONIC_DEBUG_DATA(wt.pts(), wt.weight()), PT_DEBUG_DATA(i, 0));
122*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
123*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
124*c8dee2aaSAndroid Build Coastguard Worker }
125*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
126*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
127*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
128*c8dee2aaSAndroid Build Coastguard Worker }
129*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
130*c8dee2aaSAndroid Build Coastguard Worker }
131*c8dee2aaSAndroid Build Coastguard Worker
debugShowConicIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)132*c8dee2aaSAndroid Build Coastguard Worker static void debugShowConicIntersection(int pts, const SkIntersectionHelper& wt,
133*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
134*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
135*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
136*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " CONIC_DEBUG_STR " " CONIC_DEBUG_STR "\n",
137*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, CONIC_DEBUG_DATA(wt.pts(), wt.weight()),
138*c8dee2aaSAndroid Build Coastguard Worker CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
139*c8dee2aaSAndroid Build Coastguard Worker return;
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CONIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
142*c8dee2aaSAndroid Build Coastguard Worker i[0][0], CONIC_DEBUG_DATA(wt.pts(), wt.weight()), PT_DEBUG_DATA(i, 0));
143*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
144*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
145*c8dee2aaSAndroid Build Coastguard Worker }
146*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " CONIC_DEBUG_STR, i[1][0], CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
147*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
148*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
149*c8dee2aaSAndroid Build Coastguard Worker }
150*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
151*c8dee2aaSAndroid Build Coastguard Worker }
152*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicLineIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)153*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicLineIntersection(int pts, const SkIntersectionHelper& wt,
154*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
155*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
156*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
157*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " LINE_DEBUG_STR "\n",
158*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
159*c8dee2aaSAndroid Build Coastguard Worker return;
160*c8dee2aaSAndroid Build Coastguard Worker }
161*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
162*c8dee2aaSAndroid Build Coastguard Worker i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
163*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
164*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
165*c8dee2aaSAndroid Build Coastguard Worker }
166*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
167*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
168*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
169*c8dee2aaSAndroid Build Coastguard Worker }
170*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
171*c8dee2aaSAndroid Build Coastguard Worker }
172*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicQuadIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)173*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicQuadIntersection(int pts, const SkIntersectionHelper& wt,
174*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
175*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
176*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
177*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " QUAD_DEBUG_STR "\n",
178*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
179*c8dee2aaSAndroid Build Coastguard Worker return;
180*c8dee2aaSAndroid Build Coastguard Worker }
181*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
182*c8dee2aaSAndroid Build Coastguard Worker i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
183*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
184*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
185*c8dee2aaSAndroid Build Coastguard Worker }
186*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
187*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
188*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
189*c8dee2aaSAndroid Build Coastguard Worker }
190*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
191*c8dee2aaSAndroid Build Coastguard Worker }
192*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicConicIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)193*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicConicIntersection(int pts, const SkIntersectionHelper& wt,
194*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
195*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
196*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
197*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " CONIC_DEBUG_STR "\n",
198*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
199*c8dee2aaSAndroid Build Coastguard Worker return;
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
202*c8dee2aaSAndroid Build Coastguard Worker i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
203*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
204*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
205*c8dee2aaSAndroid Build Coastguard Worker }
206*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " CONIC_DEBUG_STR, i[1][0], CONIC_DEBUG_DATA(wn.pts(), wn.weight()));
207*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
208*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
209*c8dee2aaSAndroid Build Coastguard Worker }
210*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
211*c8dee2aaSAndroid Build Coastguard Worker }
212*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicIntersection(int pts,const SkIntersectionHelper & wt,const SkIntersectionHelper & wn,const SkIntersections & i)213*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
214*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& wn, const SkIntersections& i) {
215*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i.used() == pts);
216*c8dee2aaSAndroid Build Coastguard Worker if (!pts) {
217*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " CUBIC_DEBUG_STR "\n",
218*c8dee2aaSAndroid Build Coastguard Worker __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), CUBIC_DEBUG_DATA(wn.pts()));
219*c8dee2aaSAndroid Build Coastguard Worker return;
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
222*c8dee2aaSAndroid Build Coastguard Worker i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
223*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
224*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
225*c8dee2aaSAndroid Build Coastguard Worker }
226*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" wnTs[0]=%g " CUBIC_DEBUG_STR, i[1][0], CUBIC_DEBUG_DATA(wn.pts()));
227*c8dee2aaSAndroid Build Coastguard Worker for (int n = 1; n < pts; ++n) {
228*c8dee2aaSAndroid Build Coastguard Worker SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
229*c8dee2aaSAndroid Build Coastguard Worker }
230*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\n");
231*c8dee2aaSAndroid Build Coastguard Worker }
232*c8dee2aaSAndroid Build Coastguard Worker
233*c8dee2aaSAndroid Build Coastguard Worker #else
debugShowLineIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)234*c8dee2aaSAndroid Build Coastguard Worker static void debugShowLineIntersection(int , const SkIntersectionHelper& ,
235*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker
debugShowQuadLineIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)238*c8dee2aaSAndroid Build Coastguard Worker static void debugShowQuadLineIntersection(int , const SkIntersectionHelper& ,
239*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
240*c8dee2aaSAndroid Build Coastguard Worker }
241*c8dee2aaSAndroid Build Coastguard Worker
debugShowQuadIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)242*c8dee2aaSAndroid Build Coastguard Worker static void debugShowQuadIntersection(int , const SkIntersectionHelper& ,
243*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
244*c8dee2aaSAndroid Build Coastguard Worker }
245*c8dee2aaSAndroid Build Coastguard Worker
debugShowConicLineIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)246*c8dee2aaSAndroid Build Coastguard Worker static void debugShowConicLineIntersection(int , const SkIntersectionHelper& ,
247*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
248*c8dee2aaSAndroid Build Coastguard Worker }
249*c8dee2aaSAndroid Build Coastguard Worker
debugShowConicQuadIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)250*c8dee2aaSAndroid Build Coastguard Worker static void debugShowConicQuadIntersection(int , const SkIntersectionHelper& ,
251*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
252*c8dee2aaSAndroid Build Coastguard Worker }
253*c8dee2aaSAndroid Build Coastguard Worker
debugShowConicIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)254*c8dee2aaSAndroid Build Coastguard Worker static void debugShowConicIntersection(int , const SkIntersectionHelper& ,
255*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
256*c8dee2aaSAndroid Build Coastguard Worker }
257*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicLineIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)258*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicLineIntersection(int , const SkIntersectionHelper& ,
259*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicQuadIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)262*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicQuadIntersection(int , const SkIntersectionHelper& ,
263*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
264*c8dee2aaSAndroid Build Coastguard Worker }
265*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicConicIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)266*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicConicIntersection(int , const SkIntersectionHelper& ,
267*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
268*c8dee2aaSAndroid Build Coastguard Worker }
269*c8dee2aaSAndroid Build Coastguard Worker
debugShowCubicIntersection(int,const SkIntersectionHelper &,const SkIntersectionHelper &,const SkIntersections &)270*c8dee2aaSAndroid Build Coastguard Worker static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
271*c8dee2aaSAndroid Build Coastguard Worker const SkIntersectionHelper& , const SkIntersections& ) {
272*c8dee2aaSAndroid Build Coastguard Worker }
273*c8dee2aaSAndroid Build Coastguard Worker #endif
274*c8dee2aaSAndroid Build Coastguard Worker
AddIntersectTs(SkOpContour * test,SkOpContour * next,SkOpCoincidence * coincidence)275*c8dee2aaSAndroid Build Coastguard Worker bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coincidence) {
276*c8dee2aaSAndroid Build Coastguard Worker if (test != next) {
277*c8dee2aaSAndroid Build Coastguard Worker if (AlmostLessUlps(test->bounds().fBottom, next->bounds().fTop)) {
278*c8dee2aaSAndroid Build Coastguard Worker return false;
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker // OPTIMIZATION: outset contour bounds a smidgen instead?
281*c8dee2aaSAndroid Build Coastguard Worker if (!SkPathOpsBounds::Intersects(test->bounds(), next->bounds())) {
282*c8dee2aaSAndroid Build Coastguard Worker return true;
283*c8dee2aaSAndroid Build Coastguard Worker }
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker SkIntersectionHelper wt;
286*c8dee2aaSAndroid Build Coastguard Worker wt.init(test);
287*c8dee2aaSAndroid Build Coastguard Worker do {
288*c8dee2aaSAndroid Build Coastguard Worker SkIntersectionHelper wn;
289*c8dee2aaSAndroid Build Coastguard Worker wn.init(next);
290*c8dee2aaSAndroid Build Coastguard Worker test->debugValidate();
291*c8dee2aaSAndroid Build Coastguard Worker next->debugValidate();
292*c8dee2aaSAndroid Build Coastguard Worker if (test == next && !wn.startAfter(wt)) {
293*c8dee2aaSAndroid Build Coastguard Worker continue;
294*c8dee2aaSAndroid Build Coastguard Worker }
295*c8dee2aaSAndroid Build Coastguard Worker do {
296*c8dee2aaSAndroid Build Coastguard Worker if (!SkPathOpsBounds::Intersects(wt.bounds(), wn.bounds())) {
297*c8dee2aaSAndroid Build Coastguard Worker continue;
298*c8dee2aaSAndroid Build Coastguard Worker }
299*c8dee2aaSAndroid Build Coastguard Worker int pts = 0;
300*c8dee2aaSAndroid Build Coastguard Worker SkIntersections ts { SkDEBUGCODE(test->globalState()) };
301*c8dee2aaSAndroid Build Coastguard Worker bool swap = false;
302*c8dee2aaSAndroid Build Coastguard Worker SkDQuad quad1, quad2;
303*c8dee2aaSAndroid Build Coastguard Worker SkDConic conic1, conic2;
304*c8dee2aaSAndroid Build Coastguard Worker SkDCubic cubic1, cubic2;
305*c8dee2aaSAndroid Build Coastguard Worker switch (wt.segmentType()) {
306*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kHorizontalLine_Segment:
307*c8dee2aaSAndroid Build Coastguard Worker swap = true;
308*c8dee2aaSAndroid Build Coastguard Worker switch (wn.segmentType()) {
309*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kHorizontalLine_Segment:
310*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kVerticalLine_Segment:
311*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kLine_Segment:
312*c8dee2aaSAndroid Build Coastguard Worker pts = ts.lineHorizontal(wn.pts(), wt.left(),
313*c8dee2aaSAndroid Build Coastguard Worker wt.right(), wt.y(), wt.xFlipped());
314*c8dee2aaSAndroid Build Coastguard Worker debugShowLineIntersection(pts, wn, wt, ts);
315*c8dee2aaSAndroid Build Coastguard Worker break;
316*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kQuad_Segment:
317*c8dee2aaSAndroid Build Coastguard Worker pts = ts.quadHorizontal(wn.pts(), wt.left(),
318*c8dee2aaSAndroid Build Coastguard Worker wt.right(), wt.y(), wt.xFlipped());
319*c8dee2aaSAndroid Build Coastguard Worker debugShowQuadLineIntersection(pts, wn, wt, ts);
320*c8dee2aaSAndroid Build Coastguard Worker break;
321*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kConic_Segment:
322*c8dee2aaSAndroid Build Coastguard Worker pts = ts.conicHorizontal(wn.pts(), wn.weight(), wt.left(),
323*c8dee2aaSAndroid Build Coastguard Worker wt.right(), wt.y(), wt.xFlipped());
324*c8dee2aaSAndroid Build Coastguard Worker debugShowConicLineIntersection(pts, wn, wt, ts);
325*c8dee2aaSAndroid Build Coastguard Worker break;
326*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kCubic_Segment:
327*c8dee2aaSAndroid Build Coastguard Worker pts = ts.cubicHorizontal(wn.pts(), wt.left(),
328*c8dee2aaSAndroid Build Coastguard Worker wt.right(), wt.y(), wt.xFlipped());
329*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicLineIntersection(pts, wn, wt, ts);
330*c8dee2aaSAndroid Build Coastguard Worker break;
331*c8dee2aaSAndroid Build Coastguard Worker default:
332*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(0);
333*c8dee2aaSAndroid Build Coastguard Worker }
334*c8dee2aaSAndroid Build Coastguard Worker break;
335*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kVerticalLine_Segment:
336*c8dee2aaSAndroid Build Coastguard Worker swap = true;
337*c8dee2aaSAndroid Build Coastguard Worker switch (wn.segmentType()) {
338*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kHorizontalLine_Segment:
339*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kVerticalLine_Segment:
340*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kLine_Segment: {
341*c8dee2aaSAndroid Build Coastguard Worker pts = ts.lineVertical(wn.pts(), wt.top(),
342*c8dee2aaSAndroid Build Coastguard Worker wt.bottom(), wt.x(), wt.yFlipped());
343*c8dee2aaSAndroid Build Coastguard Worker debugShowLineIntersection(pts, wn, wt, ts);
344*c8dee2aaSAndroid Build Coastguard Worker break;
345*c8dee2aaSAndroid Build Coastguard Worker }
346*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kQuad_Segment: {
347*c8dee2aaSAndroid Build Coastguard Worker pts = ts.quadVertical(wn.pts(), wt.top(),
348*c8dee2aaSAndroid Build Coastguard Worker wt.bottom(), wt.x(), wt.yFlipped());
349*c8dee2aaSAndroid Build Coastguard Worker debugShowQuadLineIntersection(pts, wn, wt, ts);
350*c8dee2aaSAndroid Build Coastguard Worker break;
351*c8dee2aaSAndroid Build Coastguard Worker }
352*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kConic_Segment: {
353*c8dee2aaSAndroid Build Coastguard Worker pts = ts.conicVertical(wn.pts(), wn.weight(), wt.top(),
354*c8dee2aaSAndroid Build Coastguard Worker wt.bottom(), wt.x(), wt.yFlipped());
355*c8dee2aaSAndroid Build Coastguard Worker debugShowConicLineIntersection(pts, wn, wt, ts);
356*c8dee2aaSAndroid Build Coastguard Worker break;
357*c8dee2aaSAndroid Build Coastguard Worker }
358*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kCubic_Segment: {
359*c8dee2aaSAndroid Build Coastguard Worker pts = ts.cubicVertical(wn.pts(), wt.top(),
360*c8dee2aaSAndroid Build Coastguard Worker wt.bottom(), wt.x(), wt.yFlipped());
361*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicLineIntersection(pts, wn, wt, ts);
362*c8dee2aaSAndroid Build Coastguard Worker break;
363*c8dee2aaSAndroid Build Coastguard Worker }
364*c8dee2aaSAndroid Build Coastguard Worker default:
365*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(0);
366*c8dee2aaSAndroid Build Coastguard Worker }
367*c8dee2aaSAndroid Build Coastguard Worker break;
368*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kLine_Segment:
369*c8dee2aaSAndroid Build Coastguard Worker switch (wn.segmentType()) {
370*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kHorizontalLine_Segment:
371*c8dee2aaSAndroid Build Coastguard Worker pts = ts.lineHorizontal(wt.pts(), wn.left(),
372*c8dee2aaSAndroid Build Coastguard Worker wn.right(), wn.y(), wn.xFlipped());
373*c8dee2aaSAndroid Build Coastguard Worker debugShowLineIntersection(pts, wt, wn, ts);
374*c8dee2aaSAndroid Build Coastguard Worker break;
375*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kVerticalLine_Segment:
376*c8dee2aaSAndroid Build Coastguard Worker pts = ts.lineVertical(wt.pts(), wn.top(),
377*c8dee2aaSAndroid Build Coastguard Worker wn.bottom(), wn.x(), wn.yFlipped());
378*c8dee2aaSAndroid Build Coastguard Worker debugShowLineIntersection(pts, wt, wn, ts);
379*c8dee2aaSAndroid Build Coastguard Worker break;
380*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kLine_Segment:
381*c8dee2aaSAndroid Build Coastguard Worker pts = ts.lineLine(wt.pts(), wn.pts());
382*c8dee2aaSAndroid Build Coastguard Worker debugShowLineIntersection(pts, wt, wn, ts);
383*c8dee2aaSAndroid Build Coastguard Worker break;
384*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kQuad_Segment:
385*c8dee2aaSAndroid Build Coastguard Worker swap = true;
386*c8dee2aaSAndroid Build Coastguard Worker pts = ts.quadLine(wn.pts(), wt.pts());
387*c8dee2aaSAndroid Build Coastguard Worker debugShowQuadLineIntersection(pts, wn, wt, ts);
388*c8dee2aaSAndroid Build Coastguard Worker break;
389*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kConic_Segment:
390*c8dee2aaSAndroid Build Coastguard Worker swap = true;
391*c8dee2aaSAndroid Build Coastguard Worker pts = ts.conicLine(wn.pts(), wn.weight(), wt.pts());
392*c8dee2aaSAndroid Build Coastguard Worker debugShowConicLineIntersection(pts, wn, wt, ts);
393*c8dee2aaSAndroid Build Coastguard Worker break;
394*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kCubic_Segment:
395*c8dee2aaSAndroid Build Coastguard Worker swap = true;
396*c8dee2aaSAndroid Build Coastguard Worker pts = ts.cubicLine(wn.pts(), wt.pts());
397*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicLineIntersection(pts, wn, wt, ts);
398*c8dee2aaSAndroid Build Coastguard Worker break;
399*c8dee2aaSAndroid Build Coastguard Worker default:
400*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(0);
401*c8dee2aaSAndroid Build Coastguard Worker }
402*c8dee2aaSAndroid Build Coastguard Worker break;
403*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kQuad_Segment:
404*c8dee2aaSAndroid Build Coastguard Worker switch (wn.segmentType()) {
405*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kHorizontalLine_Segment:
406*c8dee2aaSAndroid Build Coastguard Worker pts = ts.quadHorizontal(wt.pts(), wn.left(),
407*c8dee2aaSAndroid Build Coastguard Worker wn.right(), wn.y(), wn.xFlipped());
408*c8dee2aaSAndroid Build Coastguard Worker debugShowQuadLineIntersection(pts, wt, wn, ts);
409*c8dee2aaSAndroid Build Coastguard Worker break;
410*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kVerticalLine_Segment:
411*c8dee2aaSAndroid Build Coastguard Worker pts = ts.quadVertical(wt.pts(), wn.top(),
412*c8dee2aaSAndroid Build Coastguard Worker wn.bottom(), wn.x(), wn.yFlipped());
413*c8dee2aaSAndroid Build Coastguard Worker debugShowQuadLineIntersection(pts, wt, wn, ts);
414*c8dee2aaSAndroid Build Coastguard Worker break;
415*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kLine_Segment:
416*c8dee2aaSAndroid Build Coastguard Worker pts = ts.quadLine(wt.pts(), wn.pts());
417*c8dee2aaSAndroid Build Coastguard Worker debugShowQuadLineIntersection(pts, wt, wn, ts);
418*c8dee2aaSAndroid Build Coastguard Worker break;
419*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kQuad_Segment: {
420*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(quad1.set(wt.pts()), quad2.set(wn.pts()));
421*c8dee2aaSAndroid Build Coastguard Worker debugShowQuadIntersection(pts, wt, wn, ts);
422*c8dee2aaSAndroid Build Coastguard Worker break;
423*c8dee2aaSAndroid Build Coastguard Worker }
424*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kConic_Segment: {
425*c8dee2aaSAndroid Build Coastguard Worker swap = true;
426*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(conic2.set(wn.pts(), wn.weight()),
427*c8dee2aaSAndroid Build Coastguard Worker quad1.set(wt.pts()));
428*c8dee2aaSAndroid Build Coastguard Worker debugShowConicQuadIntersection(pts, wn, wt, ts);
429*c8dee2aaSAndroid Build Coastguard Worker break;
430*c8dee2aaSAndroid Build Coastguard Worker }
431*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kCubic_Segment: {
432*c8dee2aaSAndroid Build Coastguard Worker swap = true;
433*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(cubic2.set(wn.pts()), quad1.set(wt.pts()));
434*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicQuadIntersection(pts, wn, wt, ts);
435*c8dee2aaSAndroid Build Coastguard Worker break;
436*c8dee2aaSAndroid Build Coastguard Worker }
437*c8dee2aaSAndroid Build Coastguard Worker default:
438*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(0);
439*c8dee2aaSAndroid Build Coastguard Worker }
440*c8dee2aaSAndroid Build Coastguard Worker break;
441*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kConic_Segment:
442*c8dee2aaSAndroid Build Coastguard Worker switch (wn.segmentType()) {
443*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kHorizontalLine_Segment:
444*c8dee2aaSAndroid Build Coastguard Worker pts = ts.conicHorizontal(wt.pts(), wt.weight(), wn.left(),
445*c8dee2aaSAndroid Build Coastguard Worker wn.right(), wn.y(), wn.xFlipped());
446*c8dee2aaSAndroid Build Coastguard Worker debugShowConicLineIntersection(pts, wt, wn, ts);
447*c8dee2aaSAndroid Build Coastguard Worker break;
448*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kVerticalLine_Segment:
449*c8dee2aaSAndroid Build Coastguard Worker pts = ts.conicVertical(wt.pts(), wt.weight(), wn.top(),
450*c8dee2aaSAndroid Build Coastguard Worker wn.bottom(), wn.x(), wn.yFlipped());
451*c8dee2aaSAndroid Build Coastguard Worker debugShowConicLineIntersection(pts, wt, wn, ts);
452*c8dee2aaSAndroid Build Coastguard Worker break;
453*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kLine_Segment:
454*c8dee2aaSAndroid Build Coastguard Worker pts = ts.conicLine(wt.pts(), wt.weight(), wn.pts());
455*c8dee2aaSAndroid Build Coastguard Worker debugShowConicLineIntersection(pts, wt, wn, ts);
456*c8dee2aaSAndroid Build Coastguard Worker break;
457*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kQuad_Segment: {
458*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(conic1.set(wt.pts(), wt.weight()),
459*c8dee2aaSAndroid Build Coastguard Worker quad2.set(wn.pts()));
460*c8dee2aaSAndroid Build Coastguard Worker debugShowConicQuadIntersection(pts, wt, wn, ts);
461*c8dee2aaSAndroid Build Coastguard Worker break;
462*c8dee2aaSAndroid Build Coastguard Worker }
463*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kConic_Segment: {
464*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(conic1.set(wt.pts(), wt.weight()),
465*c8dee2aaSAndroid Build Coastguard Worker conic2.set(wn.pts(), wn.weight()));
466*c8dee2aaSAndroid Build Coastguard Worker debugShowConicIntersection(pts, wt, wn, ts);
467*c8dee2aaSAndroid Build Coastguard Worker break;
468*c8dee2aaSAndroid Build Coastguard Worker }
469*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kCubic_Segment: {
470*c8dee2aaSAndroid Build Coastguard Worker swap = true;
471*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(cubic2.set(wn.pts()
472*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGPARAMS(ts.globalState())),
473*c8dee2aaSAndroid Build Coastguard Worker conic1.set(wt.pts(), wt.weight()
474*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGPARAMS(ts.globalState())));
475*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicConicIntersection(pts, wn, wt, ts);
476*c8dee2aaSAndroid Build Coastguard Worker break;
477*c8dee2aaSAndroid Build Coastguard Worker }
478*c8dee2aaSAndroid Build Coastguard Worker }
479*c8dee2aaSAndroid Build Coastguard Worker break;
480*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kCubic_Segment:
481*c8dee2aaSAndroid Build Coastguard Worker switch (wn.segmentType()) {
482*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kHorizontalLine_Segment:
483*c8dee2aaSAndroid Build Coastguard Worker pts = ts.cubicHorizontal(wt.pts(), wn.left(),
484*c8dee2aaSAndroid Build Coastguard Worker wn.right(), wn.y(), wn.xFlipped());
485*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicLineIntersection(pts, wt, wn, ts);
486*c8dee2aaSAndroid Build Coastguard Worker break;
487*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kVerticalLine_Segment:
488*c8dee2aaSAndroid Build Coastguard Worker pts = ts.cubicVertical(wt.pts(), wn.top(),
489*c8dee2aaSAndroid Build Coastguard Worker wn.bottom(), wn.x(), wn.yFlipped());
490*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicLineIntersection(pts, wt, wn, ts);
491*c8dee2aaSAndroid Build Coastguard Worker break;
492*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kLine_Segment:
493*c8dee2aaSAndroid Build Coastguard Worker pts = ts.cubicLine(wt.pts(), wn.pts());
494*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicLineIntersection(pts, wt, wn, ts);
495*c8dee2aaSAndroid Build Coastguard Worker break;
496*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kQuad_Segment: {
497*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(cubic1.set(wt.pts()), quad2.set(wn.pts()));
498*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicQuadIntersection(pts, wt, wn, ts);
499*c8dee2aaSAndroid Build Coastguard Worker break;
500*c8dee2aaSAndroid Build Coastguard Worker }
501*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kConic_Segment: {
502*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(cubic1.set(wt.pts()
503*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGPARAMS(ts.globalState())),
504*c8dee2aaSAndroid Build Coastguard Worker conic2.set(wn.pts(), wn.weight()
505*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGPARAMS(ts.globalState())));
506*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicConicIntersection(pts, wt, wn, ts);
507*c8dee2aaSAndroid Build Coastguard Worker break;
508*c8dee2aaSAndroid Build Coastguard Worker }
509*c8dee2aaSAndroid Build Coastguard Worker case SkIntersectionHelper::kCubic_Segment: {
510*c8dee2aaSAndroid Build Coastguard Worker pts = ts.intersect(cubic1.set(wt.pts()), cubic2.set(wn.pts()));
511*c8dee2aaSAndroid Build Coastguard Worker debugShowCubicIntersection(pts, wt, wn, ts);
512*c8dee2aaSAndroid Build Coastguard Worker break;
513*c8dee2aaSAndroid Build Coastguard Worker }
514*c8dee2aaSAndroid Build Coastguard Worker default:
515*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(0);
516*c8dee2aaSAndroid Build Coastguard Worker }
517*c8dee2aaSAndroid Build Coastguard Worker break;
518*c8dee2aaSAndroid Build Coastguard Worker default:
519*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(0);
520*c8dee2aaSAndroid Build Coastguard Worker }
521*c8dee2aaSAndroid Build Coastguard Worker #if DEBUG_T_SECT_LOOP_COUNT
522*c8dee2aaSAndroid Build Coastguard Worker test->globalState()->debugAddLoopCount(&ts, wt, wn);
523*c8dee2aaSAndroid Build Coastguard Worker #endif
524*c8dee2aaSAndroid Build Coastguard Worker int coinIndex = -1;
525*c8dee2aaSAndroid Build Coastguard Worker SkOpPtT* coinPtT[2];
526*c8dee2aaSAndroid Build Coastguard Worker for (int pt = 0; pt < pts; ++pt) {
527*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1);
528*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1);
529*c8dee2aaSAndroid Build Coastguard Worker wt.segment()->debugValidate();
530*c8dee2aaSAndroid Build Coastguard Worker // if t value is used to compute pt in addT, error may creep in and
531*c8dee2aaSAndroid Build Coastguard Worker // rect intersections may result in non-rects. if pt value from intersection
532*c8dee2aaSAndroid Build Coastguard Worker // is passed in, current tests break. As a workaround, pass in pt
533*c8dee2aaSAndroid Build Coastguard Worker // value from intersection only if pt.x and pt.y is integral
534*c8dee2aaSAndroid Build Coastguard Worker SkPoint iPt = ts.pt(pt).asSkPoint();
535*c8dee2aaSAndroid Build Coastguard Worker bool iPtIsIntegral = iPt.fX == floor(iPt.fX) && iPt.fY == floor(iPt.fY);
536*c8dee2aaSAndroid Build Coastguard Worker SkOpPtT* testTAt = iPtIsIntegral ? wt.segment()->addT(ts[swap][pt], iPt)
537*c8dee2aaSAndroid Build Coastguard Worker : wt.segment()->addT(ts[swap][pt]);
538*c8dee2aaSAndroid Build Coastguard Worker wn.segment()->debugValidate();
539*c8dee2aaSAndroid Build Coastguard Worker SkOpPtT* nextTAt = iPtIsIntegral ? wn.segment()->addT(ts[!swap][pt], iPt)
540*c8dee2aaSAndroid Build Coastguard Worker : wn.segment()->addT(ts[!swap][pt]);
541*c8dee2aaSAndroid Build Coastguard Worker if (!testTAt->contains(nextTAt)) {
542*c8dee2aaSAndroid Build Coastguard Worker SkOpPtT* oppPrev = testTAt->oppPrev(nextTAt); // Returns nullptr if pair
543*c8dee2aaSAndroid Build Coastguard Worker if (oppPrev) { // already share a pt-t loop.
544*c8dee2aaSAndroid Build Coastguard Worker testTAt->span()->mergeMatches(nextTAt->span());
545*c8dee2aaSAndroid Build Coastguard Worker testTAt->addOpp(nextTAt, oppPrev);
546*c8dee2aaSAndroid Build Coastguard Worker }
547*c8dee2aaSAndroid Build Coastguard Worker if (testTAt->fPt != nextTAt->fPt) {
548*c8dee2aaSAndroid Build Coastguard Worker testTAt->span()->unaligned();
549*c8dee2aaSAndroid Build Coastguard Worker nextTAt->span()->unaligned();
550*c8dee2aaSAndroid Build Coastguard Worker }
551*c8dee2aaSAndroid Build Coastguard Worker wt.segment()->debugValidate();
552*c8dee2aaSAndroid Build Coastguard Worker wn.segment()->debugValidate();
553*c8dee2aaSAndroid Build Coastguard Worker }
554*c8dee2aaSAndroid Build Coastguard Worker if (!ts.isCoincident(pt)) {
555*c8dee2aaSAndroid Build Coastguard Worker continue;
556*c8dee2aaSAndroid Build Coastguard Worker }
557*c8dee2aaSAndroid Build Coastguard Worker if (coinIndex < 0) {
558*c8dee2aaSAndroid Build Coastguard Worker coinPtT[0] = testTAt;
559*c8dee2aaSAndroid Build Coastguard Worker coinPtT[1] = nextTAt;
560*c8dee2aaSAndroid Build Coastguard Worker coinIndex = pt;
561*c8dee2aaSAndroid Build Coastguard Worker continue;
562*c8dee2aaSAndroid Build Coastguard Worker }
563*c8dee2aaSAndroid Build Coastguard Worker if (coinPtT[0]->span() == testTAt->span()) {
564*c8dee2aaSAndroid Build Coastguard Worker coinIndex = -1;
565*c8dee2aaSAndroid Build Coastguard Worker continue;
566*c8dee2aaSAndroid Build Coastguard Worker }
567*c8dee2aaSAndroid Build Coastguard Worker if (coinPtT[1]->span() == nextTAt->span()) {
568*c8dee2aaSAndroid Build Coastguard Worker coinIndex = -1; // coincidence span collapsed
569*c8dee2aaSAndroid Build Coastguard Worker continue;
570*c8dee2aaSAndroid Build Coastguard Worker }
571*c8dee2aaSAndroid Build Coastguard Worker if (swap) {
572*c8dee2aaSAndroid Build Coastguard Worker using std::swap;
573*c8dee2aaSAndroid Build Coastguard Worker swap(coinPtT[0], coinPtT[1]);
574*c8dee2aaSAndroid Build Coastguard Worker swap(testTAt, nextTAt);
575*c8dee2aaSAndroid Build Coastguard Worker }
576*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(coincidence->globalState()->debugSkipAssert()
577*c8dee2aaSAndroid Build Coastguard Worker || coinPtT[0]->span()->t() < testTAt->span()->t());
578*c8dee2aaSAndroid Build Coastguard Worker if (coinPtT[0]->span()->deleted()) {
579*c8dee2aaSAndroid Build Coastguard Worker coinIndex = -1;
580*c8dee2aaSAndroid Build Coastguard Worker continue;
581*c8dee2aaSAndroid Build Coastguard Worker }
582*c8dee2aaSAndroid Build Coastguard Worker if (testTAt->span()->deleted()) {
583*c8dee2aaSAndroid Build Coastguard Worker coinIndex = -1;
584*c8dee2aaSAndroid Build Coastguard Worker continue;
585*c8dee2aaSAndroid Build Coastguard Worker }
586*c8dee2aaSAndroid Build Coastguard Worker coincidence->add(coinPtT[0], testTAt, coinPtT[1], nextTAt);
587*c8dee2aaSAndroid Build Coastguard Worker wt.segment()->debugValidate();
588*c8dee2aaSAndroid Build Coastguard Worker wn.segment()->debugValidate();
589*c8dee2aaSAndroid Build Coastguard Worker coinIndex = -1;
590*c8dee2aaSAndroid Build Coastguard Worker }
591*c8dee2aaSAndroid Build Coastguard Worker SkOPOBJASSERT(coincidence, coinIndex < 0); // expect coincidence to be paired
592*c8dee2aaSAndroid Build Coastguard Worker } while (wn.advance());
593*c8dee2aaSAndroid Build Coastguard Worker } while (wt.advance());
594*c8dee2aaSAndroid Build Coastguard Worker return true;
595*c8dee2aaSAndroid Build Coastguard Worker }
596