1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci#include "src/pathops/SkIntersections.h" 8cb93a386Sopenharmony_ci#include "src/pathops/SkPathOpsLine.h" 9cb93a386Sopenharmony_ci#include "tests/PathOpsTestCommon.h" 10cb93a386Sopenharmony_ci#include "tests/Test.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci// FIXME: add tests for intersecting, non-intersecting, degenerate, coincident 13cb93a386Sopenharmony_cistatic const SkDLine tests[][2] = { 14cb93a386Sopenharmony_ci{{{{0.00010360032320022583, 1.0172703415155411}, {0.00014114845544099808, 1.0200891587883234}}}, 15cb93a386Sopenharmony_ci {{{0.00010259449481964111, 1.017270140349865}, {0.00018215179443359375, 1.022890567779541}}}}, 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci#if 0 18cb93a386Sopenharmony_ci // these do intersect at a pair of points, but not close enough for check results liking 19cb93a386Sopenharmony_ci {{{{365.848175,5081.15186}, {368,5103}}}, {{{367.967712,5102.61084}, {368.278717,5105.71045}}}}, 20cb93a386Sopenharmony_ci#endif 21cb93a386Sopenharmony_ci {{{{30,20}, {30,50}}}, {{{24,30}, {36,30}}}}, 22cb93a386Sopenharmony_ci {{{{323,193}, {-317,193}}}, {{{0,994}, {0,0}}}}, 23cb93a386Sopenharmony_ci {{{{90,230}, {160,60}}}, {{{60,120}, {260,120}}}}, 24cb93a386Sopenharmony_ci {{{{90,230}, {160,60}}}, {{{181.176468,120}, {135.294128,120}}}}, 25cb93a386Sopenharmony_ci {{{{181.1764678955078125f, 120}, {186.3661956787109375f, 134.7042236328125f}}}, 26cb93a386Sopenharmony_ci {{{175.8309783935546875f, 141.5211334228515625f}, {187.8782806396484375f, 133.7258148193359375f}}}}, 27cb93a386Sopenharmony_ci#if 0 // FIXME: these fail because one line is too short and appears quasi-coincident 28cb93a386Sopenharmony_ci {{{{158.000000, 926.000000}, {1108.00000, 926.000000}}}, 29cb93a386Sopenharmony_ci {{{1108.00000, 926.000000}, {1108.00000, 925.999634}}}}, 30cb93a386Sopenharmony_ci {{{{1108,926}, {1108,925.9996337890625}}}, {{{158,926}, {1108,926}}}}, 31cb93a386Sopenharmony_ci#endif 32cb93a386Sopenharmony_ci {{{{192, 4}, {243, 4}}}, {{{246, 4}, {189, 4}}}}, 33cb93a386Sopenharmony_ci {{{{246, 4}, {189, 4}}}, {{{192, 4}, {243, 4}}}}, 34cb93a386Sopenharmony_ci {{{{5, 0}, {0, 5}}}, {{{5, 4}, {1, 4}}}}, 35cb93a386Sopenharmony_ci {{{{0, 0}, {1, 0}}}, {{{1, 0}, {0, 0}}}}, 36cb93a386Sopenharmony_ci {{{{0, 0}, {0, 0}}}, {{{0, 0}, {1, 0}}}}, 37cb93a386Sopenharmony_ci {{{{0, 1}, {0, 1}}}, {{{0, 0}, {0, 2}}}}, 38cb93a386Sopenharmony_ci {{{{0, 0}, {1, 0}}}, {{{0, 0}, {2, 0}}}}, 39cb93a386Sopenharmony_ci {{{{1, 1}, {2, 2}}}, {{{0, 0}, {3, 3}}}}, 40cb93a386Sopenharmony_ci {{{{166.86950047022856, 112.69654129527828}, {166.86948801592692, 112.69655741235339}}}, 41cb93a386Sopenharmony_ci {{{166.86960700313026, 112.6965477747386}, {166.86925794355412, 112.69656471103423}}}} 42cb93a386Sopenharmony_ci}; 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_cistatic const size_t tests_count = SK_ARRAY_COUNT(tests); 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_cistatic const SkDLine noIntersect[][2] = { 47cb93a386Sopenharmony_ci {{{{(double) (2 - 1e-6f),2}, {(double) (2 - 1e-6f),4}}}, 48cb93a386Sopenharmony_ci {{{2,1}, {2,3}}}}, 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci {{{{0, 0}, {1, 0}}}, {{{3, 0}, {2, 0}}}}, 51cb93a386Sopenharmony_ci {{{{0, 0}, {0, 0}}}, {{{1, 0}, {2, 0}}}}, 52cb93a386Sopenharmony_ci {{{{0, 1}, {0, 1}}}, {{{0, 3}, {0, 2}}}}, 53cb93a386Sopenharmony_ci {{{{0, 0}, {1, 0}}}, {{{2, 0}, {3, 0}}}}, 54cb93a386Sopenharmony_ci {{{{1, 1}, {2, 2}}}, {{{4, 4}, {3, 3}}}}, 55cb93a386Sopenharmony_ci}; 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_cistatic const size_t noIntersect_count = SK_ARRAY_COUNT(noIntersect); 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_cistatic const SkDLine coincidentTests[][2] = { 60cb93a386Sopenharmony_ci {{{ {-1.48383003e-006,-83}, {4.2268899e-014,-60} }}, 61cb93a386Sopenharmony_ci {{ {9.5359502e-007,-60}, {5.08227985e-015,-83} }}}, 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci {{{ { 10105, 2510 }, { 10123, 2509.98999f } }}, 64cb93a386Sopenharmony_ci {{{10105, 2509.98999f}, { 10123, 2510 } }}}, 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci {{ { { 0, 482.5 }, { -4.4408921e-016, 682.5 } } }, 67cb93a386Sopenharmony_ci {{{0,683}, {0,482}}}}, 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci {{{{1.77635684e-015,312}, {-1.24344979e-014,348}}}, 70cb93a386Sopenharmony_ci {{{0,348}, {0,312}}}}, 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci {{{{979.304871, 561}, {1036.69507, 291}}}, 73cb93a386Sopenharmony_ci {{{985.681519, 531}, {982.159790, 547.568542}}}}, 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci {{{{232.159805, 547.568542}, {235.681549, 531}}}, 76cb93a386Sopenharmony_ci {{{286.695129,291}, {229.304855,561}}}}, 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci {{{{186.3661956787109375f, 134.7042236328125f}, {187.8782806396484375f, 133.7258148193359375f}}}, 79cb93a386Sopenharmony_ci {{{175.8309783935546875f, 141.5211334228515625f}, {187.8782806396484375f, 133.7258148193359375f}}}}, 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci {{{{235.681549, 531.000000}, {280.318420, 321.000000}}}, 82cb93a386Sopenharmony_ci {{{286.695129, 291.000000}, {229.304855, 561.000000}}}}, 83cb93a386Sopenharmony_ci}; 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_cistatic const size_t coincidentTests_count = SK_ARRAY_COUNT(coincidentTests); 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_cistatic void check_results(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2, 88cb93a386Sopenharmony_ci const SkIntersections& ts, bool nearAllowed) { 89cb93a386Sopenharmony_ci for (int i = 0; i < ts.used(); ++i) { 90cb93a386Sopenharmony_ci SkDPoint result1 = line1.ptAtT(ts[0][i]); 91cb93a386Sopenharmony_ci SkDPoint result2 = line2.ptAtT(ts[1][i]); 92cb93a386Sopenharmony_ci if (nearAllowed && result1.roughlyEqual(result2)) { 93cb93a386Sopenharmony_ci continue; 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci if (!result1.approximatelyEqual(result2) && !ts.nearlySame(i)) { 96cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, ts.used() != 1); 97cb93a386Sopenharmony_ci result2 = line2.ptAtT(ts[1][i ^ 1]); 98cb93a386Sopenharmony_ci if (!result1.approximatelyEqual(result2)) { 99cb93a386Sopenharmony_ci SkDebugf("."); 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, result1.approximatelyEqual(result2)); 102cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, result1.approximatelyEqual(ts.pt(i).asSkPoint())); 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci} 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_cistatic void testOne(skiatest::Reporter* reporter, const SkDLine& line1, const SkDLine& line2, 108cb93a386Sopenharmony_ci bool nearAllowed) { 109cb93a386Sopenharmony_ci SkASSERT(ValidLine(line1)); 110cb93a386Sopenharmony_ci SkASSERT(ValidLine(line2)); 111cb93a386Sopenharmony_ci SkIntersections i; 112cb93a386Sopenharmony_ci i.allowNear(nearAllowed); 113cb93a386Sopenharmony_ci int pts = i.intersect(line1, line2); 114cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts); 115cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == i.used()); 116cb93a386Sopenharmony_ci check_results(reporter, line1, line2, i, nearAllowed); 117cb93a386Sopenharmony_ci if (line1[0] == line1[1] || line2[0] == line2[1]) { 118cb93a386Sopenharmony_ci return; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci if (line1[0].fY == line1[1].fY) { 121cb93a386Sopenharmony_ci double left = std::min(line1[0].fX, line1[1].fX); 122cb93a386Sopenharmony_ci double right = std::max(line1[0].fX, line1[1].fX); 123cb93a386Sopenharmony_ci SkIntersections ts; 124cb93a386Sopenharmony_ci ts.horizontal(line2, left, right, line1[0].fY, line1[0].fX != left); 125cb93a386Sopenharmony_ci check_results(reporter, line2, line1, ts, nearAllowed); 126cb93a386Sopenharmony_ci } 127cb93a386Sopenharmony_ci if (line2[0].fY == line2[1].fY) { 128cb93a386Sopenharmony_ci double left = std::min(line2[0].fX, line2[1].fX); 129cb93a386Sopenharmony_ci double right = std::max(line2[0].fX, line2[1].fX); 130cb93a386Sopenharmony_ci SkIntersections ts; 131cb93a386Sopenharmony_ci ts.horizontal(line1, left, right, line2[0].fY, line2[0].fX != left); 132cb93a386Sopenharmony_ci check_results(reporter, line1, line2, ts, nearAllowed); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci if (line1[0].fX == line1[1].fX) { 135cb93a386Sopenharmony_ci double top = std::min(line1[0].fY, line1[1].fY); 136cb93a386Sopenharmony_ci double bottom = std::max(line1[0].fY, line1[1].fY); 137cb93a386Sopenharmony_ci SkIntersections ts; 138cb93a386Sopenharmony_ci ts.vertical(line2, top, bottom, line1[0].fX, line1[0].fY != top); 139cb93a386Sopenharmony_ci check_results(reporter, line2, line1, ts, nearAllowed); 140cb93a386Sopenharmony_ci } 141cb93a386Sopenharmony_ci if (line2[0].fX == line2[1].fX) { 142cb93a386Sopenharmony_ci double top = std::min(line2[0].fY, line2[1].fY); 143cb93a386Sopenharmony_ci double bottom = std::max(line2[0].fY, line2[1].fY); 144cb93a386Sopenharmony_ci SkIntersections ts; 145cb93a386Sopenharmony_ci ts.vertical(line1, top, bottom, line2[0].fX, line2[0].fY != top); 146cb93a386Sopenharmony_ci check_results(reporter, line1, line2, ts, nearAllowed); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci reporter->bumpTestCount(); 149cb93a386Sopenharmony_ci} 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_cistatic void testOneCoincident(skiatest::Reporter* reporter, const SkDLine& line1, 152cb93a386Sopenharmony_ci const SkDLine& line2) { 153cb93a386Sopenharmony_ci SkASSERT(ValidLine(line1)); 154cb93a386Sopenharmony_ci SkASSERT(ValidLine(line2)); 155cb93a386Sopenharmony_ci SkIntersections i; 156cb93a386Sopenharmony_ci int pts = i.intersect(line1, line2); 157cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == 2); 158cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == i.used()); 159cb93a386Sopenharmony_ci check_results(reporter, line1, line2, i, false); 160cb93a386Sopenharmony_ci if (line1[0] == line1[1] || line2[0] == line2[1]) { 161cb93a386Sopenharmony_ci return; 162cb93a386Sopenharmony_ci } 163cb93a386Sopenharmony_ci if (line1[0].fY == line1[1].fY) { 164cb93a386Sopenharmony_ci double left = std::min(line1[0].fX, line1[1].fX); 165cb93a386Sopenharmony_ci double right = std::max(line1[0].fX, line1[1].fX); 166cb93a386Sopenharmony_ci SkIntersections ts; 167cb93a386Sopenharmony_ci ts.horizontal(line2, left, right, line1[0].fY, line1[0].fX != left); 168cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == 2); 169cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == ts.used()); 170cb93a386Sopenharmony_ci check_results(reporter, line2, line1, ts, false); 171cb93a386Sopenharmony_ci } 172cb93a386Sopenharmony_ci if (line2[0].fY == line2[1].fY) { 173cb93a386Sopenharmony_ci double left = std::min(line2[0].fX, line2[1].fX); 174cb93a386Sopenharmony_ci double right = std::max(line2[0].fX, line2[1].fX); 175cb93a386Sopenharmony_ci SkIntersections ts; 176cb93a386Sopenharmony_ci ts.horizontal(line1, left, right, line2[0].fY, line2[0].fX != left); 177cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == 2); 178cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == ts.used()); 179cb93a386Sopenharmony_ci check_results(reporter, line1, line2, ts, false); 180cb93a386Sopenharmony_ci } 181cb93a386Sopenharmony_ci if (line1[0].fX == line1[1].fX) { 182cb93a386Sopenharmony_ci double top = std::min(line1[0].fY, line1[1].fY); 183cb93a386Sopenharmony_ci double bottom = std::max(line1[0].fY, line1[1].fY); 184cb93a386Sopenharmony_ci SkIntersections ts; 185cb93a386Sopenharmony_ci ts.vertical(line2, top, bottom, line1[0].fX, line1[0].fY != top); 186cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == 2); 187cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == ts.used()); 188cb93a386Sopenharmony_ci check_results(reporter, line2, line1, ts, false); 189cb93a386Sopenharmony_ci } 190cb93a386Sopenharmony_ci if (line2[0].fX == line2[1].fX) { 191cb93a386Sopenharmony_ci double top = std::min(line2[0].fY, line2[1].fY); 192cb93a386Sopenharmony_ci double bottom = std::max(line2[0].fY, line2[1].fY); 193cb93a386Sopenharmony_ci SkIntersections ts; 194cb93a386Sopenharmony_ci ts.vertical(line1, top, bottom, line2[0].fX, line2[0].fY != top); 195cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == 2); 196cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == ts.used()); 197cb93a386Sopenharmony_ci check_results(reporter, line1, line2, ts, false); 198cb93a386Sopenharmony_ci } 199cb93a386Sopenharmony_ci reporter->bumpTestCount(); 200cb93a386Sopenharmony_ci} 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ciDEF_TEST(PathOpsLineIntersection, reporter) { 203cb93a386Sopenharmony_ci size_t index; 204cb93a386Sopenharmony_ci for (index = 0; index < coincidentTests_count; ++index) { 205cb93a386Sopenharmony_ci const SkDLine& line1 = coincidentTests[index][0]; 206cb93a386Sopenharmony_ci const SkDLine& line2 = coincidentTests[index][1]; 207cb93a386Sopenharmony_ci testOneCoincident(reporter, line1, line2); 208cb93a386Sopenharmony_ci } 209cb93a386Sopenharmony_ci for (index = 0; index < tests_count; ++index) { 210cb93a386Sopenharmony_ci const SkDLine& line1 = tests[index][0]; 211cb93a386Sopenharmony_ci const SkDLine& line2 = tests[index][1]; 212cb93a386Sopenharmony_ci testOne(reporter, line1, line2, true); 213cb93a386Sopenharmony_ci } 214cb93a386Sopenharmony_ci for (index = 0; index < noIntersect_count; ++index) { 215cb93a386Sopenharmony_ci const SkDLine& line1 = noIntersect[index][0]; 216cb93a386Sopenharmony_ci const SkDLine& line2 = noIntersect[index][1]; 217cb93a386Sopenharmony_ci SkIntersections ts; 218cb93a386Sopenharmony_ci int pts = ts.intersect(line1, line2); 219cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !pts); 220cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, pts == ts.used()); 221cb93a386Sopenharmony_ci reporter->bumpTestCount(); 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci} 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_ciDEF_TEST(PathOpsLineIntersectionOneOff, reporter) { 226cb93a386Sopenharmony_ci int index = 0; 227cb93a386Sopenharmony_ci SkASSERT(index < (int) tests_count); 228cb93a386Sopenharmony_ci testOne(reporter, tests[index][0], tests[index][1], true); 229cb93a386Sopenharmony_ci} 230cb93a386Sopenharmony_ci 231cb93a386Sopenharmony_ciDEF_TEST(PathOpsLineIntersectionExactOneOff, reporter) { 232cb93a386Sopenharmony_ci int index = 0; 233cb93a386Sopenharmony_ci SkASSERT(index < (int) tests_count); 234cb93a386Sopenharmony_ci testOne(reporter, tests[index][0], tests[index][1], false); 235cb93a386Sopenharmony_ci} 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_ciDEF_TEST(PathOpsLineIntersectionOneCoincident, reporter) { 238cb93a386Sopenharmony_ci int index = 0; 239cb93a386Sopenharmony_ci SkASSERT(index < (int) coincidentTests_count); 240cb93a386Sopenharmony_ci const SkDLine& line1 = coincidentTests[index][0]; 241cb93a386Sopenharmony_ci const SkDLine& line2 = coincidentTests[index][1]; 242cb93a386Sopenharmony_ci testOneCoincident(reporter, line1, line2); 243cb93a386Sopenharmony_ci} 244