blob: f2bef912ebfe0a6cd487a9afe077d6a5830fb443 [file] [log] [blame]
caryclark@google.com9166dcb2013-04-08 11:50:00 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
caryclark@google.com8d0a5242013-07-16 16:11:16 +00007#include "PathOpsTestCommon.h"
caryclark@google.com9166dcb2013-04-08 11:50:00 +00008#include "SkIntersections.h"
9#include "SkPathOpsLine.h"
10#include "Test.h"
11
12// FIXME: add tests for intersecting, non-intersecting, degenerate, coincident
13static const SkDLine tests[][2] = {
caryclark@google.com07e97fc2013-07-08 17:17:02 +000014#if 0 // FIXME: these fail because one line is too short and appears quasi-coincident
15 {{{{158.000000, 926.000000}, {1108.00000, 926.000000}}},
16 {{{1108.00000, 926.000000}, {1108.00000, 925.999634}}}},
17 {{{{1108,926}, {1108,925.9996337890625}}}, {{{158,926}, {1108,926}}}},
18#endif
caryclark@google.coma5e55922013-05-07 18:51:31 +000019 {{{{192, 4}, {243, 4}}}, {{{246, 4}, {189, 4}}}},
20 {{{{246, 4}, {189, 4}}}, {{{192, 4}, {243, 4}}}},
caryclark@google.com03610322013-04-18 15:58:21 +000021 {{{{5, 0}, {0, 5}}}, {{{5, 4}, {1, 4}}}},
caryclark@google.com9166dcb2013-04-08 11:50:00 +000022 {{{{0, 0}, {1, 0}}}, {{{1, 0}, {0, 0}}}},
23 {{{{0, 0}, {0, 0}}}, {{{0, 0}, {1, 0}}}},
24 {{{{0, 1}, {0, 1}}}, {{{0, 0}, {0, 2}}}},
25 {{{{0, 0}, {1, 0}}}, {{{0, 0}, {2, 0}}}},
26 {{{{1, 1}, {2, 2}}}, {{{0, 0}, {3, 3}}}},
27 {{{{166.86950047022856, 112.69654129527828}, {166.86948801592692, 112.69655741235339}}},
28 {{{166.86960700313026, 112.6965477747386}, {166.86925794355412, 112.69656471103423}}}}
29};
30
caryclark@google.comad65a3e2013-04-15 19:13:59 +000031static const size_t tests_count = SK_ARRAY_COUNT(tests);
caryclark@google.com9166dcb2013-04-08 11:50:00 +000032
33static const SkDLine noIntersect[][2] = {
34 {{{{0, 0}, {1, 0}}}, {{{3, 0}, {2, 0}}}},
35 {{{{0, 0}, {0, 0}}}, {{{1, 0}, {2, 0}}}},
36 {{{{0, 1}, {0, 1}}}, {{{0, 3}, {0, 2}}}},
37 {{{{0, 0}, {1, 0}}}, {{{2, 0}, {3, 0}}}},
38 {{{{1, 1}, {2, 2}}}, {{{4, 4}, {3, 3}}}},
39};
40
caryclark@google.comad65a3e2013-04-15 19:13:59 +000041static const size_t noIntersect_count = SK_ARRAY_COUNT(noIntersect);
caryclark@google.com9166dcb2013-04-08 11:50:00 +000042
caryclark@google.com07e97fc2013-07-08 17:17:02 +000043static const SkDLine coincidentTests[][2] = {
44 {{{{235.681549, 531.000000}, {280.318420, 321.000000}}},
45 {{{286.695129, 291.000000}, {229.304855, 561.000000}}}},
46};
47
48static const size_t coincidentTests_count = SK_ARRAY_COUNT(coincidentTests);
49
caryclark@google.coma5e55922013-05-07 18:51:31 +000050static void check_results(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2,
51 const SkIntersections& ts) {
52 for (int i = 0; i < ts.used(); ++i) {
53 SkDPoint result1 = line1.xyAtT(ts[0][i]);
54 SkDPoint result2 = line2.xyAtT(ts[1][i]);
55 if (!result1.approximatelyEqual(result2)) {
56 REPORTER_ASSERT(reporter, ts.used() != 1);
57 result2 = line2.xyAtT(ts[1][i ^ 1]);
58 REPORTER_ASSERT(reporter, result1.approximatelyEqual(result2));
59 REPORTER_ASSERT(reporter, result1.approximatelyEqual(ts.pt(i).asSkPoint()));
60 }
61 }
62}
63
caryclark@google.com07e97fc2013-07-08 17:17:02 +000064static void testOne(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2) {
caryclark@google.com8d0a5242013-07-16 16:11:16 +000065 SkASSERT(ValidLine(line1));
66 SkASSERT(ValidLine(line2));
caryclark@google.com07e97fc2013-07-08 17:17:02 +000067 SkIntersections i;
68 int pts = i.intersect(line1, line2);
69 REPORTER_ASSERT(reporter, pts);
70 REPORTER_ASSERT(reporter, pts == i.used());
71 check_results(reporter, line1, line2, i);
72 if (line1[0] == line1[1] || line2[0] == line2[1]) {
73 return;
74 }
75 if (line1[0].fY == line1[1].fY) {
76 double left = SkTMin(line1[0].fX, line1[1].fX);
77 double right = SkTMax(line1[0].fX, line1[1].fX);
78 SkIntersections ts;
79 ts.horizontal(line2, left, right, line1[0].fY, line1[0].fX != left);
80 check_results(reporter, line2, line1, ts);
81 }
82 if (line2[0].fY == line2[1].fY) {
83 double left = SkTMin(line2[0].fX, line2[1].fX);
84 double right = SkTMax(line2[0].fX, line2[1].fX);
85 SkIntersections ts;
86 ts.horizontal(line1, left, right, line2[0].fY, line2[0].fX != left);
87 check_results(reporter, line1, line2, ts);
88 }
89 if (line1[0].fX == line1[1].fX) {
90 double top = SkTMin(line1[0].fY, line1[1].fY);
91 double bottom = SkTMax(line1[0].fY, line1[1].fY);
92 SkIntersections ts;
93 ts.vertical(line2, top, bottom, line1[0].fX, line1[0].fY != top);
94 check_results(reporter, line2, line1, ts);
95 }
96 if (line2[0].fX == line2[1].fX) {
97 double top = SkTMin(line2[0].fY, line2[1].fY);
98 double bottom = SkTMax(line2[0].fY, line2[1].fY);
99 SkIntersections ts;
100 ts.vertical(line1, top, bottom, line2[0].fX, line2[0].fY != top);
101 check_results(reporter, line1, line2, ts);
102 }
103}
104
105static void testOneCoincident(skiatest::Reporter* reporter, const SkDLine& line1,
106 const SkDLine& line2) {
caryclark@google.com8d0a5242013-07-16 16:11:16 +0000107 SkASSERT(ValidLine(line1));
108 SkASSERT(ValidLine(line2));
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000109 SkIntersections ts2;
110 int pts2 = ts2.intersect(line1, line2);
111 REPORTER_ASSERT(reporter, pts2 == 2);
112 REPORTER_ASSERT(reporter, pts2 == ts2.used());
113 check_results(reporter, line1, line2, ts2);
114#if 0
115 SkIntersections ts;
116 int pts = ts.intersect(line1, line2);
117 REPORTER_ASSERT(reporter, pts == pts2);
118 REPORTER_ASSERT(reporter, pts == 2);
119 REPORTER_ASSERT(reporter, pts == ts.used());
120 check_results(reporter, line1, line2, ts);
121#endif
122}
123
caryclark@google.comad65a3e2013-04-15 19:13:59 +0000124static void PathOpsLineIntersectionTest(skiatest::Reporter* reporter) {
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000125 size_t index;
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000126 for (index = 0; index < coincidentTests_count; ++index) {
127 const SkDLine& line1 = coincidentTests[index][0];
128 const SkDLine& line2 = coincidentTests[index][1];
129 testOneCoincident(reporter, line1, line2);
130 reporter->bumpTestCount();
131 }
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000132 for (index = 0; index < tests_count; ++index) {
133 const SkDLine& line1 = tests[index][0];
134 const SkDLine& line2 = tests[index][1];
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000135 testOne(reporter, line1, line2);
136 reporter->bumpTestCount();
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000137 }
138 for (index = 0; index < noIntersect_count; ++index) {
139 const SkDLine& line1 = noIntersect[index][0];
140 const SkDLine& line2 = noIntersect[index][1];
141 SkIntersections ts;
142 int pts = ts.intersect(line1, line2);
skia.committer@gmail.com2b34fe02013-05-08 07:01:40 +0000143 REPORTER_ASSERT(reporter, !pts);
caryclark@google.coma5e55922013-05-07 18:51:31 +0000144 REPORTER_ASSERT(reporter, pts == ts.used());
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000145 reporter->bumpTestCount();
caryclark@google.coma5e55922013-05-07 18:51:31 +0000146 }
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000147}
148
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000149static void PathOpsLineIntersectionTestOne(skiatest::Reporter* reporter) {
150 int index = 0;
151 SkASSERT(index < (int) tests_count);
152 const SkDLine& line1 = tests[index][0];
153 const SkDLine& line2 = tests[index][1];
154 testOne(reporter, line1, line2);
155}
156
157static void PathOpsLineIntersectionTestOneCoincident(skiatest::Reporter* reporter) {
158 int index = 0;
159 SkASSERT(index < (int) coincidentTests_count);
160 const SkDLine& line1 = coincidentTests[index][0];
161 const SkDLine& line2 = coincidentTests[index][1];
162 testOneCoincident(reporter, line1, line2);
163}
164
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000165#include "TestClassDef.h"
caryclark@google.comad65a3e2013-04-15 19:13:59 +0000166DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionTest)
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000167
168DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionTestOne)
169
170DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionTestOneCoincident)