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
testCommon(SkTArray<SimplifyFindTopTest::Contour> & contours,int & index,int & end)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
test(const SkPath & path)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
test(const SkPath & path,SkScalar x1,SkScalar y1,SkScalar x2,SkScalar y2)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
testLine1()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
addInnerCWTriangle(SkPath & path)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
addInnerCCWTriangle(SkPath & path)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
addOuterCWTriangle(SkPath & path)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
addOuterCCWTriangle(SkPath & path)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
testLine2()116 static void testLine2() {
117 SkPath path;
118 addInnerCWTriangle(path);
119 addOuterCWTriangle(path);
120 test(path, 0, 2, 3, 0);
121 }
122
testLine3()123 static void testLine3() {
124 SkPath path;
125 addOuterCWTriangle(path);
126 addInnerCWTriangle(path);
127 test(path, 0, 2, 3, 0);
128 }
129
testLine4()130 static void testLine4() {
131 SkPath path;
132 addInnerCCWTriangle(path);
133 addOuterCWTriangle(path);
134 test(path, 0, 2, 3, 0);
135 }
136
testLine5()137 static void testLine5() {
138 SkPath path;
139 addOuterCWTriangle(path);
140 addInnerCCWTriangle(path);
141 test(path, 0, 2, 3, 0);
142 }
143
testLine6()144 static void testLine6() {
145 SkPath path;
146 addInnerCWTriangle(path);
147 addOuterCCWTriangle(path);
148 test(path, 0, 2, 3, 0);
149 }
150
testLine7()151 static void testLine7() {
152 SkPath path;
153 addOuterCCWTriangle(path);
154 addInnerCWTriangle(path);
155 test(path, 0, 2, 3, 0);
156 }
157
testLine8()158 static void testLine8() {
159 SkPath path;
160 addInnerCCWTriangle(path);
161 addOuterCCWTriangle(path);
162 test(path, 0, 2, 3, 0);
163 }
164
testLine9()165 static void testLine9() {
166 SkPath path;
167 addOuterCCWTriangle(path);
168 addInnerCCWTriangle(path);
169 test(path, 0, 2, 3, 0);
170 }
171
testQuads()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
testCubics()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
SimplifyFindTop_Test()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