blob: 57b42ec3c0c599ac40f137028fffb7e17a38694f [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.com4fdbb222013-07-23 15:27:41 +000014 {{{{181.1764678955078125f, 120}, {186.3661956787109375f, 134.7042236328125f}}},
15 {{{175.8309783935546875f, 141.5211334228515625f}, {187.8782806396484375f, 133.7258148193359375f}}}},
caryclark@google.com07e97fc2013-07-08 17:17:02 +000016#if 0 // FIXME: these fail because one line is too short and appears quasi-coincident
17 {{{{158.000000, 926.000000}, {1108.00000, 926.000000}}},
18 {{{1108.00000, 926.000000}, {1108.00000, 925.999634}}}},
19 {{{{1108,926}, {1108,925.9996337890625}}}, {{{158,926}, {1108,926}}}},
20#endif
caryclark@google.coma5e55922013-05-07 18:51:31 +000021 {{{{192, 4}, {243, 4}}}, {{{246, 4}, {189, 4}}}},
22 {{{{246, 4}, {189, 4}}}, {{{192, 4}, {243, 4}}}},
caryclark@google.com03610322013-04-18 15:58:21 +000023 {{{{5, 0}, {0, 5}}}, {{{5, 4}, {1, 4}}}},
caryclark@google.com9166dcb2013-04-08 11:50:00 +000024 {{{{0, 0}, {1, 0}}}, {{{1, 0}, {0, 0}}}},
25 {{{{0, 0}, {0, 0}}}, {{{0, 0}, {1, 0}}}},
26 {{{{0, 1}, {0, 1}}}, {{{0, 0}, {0, 2}}}},
27 {{{{0, 0}, {1, 0}}}, {{{0, 0}, {2, 0}}}},
28 {{{{1, 1}, {2, 2}}}, {{{0, 0}, {3, 3}}}},
29 {{{{166.86950047022856, 112.69654129527828}, {166.86948801592692, 112.69655741235339}}},
30 {{{166.86960700313026, 112.6965477747386}, {166.86925794355412, 112.69656471103423}}}}
31};
32
caryclark@google.comad65a3e2013-04-15 19:13:59 +000033static const size_t tests_count = SK_ARRAY_COUNT(tests);
caryclark@google.com9166dcb2013-04-08 11:50:00 +000034
35static const SkDLine noIntersect[][2] = {
36 {{{{0, 0}, {1, 0}}}, {{{3, 0}, {2, 0}}}},
37 {{{{0, 0}, {0, 0}}}, {{{1, 0}, {2, 0}}}},
38 {{{{0, 1}, {0, 1}}}, {{{0, 3}, {0, 2}}}},
39 {{{{0, 0}, {1, 0}}}, {{{2, 0}, {3, 0}}}},
40 {{{{1, 1}, {2, 2}}}, {{{4, 4}, {3, 3}}}},
41};
42
caryclark@google.comad65a3e2013-04-15 19:13:59 +000043static const size_t noIntersect_count = SK_ARRAY_COUNT(noIntersect);
caryclark@google.com9166dcb2013-04-08 11:50:00 +000044
caryclark@google.com07e97fc2013-07-08 17:17:02 +000045static const SkDLine coincidentTests[][2] = {
caryclark@google.com4fdbb222013-07-23 15:27:41 +000046 {{{{186.3661956787109375f, 134.7042236328125f}, {187.8782806396484375f, 133.7258148193359375f}}},
47 {{{175.8309783935546875f, 141.5211334228515625f}, {187.8782806396484375f, 133.7258148193359375f}}}},
48
caryclark@google.com07e97fc2013-07-08 17:17:02 +000049 {{{{235.681549, 531.000000}, {280.318420, 321.000000}}},
caryclark@google.com4fdbb222013-07-23 15:27:41 +000050 {{{286.695129, 291.000000}, {229.304855, 561.000000}}}},
caryclark@google.com07e97fc2013-07-08 17:17:02 +000051};
52
53static const size_t coincidentTests_count = SK_ARRAY_COUNT(coincidentTests);
54
caryclark@google.coma5e55922013-05-07 18:51:31 +000055static void check_results(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2,
56 const SkIntersections& ts) {
57 for (int i = 0; i < ts.used(); ++i) {
caryclark@google.com4fdbb222013-07-23 15:27:41 +000058 SkDPoint result1 = line1.ptAtT(ts[0][i]);
59 SkDPoint result2 = line2.ptAtT(ts[1][i]);
caryclark@google.coma5e55922013-05-07 18:51:31 +000060 if (!result1.approximatelyEqual(result2)) {
61 REPORTER_ASSERT(reporter, ts.used() != 1);
caryclark@google.com4fdbb222013-07-23 15:27:41 +000062 result2 = line2.ptAtT(ts[1][i ^ 1]);
caryclark@google.coma5e55922013-05-07 18:51:31 +000063 REPORTER_ASSERT(reporter, result1.approximatelyEqual(result2));
64 REPORTER_ASSERT(reporter, result1.approximatelyEqual(ts.pt(i).asSkPoint()));
65 }
66 }
67}
68
caryclark@google.com07e97fc2013-07-08 17:17:02 +000069static void testOne(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2) {
caryclark@google.com8d0a5242013-07-16 16:11:16 +000070 SkASSERT(ValidLine(line1));
71 SkASSERT(ValidLine(line2));
caryclark@google.com07e97fc2013-07-08 17:17:02 +000072 SkIntersections i;
73 int pts = i.intersect(line1, line2);
74 REPORTER_ASSERT(reporter, pts);
75 REPORTER_ASSERT(reporter, pts == i.used());
76 check_results(reporter, line1, line2, i);
77 if (line1[0] == line1[1] || line2[0] == line2[1]) {
78 return;
79 }
80 if (line1[0].fY == line1[1].fY) {
81 double left = SkTMin(line1[0].fX, line1[1].fX);
82 double right = SkTMax(line1[0].fX, line1[1].fX);
83 SkIntersections ts;
84 ts.horizontal(line2, left, right, line1[0].fY, line1[0].fX != left);
85 check_results(reporter, line2, line1, ts);
86 }
87 if (line2[0].fY == line2[1].fY) {
88 double left = SkTMin(line2[0].fX, line2[1].fX);
89 double right = SkTMax(line2[0].fX, line2[1].fX);
90 SkIntersections ts;
91 ts.horizontal(line1, left, right, line2[0].fY, line2[0].fX != left);
92 check_results(reporter, line1, line2, ts);
93 }
94 if (line1[0].fX == line1[1].fX) {
95 double top = SkTMin(line1[0].fY, line1[1].fY);
96 double bottom = SkTMax(line1[0].fY, line1[1].fY);
97 SkIntersections ts;
98 ts.vertical(line2, top, bottom, line1[0].fX, line1[0].fY != top);
99 check_results(reporter, line2, line1, ts);
100 }
101 if (line2[0].fX == line2[1].fX) {
102 double top = SkTMin(line2[0].fY, line2[1].fY);
103 double bottom = SkTMax(line2[0].fY, line2[1].fY);
104 SkIntersections ts;
105 ts.vertical(line1, top, bottom, line2[0].fX, line2[0].fY != top);
106 check_results(reporter, line1, line2, ts);
107 }
108}
109
110static void testOneCoincident(skiatest::Reporter* reporter, const SkDLine& line1,
111 const SkDLine& line2) {
caryclark@google.com8d0a5242013-07-16 16:11:16 +0000112 SkASSERT(ValidLine(line1));
113 SkASSERT(ValidLine(line2));
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000114 SkIntersections ts2;
115 int pts2 = ts2.intersect(line1, line2);
116 REPORTER_ASSERT(reporter, pts2 == 2);
117 REPORTER_ASSERT(reporter, pts2 == ts2.used());
118 check_results(reporter, line1, line2, ts2);
119#if 0
120 SkIntersections ts;
121 int pts = ts.intersect(line1, line2);
122 REPORTER_ASSERT(reporter, pts == pts2);
123 REPORTER_ASSERT(reporter, pts == 2);
124 REPORTER_ASSERT(reporter, pts == ts.used());
125 check_results(reporter, line1, line2, ts);
126#endif
127}
128
caryclark@google.comad65a3e2013-04-15 19:13:59 +0000129static void PathOpsLineIntersectionTest(skiatest::Reporter* reporter) {
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000130 size_t index;
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000131 for (index = 0; index < coincidentTests_count; ++index) {
132 const SkDLine& line1 = coincidentTests[index][0];
133 const SkDLine& line2 = coincidentTests[index][1];
134 testOneCoincident(reporter, line1, line2);
135 reporter->bumpTestCount();
136 }
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000137 for (index = 0; index < tests_count; ++index) {
138 const SkDLine& line1 = tests[index][0];
139 const SkDLine& line2 = tests[index][1];
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000140 testOne(reporter, line1, line2);
141 reporter->bumpTestCount();
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000142 }
143 for (index = 0; index < noIntersect_count; ++index) {
144 const SkDLine& line1 = noIntersect[index][0];
145 const SkDLine& line2 = noIntersect[index][1];
146 SkIntersections ts;
147 int pts = ts.intersect(line1, line2);
skia.committer@gmail.com2b34fe02013-05-08 07:01:40 +0000148 REPORTER_ASSERT(reporter, !pts);
caryclark@google.coma5e55922013-05-07 18:51:31 +0000149 REPORTER_ASSERT(reporter, pts == ts.used());
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000150 reporter->bumpTestCount();
caryclark@google.coma5e55922013-05-07 18:51:31 +0000151 }
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000152}
153
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000154static void PathOpsLineIntersectionOneOffTest(skiatest::Reporter* reporter) {
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000155 int index = 0;
156 SkASSERT(index < (int) tests_count);
157 const SkDLine& line1 = tests[index][0];
158 const SkDLine& line2 = tests[index][1];
159 testOne(reporter, line1, line2);
160}
161
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000162static void PathOpsLineIntersectionOneCoincidentTest(skiatest::Reporter* reporter) {
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000163 int index = 0;
164 SkASSERT(index < (int) coincidentTests_count);
165 const SkDLine& line1 = coincidentTests[index][0];
166 const SkDLine& line2 = coincidentTests[index][1];
167 testOneCoincident(reporter, line1, line2);
168}
169
caryclark@google.com9166dcb2013-04-08 11:50:00 +0000170#include "TestClassDef.h"
caryclark@google.comad65a3e2013-04-15 19:13:59 +0000171DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionTest)
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000172
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000173DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionOneOffTest)
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000174
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000175DEFINE_TESTCLASS_SHORT(PathOpsLineIntersectionOneCoincidentTest)