OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 | 7 |
8 #include "PathOpsExtendedTest.h" | 8 #include "PathOpsExtendedTest.h" |
9 #include "PathOpsThreadedCommon.h" | 9 #include "PathOpsThreadedCommon.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 "i", | 38 "i", |
39 "u", | 39 "u", |
40 "o", | 40 "o", |
41 }; | 41 }; |
42 | 42 |
43 static bool gShowPath = false; | 43 static bool gShowPath = false; |
44 static bool gComparePaths = true; | 44 static bool gComparePaths = true; |
45 static bool gComparePathsAssert = true; | 45 static bool gComparePathsAssert = true; |
46 static bool gPathStrAssert = true; | 46 static bool gPathStrAssert = true; |
47 | 47 |
48 static void showPathContours(SkPath::Iter& iter) { | 48 static void showPathContours(SkPath::Iter& iter, const char* suffix) { |
49 uint8_t verb; | 49 uint8_t verb; |
50 SkPoint pts[4]; | 50 SkPoint pts[4]; |
51 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | 51 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
52 switch (verb) { | 52 switch (verb) { |
53 case SkPath::kMove_Verb: | 53 case SkPath::kMove_Verb: |
54 SkDebugf("path.moveTo(%1.9g,%1.9g);\n", pts[0].fX, pts[0].fY); | 54 SkDebugf(" path%s.moveTo(%1.9g,%1.9g);\n", suffix, pts[0].fX,
pts[0].fY); |
55 continue; | 55 continue; |
56 case SkPath::kLine_Verb: | 56 case SkPath::kLine_Verb: |
57 SkDebugf("path.lineTo(%1.9g,%1.9g);\n", pts[1].fX, pts[1].fY); | 57 SkDebugf(" path%s.lineTo(%1.9g,%1.9g);\n", suffix, pts[1].fX,
pts[1].fY); |
58 break; | 58 break; |
59 case SkPath::kQuad_Verb: | 59 case SkPath::kQuad_Verb: |
60 SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n", | 60 SkDebugf(" path%s.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n", suffi
x, |
61 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); | 61 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); |
62 break; | 62 break; |
63 case SkPath::kCubic_Verb: | 63 case SkPath::kCubic_Verb: |
64 SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n
", | 64 SkDebugf(" path%s.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.
9g);\n", suffix, |
65 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3
].fY); | 65 pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3
].fY); |
66 break; | 66 break; |
67 case SkPath::kClose_Verb: | 67 case SkPath::kClose_Verb: |
68 SkDebugf("path.close();\n"); | 68 SkDebugf(" path%s.close();\n", suffix); |
69 break; | 69 break; |
70 default: | 70 default: |
71 SkDEBUGFAIL("bad verb"); | 71 SkDEBUGFAIL("bad verb"); |
72 return; | 72 return; |
73 } | 73 } |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 void showPath(const SkPath& path, const char* str) { | |
78 SkDebugf("%s\n", !str ? "original:" : str); | |
79 showPath(path); | |
80 } | |
81 | |
82 static const char* fillTypeStr[] = { | 77 static const char* fillTypeStr[] = { |
83 "kWinding_FillType", | 78 "kWinding_FillType", |
84 "kEvenOdd_FillType", | 79 "kEvenOdd_FillType", |
85 "kInverseWinding_FillType", | 80 "kInverseWinding_FillType", |
86 "kInverseEvenOdd_FillType" | 81 "kInverseEvenOdd_FillType" |
87 }; | 82 }; |
88 | 83 |
89 void showPath(const SkPath& path) { | 84 static void showPath(const SkPath& path, const char* suffix) { |
90 SkPath::Iter iter(path, true); | 85 SkPath::Iter iter(path, true); |
91 #define SUPPORT_RECT_CONTOUR_DETECTION 0 | 86 #define SUPPORT_RECT_CONTOUR_DETECTION 0 |
92 #if SUPPORT_RECT_CONTOUR_DETECTION | 87 #if SUPPORT_RECT_CONTOUR_DETECTION |
93 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0; | 88 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0; |
94 if (rectCount > 0) { | 89 if (rectCount > 0) { |
95 SkTDArray<SkRect> rects; | 90 SkTDArray<SkRect> rects; |
96 SkTDArray<SkPath::Direction> directions; | 91 SkTDArray<SkPath::Direction> directions; |
97 rects.setCount(rectCount); | 92 rects.setCount(rectCount); |
98 directions.setCount(rectCount); | 93 directions.setCount(rectCount); |
99 path.rectContours(rects.begin(), directions.begin()); | 94 path.rectContours(rects.begin(), directions.begin()); |
100 for (int contour = 0; contour < rectCount; ++contour) { | 95 for (int contour = 0; contour < rectCount; ++contour) { |
101 const SkRect& rect = rects[contour]; | 96 const SkRect& rect = rects[contour]; |
102 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLe
ft, rect.fTop, | 97 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLe
ft, rect.fTop, |
103 rect.fRight, rect.fBottom, directions[contour] == SkPath::kC
CW_Direction | 98 rect.fRight, rect.fBottom, directions[contour] == SkPath::kC
CW_Direction |
104 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction"); | 99 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction"); |
105 } | 100 } |
106 return; | 101 return; |
107 } | 102 } |
108 #endif | 103 #endif |
109 SkPath::FillType fillType = path.getFillType(); | 104 SkPath::FillType fillType = path.getFillType(); |
110 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); | 105 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); |
111 SkDebugf("path.setFillType(%s);\n", fillTypeStr[fillType]); | 106 SkDebugf(" path%s.setFillType(SkPath::%s);\n", suffix, fillTypeStr[fillTy
pe]); |
112 iter.setPath(path, true); | 107 iter.setPath(path, true); |
113 showPathContours(iter); | 108 showPathContours(iter, suffix); |
114 } | 109 } |
115 | 110 |
116 void showPathData(const SkPath& path) { | 111 #if DEBUG_SHOW_TEST_NAME |
| 112 static void showPathData(const SkPath& path) { |
117 SkPath::Iter iter(path, true); | 113 SkPath::Iter iter(path, true); |
118 uint8_t verb; | 114 uint8_t verb; |
119 SkPoint pts[4]; | 115 SkPoint pts[4]; |
120 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | 116 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
121 switch (verb) { | 117 switch (verb) { |
122 case SkPath::kMove_Verb: | 118 case SkPath::kMove_Verb: |
123 continue; | 119 continue; |
124 case SkPath::kLine_Verb: | 120 case SkPath::kLine_Verb: |
125 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].
fY, | 121 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].
fY, |
126 pts[1].fX, pts[1].fY); | 122 pts[1].fX, pts[1].fY); |
127 break; | 123 break; |
128 case SkPath::kQuad_Verb: | 124 case SkPath::kQuad_Verb: |
129 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", | 125 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", |
130 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY); | 126 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY); |
131 break; | 127 break; |
132 case SkPath::kCubic_Verb: | 128 case SkPath::kCubic_Verb: |
133 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%
1.9g}},\n", | 129 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%
1.9g}},\n", |
134 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY, | 130 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY, |
135 pts[3].fX, pts[3].fY); | 131 pts[3].fX, pts[3].fY); |
136 break; | 132 break; |
137 case SkPath::kClose_Verb: | 133 case SkPath::kClose_Verb: |
138 break; | 134 break; |
139 default: | 135 default: |
140 SkDEBUGFAIL("bad verb"); | 136 SkDEBUGFAIL("bad verb"); |
141 return; | 137 return; |
142 } | 138 } |
143 } | 139 } |
144 } | 140 } |
| 141 #endif |
145 | 142 |
146 void showOp(const SkPathOp op) { | 143 void showOp(const SkPathOp op) { |
147 switch (op) { | 144 switch (op) { |
148 case kDifference_PathOp: | 145 case kDifference_PathOp: |
149 SkDebugf("op difference\n"); | 146 SkDebugf("op difference\n"); |
150 break; | 147 break; |
151 case kIntersect_PathOp: | 148 case kIntersect_PathOp: |
152 SkDebugf("op intersect\n"); | 149 SkDebugf("op intersect\n"); |
153 break; | 150 break; |
154 case kUnion_PathOp: | 151 case kUnion_PathOp: |
155 SkDebugf("op union\n"); | 152 SkDebugf("op union\n"); |
156 break; | 153 break; |
157 case kXOR_PathOp: | 154 case kXOR_PathOp: |
158 SkDebugf("op xor\n"); | 155 SkDebugf("op xor\n"); |
159 break; | 156 break; |
160 case kReverseDifference_PathOp: | 157 case kReverseDifference_PathOp: |
161 SkDebugf("op reverse difference\n"); | 158 SkDebugf("op reverse difference\n"); |
162 break; | 159 break; |
163 default: | 160 default: |
164 SkASSERT(0); | 161 SkASSERT(0); |
165 } | 162 } |
166 } | 163 } |
167 | 164 |
| 165 #if 0 |
168 static void showPath(const SkPath& path, const char* str, const SkMatrix& scale)
{ | 166 static void showPath(const SkPath& path, const char* str, const SkMatrix& scale)
{ |
169 SkPath scaled; | 167 SkPath scaled; |
170 SkMatrix inverse; | 168 SkMatrix inverse; |
171 bool success = scale.invert(&inverse); | 169 bool success = scale.invert(&inverse); |
172 if (!success) { | 170 if (!success) { |
173 SkASSERT(0); | 171 SkASSERT(0); |
174 } | 172 } |
175 path.transform(inverse, &scaled); | 173 path.transform(inverse, &scaled); |
176 showPath(scaled, str); | 174 showPath(scaled, str); |
177 } | 175 } |
| 176 #endif |
178 | 177 |
179 #if DEBUG_SHOW_TEST_NAME | 178 #if DEBUG_SHOW_TEST_NAME |
180 static char hexorator(int x) { | 179 static char hexorator(int x) { |
181 if (x < 10) { | 180 if (x < 10) { |
182 return x + '0'; | 181 return x + '0'; |
183 } | 182 } |
184 x -= 10; | 183 x -= 10; |
185 SkASSERT(x < 26); | 184 SkASSERT(x < 26); |
186 return x + 'A'; | 185 return x + 'A'; |
187 } | 186 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; | 318 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; |
320 } | 319 } |
321 *outPtr++ = '\0'; | 320 *outPtr++ = '\0'; |
322 SkDebugf("%s\n", out); | 321 SkDebugf("%s\n", out); |
323 } | 322 } |
324 return true; | 323 return true; |
325 } | 324 } |
326 | 325 |
327 static void showSimplifiedPath(const SkPath& one, const SkPath& two, | 326 static void showSimplifiedPath(const SkPath& one, const SkPath& two, |
328 const SkPath& scaledOne, const SkPath& scaledTwo) { | 327 const SkPath& scaledOne, const SkPath& scaledTwo) { |
329 showPath(one, "original:"); | 328 showPath(one, ""); |
330 showPath(two, "simplified:"); | 329 // showPath(two, "simplified:"); |
331 drawAsciiPaths(scaledOne, scaledTwo, true); | 330 drawAsciiPaths(scaledOne, scaledTwo, true); |
332 } | 331 } |
333 | 332 |
334 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S
kPath& two, | 333 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S
kPath& two, |
335 SkBitmap& bitmap) { | 334 SkBitmap& bitmap) { |
336 int errors2x2; | 335 int errors2x2; |
337 SkPath scaledOne, scaledTwo; | 336 SkPath scaledOne, scaledTwo; |
338 int errors = pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors
2x2); | 337 int errors = pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors
2x2); |
339 if (errors2x2 == 0) { | 338 if (errors2x2 == 0) { |
340 return 0; | 339 return 0; |
341 } | 340 } |
342 const int MAX_ERRORS = 9; | 341 const int MAX_ERRORS = 9; |
343 if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { | 342 if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { |
344 showSimplifiedPath(one, two, scaledOne, scaledTwo); | 343 showSimplifiedPath(one, two, scaledOne, scaledTwo); |
345 } | 344 } |
346 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { | 345 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { |
347 SkDebugf("%s errors=%d\n", __FUNCTION__, errors); | 346 SkDebugf("%s errors=%d\n", __FUNCTION__, errors); |
348 showSimplifiedPath(one, two, scaledOne, scaledTwo); | 347 showSimplifiedPath(one, two, scaledOne, scaledTwo); |
349 REPORTER_ASSERT(reporter, 0); | 348 REPORTER_ASSERT(reporter, 0); |
350 } | 349 } |
351 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; | 350 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; |
352 } | 351 } |
353 | 352 |
354 static void showPathOpPath(const SkPath& one, const SkPath& two, const SkPath& a
, const SkPath& b, | 353 static void showPathOpPath(const SkPath& one, const SkPath& two, const SkPath& a
, const SkPath& b, |
355 const SkPath& scaledOne, const SkPath& scaledTwo, const SkPathOp shapeOp
, | 354 const SkPath& scaledOne, const SkPath& scaledTwo, const SkPathOp shapeOp
, |
356 const SkMatrix& scale) { | 355 const SkMatrix& scale) { |
357 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); | 356 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); |
358 showPath(a, "minuend:"); | 357 SkDebugf("static void xOp#%s(skiatest::Reporter* reporter) {\n", opSuffixes[
shapeOp]); |
359 SkDebugf("op: %s\n", opStrs[shapeOp]); | 358 SkDebugf(" SkPath path, pathB;\n"); |
360 showPath(b, "subtrahend:"); | 359 showPath(a, ""); |
| 360 showPath(b, "B"); |
| 361 SkDebugf(" testPathOp(reporter, path, pathB, %s);\n", opStrs[shapeOp]); |
| 362 SkDebugf("}\n"); |
361 // the region often isn't very helpful since it approximates curves with a l
ot of line-tos | 363 // the region often isn't very helpful since it approximates curves with a l
ot of line-tos |
362 if (0) showPath(scaledOne, "region:", scale); | 364 // if (0) showPath(scaledOne, "region:", scale); |
363 showPath(two, "op result:"); | 365 // showPath(two, "op result:"); |
364 drawAsciiPaths(scaledOne, scaledTwo, true); | 366 drawAsciiPaths(scaledOne, scaledTwo, true); |
365 } | 367 } |
366 | 368 |
367 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S
kPath& scaledOne, | 369 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S
kPath& scaledOne, |
368 const SkPath& two, const SkPath& scaledTwo, SkBitmap& bi
tmap, | 370 const SkPath& two, const SkPath& scaledTwo, SkBitmap& bi
tmap, |
369 const SkPath& a, const SkPath& b, const SkPathOp shapeOp
, | 371 const SkPath& a, const SkPath& b, const SkPathOp shapeOp
, |
370 const SkMatrix& scale) { | 372 const SkMatrix& scale) { |
371 int errors2x2; | 373 int errors2x2; |
372 int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); | 374 int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); |
373 if (errors2x2 == 0) { | 375 if (errors2x2 == 0) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 writeTestName(nameSuffix, outFile); | 443 writeTestName(nameSuffix, outFile); |
442 outFile.writeText("),\n"); | 444 outFile.writeText("),\n"); |
443 outFile.flush(); | 445 outFile.flush(); |
444 } | 446 } |
445 | 447 |
446 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, | 448 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, |
447 const char* pathStr) { | 449 const char* pathStr) { |
448 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; | 450 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; |
449 path.setFillType(fillType); | 451 path.setFillType(fillType); |
450 if (gShowPath) { | 452 if (gShowPath) { |
451 showPath(path); | 453 showPath(path, ""); |
452 } | 454 } |
453 if (!Simplify(path, &out)) { | 455 if (!Simplify(path, &out)) { |
454 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 456 SkDebugf("%s did not expect failure\n", __FUNCTION__); |
455 REPORTER_ASSERT(state.fReporter, 0); | 457 REPORTER_ASSERT(state.fReporter, 0); |
456 return false; | 458 return false; |
457 } | 459 } |
458 if (!gComparePaths) { | 460 if (!gComparePaths) { |
459 return true; | 461 return true; |
460 } | 462 } |
461 int result = comparePaths(state.fReporter, path, out, *state.fBitmap); | 463 int result = comparePaths(state.fReporter, path, out, *state.fBitmap); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 } | 616 } |
615 if (tests[index].fun == stopTest) { | 617 if (tests[index].fun == stopTest) { |
616 SkDebugf("lastTest\n"); | 618 SkDebugf("lastTest\n"); |
617 } | 619 } |
618 if (index == last) { | 620 if (index == last) { |
619 break; | 621 break; |
620 } | 622 } |
621 index += reverse ? -1 : 1; | 623 index += reverse ? -1 : 1; |
622 } while (true); | 624 } while (true); |
623 } | 625 } |
OLD | NEW |