blob: 89123bd80fb4f4257b07302e00610560224ed825 [file] [log] [blame]
caryclark@google.comb45a1b42012-05-18 20:50:33 +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 */
7
8#include "Simplify.h"
9
10namespace SimplifyAngleTest {
11
12#include "Simplify.cpp"
13
14} // end of SimplifyAngleTest namespace
15
16#include "Intersection_Tests.h"
17
18static const SkPoint lines[][2] = {
19 { { 10, 10}, { 10, 20} },
20 { { 10, 10}, { 20, 10} },
21 { { 10, 10}, {-20, 10} },
22 { { 10, 10}, { 10, -20} },
23 { { 10, 10}, { 20, 20} },
24 { { 10, 10}, {-20, -20} },
25 { { 10, 10}, {-20, 40} },
26 { { 10, 10}, { 40, -20} }
27};
28
29static const size_t lineCount = sizeof(lines) / sizeof(lines[0]);
30
31static const SkPoint quads[][3] = {
32 {{ 1, 1}, { 2, 2}, { 1, 3}}, // 0
33 {{ 1, 1}, { 3, 3}, { 1, 5}}, // 1
34 {{ 1, 1}, { 4, 4}, { 1, 7}}, // 2
35 {{ 1, 1}, { 5, 5}, { 9, 9}}, // 3
36 {{ 1, 1}, { 4, 4}, { 7, 1}}, // 4
37 {{ 1, 1}, { 3, 3}, { 5, 1}}, // 5
38 {{ 1, 1}, { 2, 2}, { 3, 1}}, // 6
39};
40
41static const size_t quadCount = sizeof(quads) / sizeof(quads[0]);
42
43static const SkPoint cubics[][4] = {
44 {{ 1, 1}, { 2, 2}, { 2, 3}, { 1, 4}},
45 {{ 1, 1}, { 3, 3}, { 3, 5}, { 1, 7}},
46 {{ 1, 1}, { 4, 4}, { 4, 7}, { 1, 10}},
47 {{ 1, 1}, { 5, 5}, { 8, 8}, { 9, 9}},
48 {{ 1, 1}, { 4, 4}, { 7, 4}, { 10, 1}},
49 {{ 1, 1}, { 3, 3}, { 5, 3}, { 7, 1}},
50 {{ 1, 1}, { 2, 2}, { 3, 2}, { 4, 1}},
51};
52
53static const size_t cubicCount = sizeof(cubics) / sizeof(cubics[0]);
54
55static void testLines(bool testFlat) {
56 // create angles in a circle
57 SkTDArray<SimplifyAngleTest::Angle> angles;
58 SkTDArray<SimplifyAngleTest::Angle* > angleList;
59 SkTDArray<double> arcTans;
60 size_t x;
61 for (x = 0; x < lineCount; ++x) {
62 SimplifyAngleTest::Angle* angle = angles.append();
63 if (testFlat) {
64 angle->setFlat(lines[x], SkPath::kLine_Verb, 0, x, x + 1, false);
65 } else {
66 angle->set(lines[x], SkPath::kLine_Verb, 0, x, x + 1, false);
67 }
68 double arcTan = atan2(lines[x][0].fX - lines[x][1].fX,
69 lines[x][0].fY - lines[x][1].fY);
70 arcTans.push(arcTan);
71 }
72 for (x = 0; x < lineCount; ++x) {
73 angleList.push(&angles[x]);
74 }
75 QSort<SimplifyAngleTest::Angle>(angleList.begin(), angleList.end() - 1);
76 bool first = true;
77 bool wrap = false;
78 double base, last;
79 for (size_t x = 0; x < lineCount; ++x) {
80 const SimplifyAngleTest::Angle* angle = angleList[x];
81 int span = angle->start();
82// SkDebugf("%s [%d] %1.9g (%1.9g,%1.9g %1.9g,%1.9g)\n", __FUNCTION__,
83// span, arcTans[span], lines[span][0].fX, lines[span][0].fY,
84// lines[span][1].fX, lines[span][1].fY);
85 if (first) {
86 base = last = arcTans[span];
87 first = false;
88 continue;
89 }
90 if (last < arcTans[span]) {
91 last = arcTans[span];
92 continue;
93 }
94 if (!wrap) {
95 if (base < arcTans[span]) {
96 SkDebugf("%s !wrap [%d] %g\n", __FUNCTION__, span, arcTans[span]);
97 SkASSERT(0);
98 }
99 last = arcTans[span];
100 wrap = true;
101 continue;
102 }
103 SkDebugf("%s wrap [%d] %g\n", __FUNCTION__, span, arcTans[span]);
104 SkASSERT(0);
105 }
106}
107
108static void testQuads(bool testFlat) {
109 SkTDArray<SimplifyAngleTest::Angle> angles;
110 SkTDArray<SimplifyAngleTest::Angle* > angleList;
111 size_t x;
112 for (x = 0; x < quadCount; ++x) {
113 SimplifyAngleTest::Angle* angle = angles.append();
114 if (testFlat) {
115 angle->setFlat(quads[x], SkPath::kQuad_Verb, 0, x, x + 1, false);
116 } else {
117 angle->set(quads[x], SkPath::kQuad_Verb, 0, x, x + 1, false);
118 }
119 }
120 for (x = 0; x < quadCount; ++x) {
121 angleList.push(&angles[x]);
122 }
123 QSort<SimplifyAngleTest::Angle>(angleList.begin(), angleList.end() - 1);
124 for (size_t x = 0; x < quadCount; ++x) {
125 *angleList[x] < *angleList[x + 1];
126 SkASSERT(x == quadCount - 1 || *angleList[x] < *angleList[x + 1]);
127 const SimplifyAngleTest::Angle* angle = angleList[x];
128 if (x != angle->start()) {
129 SkDebugf("%s [%d] [%d]\n", __FUNCTION__, x, angle->start());
130 SkASSERT(0);
131 }
132 }
133}
134
135static void testCubics(bool testFlat) {
136 SkTDArray<SimplifyAngleTest::Angle> angles;
137 SkTDArray<SimplifyAngleTest::Angle* > angleList;
138 for (size_t x = 0; x < cubicCount; ++x) {
139 SimplifyAngleTest::Angle* angle = angles.append();
140 if (testFlat) {
141 angle->setFlat(cubics[x], SkPath::kCubic_Verb, 0, x, x + 1, false);
142 } else {
143 angle->set(cubics[x], SkPath::kCubic_Verb, 0, x, x + 1, false);
144 }
145 angleList.push(angle);
146 }
147 QSort<SimplifyAngleTest::Angle>(angleList.begin(), angleList.end() - 1);
148 for (size_t x = 0; x < cubicCount; ++x) {
149 const SimplifyAngleTest::Angle* angle = angleList[x];
150 if (x != angle->start()) {
151 SkDebugf("%s [%d] [%d]\n", __FUNCTION__, x, angle->start());
152 SkASSERT(0);
153 }
154 }
155}
156
157static void (*tests[])(bool) = {
158 testLines,
159 testQuads,
160 testCubics
161};
162
163static const size_t testCount = sizeof(tests) / sizeof(tests[0]);
164
165static void (*firstTest)(bool) = 0;
166static bool skipAll = false;
167
168void SimplifyAngle_Test() {
169 if (skipAll) {
170 return;
171 }
172 size_t index = 0;
173 if (firstTest) {
174 while (index < testCount && tests[index] != firstTest) {
175 ++index;
176 }
177 }
178 bool firstTestComplete = false;
179 for ( ; index < testCount; ++index) {
180 (*tests[index])(true);
181 firstTestComplete = true;
182 }
183}