OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include "SkOpSegment.h" | 7 #include "SkOpSegment.h" |
8 #include "Test.h" | 8 #include "Test.h" |
9 | 9 |
10 static const SkPoint cubics[][4] = { | 10 static const SkPoint cubics[][4] = { |
11 {{0, 1}, {2, 6}, {4, 2}, {5, 3}}, | 11 {{0, 1}, {2, 6}, {4, 2}, {5, 3}}, |
12 {{10, 234}, {10, 229.581726f}, {13.5817204f, 226}, {18, 226}}, | 12 {{10, 234}, {10, 229.581726f}, {13.5817204f, 226}, {18, 226}}, |
| 13 {{132, 11419}, {130.89543151855469f, 11419}, {130, 11418.1044921875f}, {130,
11417}}, |
| 14 {{130.04275512695312f, 11417.4130859375f}, {130.23307800292969f, 11418.31933
59375f}, |
| 15 {131.03709411621094f, 11419}, {132, 11419}}, |
| 16 {{0,1}, {0,5}, {4,1}, {6,4}}, |
13 }; | 17 }; |
14 | 18 |
15 static const SkPoint quads[][3] = { | 19 static const SkPoint quads[][3] = { |
16 {{12.3423996f, 228.342407f}, {10, 230.686295f}, {10, 234}}, | 20 {{12.3423996f, 228.342407f}, {10, 230.686295f}, {10, 234}}, |
| 21 {{304.24319458007812f,591.75677490234375f}, {306,593.51470947265625f}, {306,
596}}, |
17 }; | 22 }; |
18 | 23 |
19 static const SkPoint lines[][2] = { | 24 static const SkPoint lines[][2] = { |
20 {{6, 2}, {2, 4}}, | 25 {{6, 2}, {2, 4}}, |
| 26 {{306,617}, {306,590}}, |
| 27 {{306,596}, {306,617}}, |
| 28 {{6,4}, {0,1}}, |
21 }; | 29 }; |
22 | 30 |
23 struct SortSet { | 31 struct SortSet { |
24 const SkPoint* ptData; | 32 const SkPoint* ptData; |
25 int ptCount; | 33 int ptCount; |
26 double tStart; | 34 double tStart; |
27 double tEnd; | 35 double tEnd; |
| 36 SkPoint endPt; |
| 37 }; |
| 38 |
| 39 static const SortSet set6[] = { |
| 40 {lines[3], 2, 0.407407407, 0.554627832}, |
| 41 {cubics[4], 4, 0.666666667, 0.548022446}, |
| 42 {lines[3], 2, 0.407407407, 0}, |
| 43 {cubics[4], 4, 0.666666667, 1}, |
28 }; | 44 }; |
29 | 45 |
30 static const SortSet set1[] = { | 46 static const SortSet set1[] = { |
31 {cubics[0], 4, 0.66666987081928919, 0.875}, | 47 {cubics[0], 4, 0.66666987081928919, 0.875}, |
32 {lines[0], 2, 0.574070336, 0.388888889}, | 48 {lines[0], 2, 0.574070336, 0.388888889}, |
33 {cubics[0], 4, 0.66666987081928919, 0.4050371120499307 }, | 49 {cubics[0], 4, 0.66666987081928919, 0.4050371120499307 }, |
34 {lines[0], 2, 0.574070336, 0.9140625}, | 50 {lines[0], 2, 0.574070336, 0.9140625}, |
35 }; | 51 }; |
36 | 52 |
| 53 static const SortSet set1a[] = { |
| 54 {cubics[0], 4, 0.666666667, 0.405037112, {4.58007812f,2.83203125f}}, |
| 55 {lines[0], 2, 0.574074074, 0.9140625, {4.44444466f,2.77777767f}}, |
| 56 }; |
| 57 |
37 static const SortSet set2[] = { | 58 static const SortSet set2[] = { |
38 {cubics[0], 4, 0.666666667, 0.875}, | 59 {cubics[0], 4, 0.666666667, 0.875}, |
39 {lines[0], 2, 0.574074074, 0.388888889}, | 60 {lines[0], 2, 0.574074074, 0.388888889}, |
40 {cubics[0], 4, 0.666666667, 0.405037112}, | 61 {cubics[0], 4, 0.666666667, 0.405037112}, |
41 {lines[0], 2, 0.574074074, 0.9140625}, | 62 {lines[0], 2, 0.574074074, 0.9140625}, |
42 }; | 63 }; |
43 | 64 |
44 static const SortSet set3[] = { | 65 static const SortSet set3[] = { |
45 {cubics[1], 4, 0, 1}, | 66 {cubics[1], 4, 0, 1}, |
46 {quads[0], 3, 1, 0}, | 67 {quads[0], 3, 1, 0}, |
47 }; | 68 }; |
48 | 69 |
| 70 static const SortSet set4[] = { |
| 71 {cubics[2], 4, 0.812114222, 1}, |
| 72 {cubics[3], 4, 0.0684734759, 0}, |
| 73 }; |
| 74 |
| 75 static const SortSet set5[] = { |
| 76 {lines[1], 2, 0.777777778, 1}, |
| 77 {quads[1], 3, 1, 4.34137342e-06}, |
| 78 {lines[2], 2, 0, 1}, |
| 79 }; |
| 80 |
| 81 static const SortSet set5a[] = { |
| 82 {lines[1], 2, 0.777777778, 1, {306,590}}, |
| 83 {quads[1], 3, 1, 4.34137342e-06, {304.243195f,591.756775f}}, |
| 84 {lines[2], 2, 0, 1, {306,617}}, |
| 85 }; |
| 86 |
49 struct SortSetTests { | 87 struct SortSetTests { |
50 const SortSet* set; | 88 const SortSet* set; |
51 size_t count; | 89 size_t count; |
| 90 SkPoint startPt; |
52 }; | 91 }; |
53 | 92 |
54 static const SortSetTests tests[] = { | 93 static const SortSetTests tests[] = { |
| 94 { set5, SK_ARRAY_COUNT(set5) }, |
| 95 { set6, SK_ARRAY_COUNT(set6) }, |
| 96 { set5a, SK_ARRAY_COUNT(set5a), {306,596} }, |
| 97 { set1a, SK_ARRAY_COUNT(set1a), {3.70370364f,3.14814806f} }, |
| 98 { set4, SK_ARRAY_COUNT(set4) }, |
55 { set3, SK_ARRAY_COUNT(set3) }, | 99 { set3, SK_ARRAY_COUNT(set3) }, |
56 { set2, SK_ARRAY_COUNT(set2) }, | 100 { set2, SK_ARRAY_COUNT(set2) }, |
57 { set1, SK_ARRAY_COUNT(set1) }, | 101 { set1, SK_ARRAY_COUNT(set1) }, |
58 }; | 102 }; |
59 | 103 |
60 static void setup(const SortSet* set, const size_t idx, SkPoint const ** data, | 104 static void setup(const SortSet* set, const size_t idx, SkPoint const ** data, |
61 SkOpSegment* seg, int* ts) { | 105 SkOpSegment* seg, int* ts, const SkPoint& startPt) { |
62 SkPoint start, end; | 106 SkPoint start, end; |
63 *data = set[idx].ptData; | 107 *data = set[idx].ptData; |
| 108 bool useIntersectPt = startPt.fX != 0 || startPt.fY != 0; |
| 109 if (useIntersectPt) { |
| 110 start = startPt; |
| 111 end = set[idx].endPt; |
| 112 } |
64 switch(set[idx].ptCount) { | 113 switch(set[idx].ptCount) { |
65 case 2: { | 114 case 2: { |
66 seg->addLine(*data, false, false); | 115 seg->addLine(*data, false, false); |
67 SkDLine dLine; | 116 SkDLine dLine; |
68 dLine.set(set[idx].ptData); | 117 dLine.set(set[idx].ptData); |
| 118 if (useIntersectPt) { |
| 119 break; |
| 120 } |
69 start = dLine.xyAtT(set[idx].tStart).asSkPoint(); | 121 start = dLine.xyAtT(set[idx].tStart).asSkPoint(); |
70 end = dLine.xyAtT(set[idx].tEnd).asSkPoint(); | 122 end = dLine.xyAtT(set[idx].tEnd).asSkPoint(); |
71 } break; | 123 } break; |
72 case 3: { | 124 case 3: { |
73 seg->addQuad(*data, false, false); | 125 seg->addQuad(*data, false, false); |
74 SkDQuad dQuad; | 126 SkDQuad dQuad; |
75 dQuad.set(set[idx].ptData); | 127 dQuad.set(set[idx].ptData); |
| 128 if (useIntersectPt) { |
| 129 break; |
| 130 } |
76 start = dQuad.xyAtT(set[idx].tStart).asSkPoint(); | 131 start = dQuad.xyAtT(set[idx].tStart).asSkPoint(); |
77 end = dQuad.xyAtT(set[idx].tEnd).asSkPoint(); | 132 end = dQuad.xyAtT(set[idx].tEnd).asSkPoint(); |
78 } break; | 133 } break; |
79 case 4: { | 134 case 4: { |
80 seg->addCubic(*data, false, false); | 135 seg->addCubic(*data, false, false); |
81 SkDCubic dCubic; | 136 SkDCubic dCubic; |
82 dCubic.set(set[idx].ptData); | 137 dCubic.set(set[idx].ptData); |
| 138 if (useIntersectPt) { |
| 139 break; |
| 140 } |
83 start = dCubic.xyAtT(set[idx].tStart).asSkPoint(); | 141 start = dCubic.xyAtT(set[idx].tStart).asSkPoint(); |
84 end = dCubic.xyAtT(set[idx].tEnd).asSkPoint(); | 142 end = dCubic.xyAtT(set[idx].tEnd).asSkPoint(); |
85 } break; | 143 } break; |
86 } | 144 } |
87 double tStart = set[idx].tStart; | 145 double tStart = set[idx].tStart; |
88 double tEnd = set[idx].tEnd; | 146 double tEnd = set[idx].tEnd; |
89 seg->addT(NULL, start, tStart); | 147 seg->addT(NULL, start, tStart); |
90 seg->addT(NULL, end, tEnd); | 148 seg->addT(NULL, end, tEnd); |
91 double tLeft = tStart < tEnd ? 0 : 1; | 149 // double tLeft = tStart < tEnd ? 0 : 1; |
92 if (tStart != tLeft && tEnd != tLeft) { | 150 if (tStart != 0 && tEnd != 0) { |
93 seg->addT(NULL, set[idx].ptData[0], tLeft); | 151 seg->addT(NULL, set[idx].ptData[0], 0); |
94 } | 152 } |
95 double tRight = tStart < tEnd ? 1 : 0; | 153 // double tRight = tStart < tEnd ? 1 : 0; |
96 if (tStart != tRight && tEnd != tRight) { | 154 if (tStart != 1 && tEnd != 1) { |
97 seg->addT(NULL, set[idx].ptData[set[idx].ptCount - 1], tRight); | 155 seg->addT(NULL, set[idx].ptData[set[idx].ptCount - 1], 1); |
98 } | 156 } |
99 int tIndex = 0; | 157 int tIndex = 0; |
100 do { | 158 do { |
101 if (seg->t(tIndex) == set[idx].tStart) { | 159 if (seg->t(tIndex) == set[idx].tStart) { |
102 ts[0] = tIndex; | 160 ts[0] = tIndex; |
103 } | 161 } |
104 if (seg->t(tIndex) == set[idx].tEnd) { | 162 if (seg->t(tIndex) == set[idx].tEnd) { |
105 ts[1] = tIndex; | 163 ts[1] = tIndex; |
106 } | 164 } |
107 if (seg->t(tIndex) >= 1) { | 165 if (seg->t(tIndex) >= 1) { |
108 break; | 166 break; |
109 } | 167 } |
110 } while (++tIndex); | 168 } while (++tIndex); |
111 } | 169 } |
112 | 170 |
113 static void PathOpsAngleTest(skiatest::Reporter* reporter) { | 171 static void PathOpsAngleTest(skiatest::Reporter* reporter) { |
114 for (size_t index = 0; index < SK_ARRAY_COUNT(tests); ++index) { | 172 for (size_t index = 0; index < SK_ARRAY_COUNT(tests); ++index) { |
115 const SortSetTests& test = tests[index]; | 173 const SortSetTests& test = tests[index]; |
116 for (size_t idxL = 0; idxL < test.count - 1; ++idxL) { | 174 for (size_t idxL = 0; idxL < test.count - 1; ++idxL) { |
117 SkOpSegment lesser, greater; | 175 SkOpSegment lesser, greater; |
118 int lesserTs[2], greaterTs[2]; | 176 int lesserTs[2], greaterTs[2]; |
119 const SkPoint* lesserData, * greaterData; | 177 const SkPoint* lesserData, * greaterData; |
120 const SortSet* set = test.set; | 178 const SortSet* set = test.set; |
121 setup(set, idxL, &lesserData, &lesser, lesserTs); | 179 setup(set, idxL, &lesserData, &lesser, lesserTs, test.startPt); |
122 size_t idxG = idxL + 1; | 180 size_t idxG = idxL + 1; |
123 setup(set, idxG, &greaterData, &greater, greaterTs); | 181 setup(set, idxG, &greaterData, &greater, greaterTs, test.startPt); |
124 SkOpAngle first, second; | 182 SkOpAngle first, second; |
125 first.set(lesserData, (SkPath::Verb) (set[idxL].ptCount - 1), &lesse
r, | 183 first.set(lesserData, (SkPath::Verb) (set[idxL].ptCount - 1), &lesse
r, |
126 lesserTs[0], lesserTs[1], lesser.spans()); | 184 lesserTs[0], lesserTs[1], lesser.spans()); |
127 second.set(greaterData, (SkPath::Verb) (set[idxG].ptCount - 1), &gre
ater, | 185 second.set(greaterData, (SkPath::Verb) (set[idxG].ptCount - 1), &gre
ater, |
128 greaterTs[0], greaterTs[1], greater.spans()); | 186 greaterTs[0], greaterTs[1], greater.spans()); |
129 bool compare = first < second; | 187 bool compare = first < second; |
130 if (!compare) { | 188 if (!compare) { |
131 SkDebugf("%s test[%d]: lesser[%d] > greater[%d]\n", __FUNCTION_
_, | 189 SkDebugf("%s test[%d]: lesser[%d] > greater[%d]\n", __FUNCTION_
_, |
132 index, idxL, idxG); | 190 index, idxL, idxG); |
| 191 compare = first < second; |
133 } | 192 } |
134 REPORTER_ASSERT(reporter, compare); | 193 REPORTER_ASSERT(reporter, compare); |
| 194 reporter->bumpTestCount(); |
135 } | 195 } |
136 } | 196 } |
137 } | 197 } |
138 | 198 |
139 #include "TestClassDef.h" | 199 #include "TestClassDef.h" |
140 DEFINE_TESTCLASS_SHORT(PathOpsAngleTest) | 200 DEFINE_TESTCLASS_SHORT(PathOpsAngleTest) |
OLD | NEW |