1 /* 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 */ 7 8 #include "Simplify.h" 9 10 namespace SimplifyFindTopTest { 11 12 #include "Simplify.cpp" 13 14 } // end of SimplifyFindTopTest namespace 15 16 #include "Intersection_Tests.h" 17 18 static const SimplifyFindTopTest::Segment* testCommon( 19 SkTArray<SimplifyFindTopTest::Contour>& contours, 20 int& index, int& end) { 21 SkTDArray<SimplifyFindTopTest::Contour*> contourList; 22 makeContourList(contours, contourList, false, false); 23 addIntersectTs(contourList[0], contourList[0]); 24 if (contours.count() > 1) { 25 SkASSERT(contours.count() == 2); 26 addIntersectTs(contourList[0], contourList[1]); 27 addIntersectTs(contourList[1], contourList[1]); 28 } 29 fixOtherTIndex(contourList); 30 #if SORTABLE_CONTOURS // old way 31 SimplifyFindTopTest::Segment* topStart = findTopContour(contourList); 32 const SimplifyFindTopTest::Segment* topSegment = topStart->findTop(index, 33 end); 34 #else 35 SkPoint bestXY = {SK_ScalarMin, SK_ScalarMin}; 36 bool done, unsortable = false; 37 const SimplifyFindTopTest::Segment* topSegment = 38 findSortableTop(contourList, index, end, bestXY, unsortable, done, true); 39 #endif 40 return topSegment; 41 } 42 43 static void test(const SkPath& path) { 44 SkTArray<SimplifyFindTopTest::Contour> contours; 45 SimplifyFindTopTest::EdgeBuilder builder(path, contours); 46 int index, end; 47 testCommon(contours, index, end); 48 SkASSERT(index + 1 == end); 49 } 50 51 static void test(const SkPath& path, SkScalar x1, SkScalar y1, 52 SkScalar x2, SkScalar y2) { 53 SkTArray<SimplifyFindTopTest::Contour> contours; 54 SimplifyFindTopTest::EdgeBuilder builder(path, contours); 55 int index, end; 56 const SimplifyFindTopTest::Segment* topSegment = 57 testCommon(contours, index, end); 58 SkPoint pts[2]; 59 double firstT = topSegment->t(index); 60 pts[0] = topSegment->xyAtT(&topSegment->span(index)); 61 int direction = index < end ? 1 : -1; 62 do { 63 index += direction; 64 double nextT = topSegment->t(index); 65 if (nextT == firstT) { 66 continue; 67 } 68 pts[1] = topSegment->xyAtT(&topSegment->span(index)); 69 if (pts[0] != pts[1]) { 70 break; 71 } 72 } while (true); 73 SkASSERT(pts[0].fX == x1); 74 SkASSERT(pts[0].fY == y1); 75 SkASSERT(pts[1].fX == x2); 76 SkASSERT(pts[1].fY == y2); 77 } 78 79 static void testLine1() { 80 SkPath path; 81 path.moveTo(2,0); 82 path.lineTo(1,1); 83 path.lineTo(0,0); 84 path.close(); 85 test(path); 86 } 87 88 static void addInnerCWTriangle(SkPath& path) { 89 path.moveTo(3,0); 90 path.lineTo(4,1); 91 path.lineTo(2,1); 92 path.close(); 93 } 94 95 static void addInnerCCWTriangle(SkPath& path) { 96 path.moveTo(3,0); 97 path.lineTo(2,1); 98 path.lineTo(4,1); 99 path.close(); 100 } 101 102 static void addOuterCWTriangle(SkPath& path) { 103 path.moveTo(3,0); 104 path.lineTo(6,2); 105 path.lineTo(0,2); 106 path.close(); 107 } 108 109 static void addOuterCCWTriangle(SkPath& path) { 110 path.moveTo(3,0); 111 path.lineTo(0,2); 112 path.lineTo(6,2); 113 path.close(); 114 } 115 116 static void testLine2() { 117 SkPath path; 118 addInnerCWTriangle(path); 119 addOuterCWTriangle(path); 120 test(path, 0, 2, 3, 0); 121 } 122 123 static void testLine3() { 124 SkPath path; 125 addOuterCWTriangle(path); 126 addInnerCWTriangle(path); 127 test(path, 0, 2, 3, 0); 128 } 129 130 static void testLine4() { 131 SkPath path; 132 addInnerCCWTriangle(path); 133 addOuterCWTriangle(path); 134 test(path, 0, 2, 3, 0); 135 } 136 137 static void testLine5() { 138 SkPath path; 139 addOuterCWTriangle(path); 140 addInnerCCWTriangle(path); 141 test(path, 0, 2, 3, 0); 142 } 143 144 static void testLine6() { 145 SkPath path; 146 addInnerCWTriangle(path); 147 addOuterCCWTriangle(path); 148 test(path, 0, 2, 3, 0); 149 } 150 151 static void testLine7() { 152 SkPath path; 153 addOuterCCWTriangle(path); 154 addInnerCWTriangle(path); 155 test(path, 0, 2, 3, 0); 156 } 157 158 static void testLine8() { 159 SkPath path; 160 addInnerCCWTriangle(path); 161 addOuterCCWTriangle(path); 162 test(path, 0, 2, 3, 0); 163 } 164 165 static void testLine9() { 166 SkPath path; 167 addOuterCCWTriangle(path); 168 addInnerCCWTriangle(path); 169 test(path, 0, 2, 3, 0); 170 } 171 172 static void testQuads() { 173 SkPath path; 174 path.moveTo(2,0); 175 path.quadTo(1,1, 0,0); 176 path.close(); 177 test(path); 178 } 179 180 static void testCubics() { 181 SkPath path; 182 path.moveTo(2,0); 183 path.cubicTo(2,3, 1,1, 0,0); 184 path.close(); 185 test(path); 186 } 187 188 static void (*tests[])() = { 189 testLine1, 190 testLine2, 191 testLine3, 192 testLine4, 193 testLine5, 194 testLine6, 195 testLine7, 196 testLine8, 197 testLine9, 198 testQuads, 199 testCubics 200 }; 201 202 static const size_t testCount = sizeof(tests) / sizeof(tests[0]); 203 204 static void (*firstTest)() = 0; 205 static bool skipAll = false; 206 207 void SimplifyFindTop_Test() { 208 if (skipAll) { 209 return; 210 } 211 size_t index = 0; 212 if (firstTest) { 213 while (index < testCount && tests[index] != firstTest) { 214 ++index; 215 } 216 } 217 bool firstTestComplete = false; 218 for ( ; index < testCount; ++index) { 219 (*tests[index])(); 220 firstTestComplete = true; 221 } 222 } 223