Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: src/pathops/SkPathOpsOp.cpp

Issue 633393002: harden pathops for pathological test (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: exclude new test that asserts in debug Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsPoint.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "SkAddIntersections.h" 7 #include "SkAddIntersections.h"
8 #include "SkOpEdgeBuilder.h" 8 #include "SkOpEdgeBuilder.h"
9 #include "SkPathOpsCommon.h" 9 #include "SkPathOpsCommon.h"
10 #include "SkPathWriter.h" 10 #include "SkPathWriter.h"
(...skipping 27 matching lines...) Expand all
38 } 38 }
39 if (!sortable) { 39 if (!sortable) {
40 continue; 40 continue;
41 } 41 }
42 // find first angle, initialize winding to computed fWindSum 42 // find first angle, initialize winding to computed fWindSum
43 const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex); 43 const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex);
44 if (!angle) { 44 if (!angle) {
45 continue; 45 continue;
46 } 46 }
47 const SkOpAngle* firstAngle = angle; 47 const SkOpAngle* firstAngle = angle;
48 SkDEBUGCODE(bool loop = false); 48 bool loop = false;
49 int winding; 49 int winding = SK_MinS32;
50 do { 50 do {
51 angle = angle->next(); 51 angle = angle->next();
52 SkASSERT(angle != firstAngle || !loop); 52 if (angle == firstAngle && loop) {
53 SkDEBUGCODE(loop |= angle == firstAngle); 53 break; // if we get here, there's no winding, loop is unorder able
54 }
55 loop |= angle == firstAngle;
54 segment = angle->segment(); 56 segment = angle->segment();
55 winding = segment->windSum(angle); 57 winding = segment->windSum(angle);
56 } while (winding == SK_MinS32); 58 } while (winding == SK_MinS32);
59 if (winding == SK_MinS32) {
60 continue;
61 }
57 int sumMiWinding = segment->updateWindingReverse(angle); 62 int sumMiWinding = segment->updateWindingReverse(angle);
58 int sumSuWinding = segment->updateOppWindingReverse(angle); 63 int sumSuWinding = segment->updateOppWindingReverse(angle);
59 if (segment->operand()) { 64 if (segment->operand()) {
60 SkTSwap<int>(sumMiWinding, sumSuWinding); 65 SkTSwap<int>(sumMiWinding, sumSuWinding);
61 } 66 }
62 SkOpSegment* first = NULL; 67 SkOpSegment* first = NULL;
63 while ((angle = angle->next()) != firstAngle) { 68 bool badData = false;
69 while ((angle = angle->next()) != firstAngle && !badData) {
64 segment = angle->segment(); 70 segment = angle->segment();
65 int start = angle->start(); 71 int start = angle->start();
66 int end = angle->end(); 72 int end = angle->end();
67 int maxWinding, sumWinding, oppMaxWinding, oppSumWinding; 73 int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
68 segment->setUpWindings(start, end, &sumMiWinding, &sumSuWinding, 74 segment->setUpWindings(start, end, &sumMiWinding, &sumSuWinding,
69 &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding); 75 &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
70 if (!segment->done(angle)) { 76 if (!segment->done(angle)) {
71 if (!first) { 77 if (!first) {
72 first = segment; 78 first = segment;
73 *tIndex = start; 79 *tIndex = start;
74 *endIndex = end; 80 *endIndex = end;
75 } 81 }
82 if (segment->inconsistentAngle(maxWinding, sumWinding, oppMaxWin ding,
83 oppSumWinding, angle)) {
84 badData = true;
85 break;
86 }
76 // OPTIMIZATION: should this also add to the chase? 87 // OPTIMIZATION: should this also add to the chase?
77 (void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding, 88 (void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
78 oppSumWinding, angle); 89 oppSumWinding, angle);
79 } 90 }
80 } 91 }
92 if (badData) {
93 continue;
94 }
81 if (first) { 95 if (first) {
82 #if TRY_ROTATE 96 #if TRY_ROTATE
83 *chase.insert(0) = span; 97 *chase.insert(0) = span;
84 #else 98 #else
85 *chase.append() = span; 99 *chase.append() = span;
86 #endif 100 #endif
87 return first; 101 return first;
88 } 102 }
89 } 103 }
90 return NULL; 104 return NULL;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 }; 252 };
239 253
240 static const bool gOutInverse[kReverseDifference_PathOp + 1][2][2] = { 254 static const bool gOutInverse[kReverseDifference_PathOp + 1][2][2] = {
241 {{ false, false }, { true, false }}, // diff 255 {{ false, false }, { true, false }}, // diff
242 {{ false, false }, { false, true }}, // sect 256 {{ false, false }, { false, true }}, // sect
243 {{ false, true }, { true, true }}, // union 257 {{ false, true }, { true, true }}, // union
244 {{ false, true }, { true, false }}, // xor 258 {{ false, true }, { true, false }}, // xor
245 {{ false, true }, { false, false }}, // rev diff 259 {{ false, true }, { false, false }}, // rev diff
246 }; 260 };
247 261
262 #define DEBUGGING_PATHOPS_FROM_HOST 0 // enable to debug svg in chrome -- note path hardcoded below
263 #if DEBUGGING_PATHOPS_FROM_HOST
264 #include "SkData.h"
265 #include "SkStream.h"
266
267 static void dump_path(FILE* file, const SkPath& path, bool force, bool dumpAsHex ) {
268 SkDynamicMemoryWStream wStream;
269 path.dump(&wStream, force, dumpAsHex);
270 SkAutoDataUnref data(wStream.copyToData());
271 fprintf(file, "%.*s\n", (int) data->size(), data->data());
272 }
273
274 static int dumpID = 0;
275
276 static void dump_op(const SkPath& one, const SkPath& two, SkPathOp op) {
277 #if SK_BUILD_FOR_MAC
278 FILE* file = fopen("/Users/caryclark/Documents/svgop.txt", "w");
279 #else
280 FILE* file = fopen("/usr/local/google/home/caryclark/Documents/svgop.txt", " w");
281 #endif
282 fprintf(file,
283 "\nstatic void fuzz763_%d(skiatest::Reporter* reporter, const char* filename) {\n",
284 ++dumpID);
285 fprintf(file, " SkPath path;\n");
286 fprintf(file, " path.setFillType((SkPath::FillType) %d);\n", one.getFillT ype());
287 dump_path(file, one, false, true);
288 fprintf(file, " SkPath path1(path);\n");
289 fprintf(file, " path.reset();\n");
290 fprintf(file, " path.setFillType((SkPath::FillType) %d);\n", two.getFillT ype());
291 dump_path(file, two, false, true);
292 fprintf(file, " SkPath path2(path);\n");
293 fprintf(file, " testPathOp(reporter, path1, path2, (SkPathOp) %d, filenam e);\n", op);
294 fprintf(file, "}\n");
295 fclose(file);
296 }
297 #endif
298
248 bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { 299 bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
300 #if DEBUGGING_PATHOPS_FROM_HOST
301 dump_op(one, two, op);
302 #endif
249 #if DEBUG_SHOW_TEST_NAME 303 #if DEBUG_SHOW_TEST_NAME
250 char* debugName = DEBUG_FILENAME_STRING; 304 char* debugName = DEBUG_FILENAME_STRING;
251 if (debugName && debugName[0]) { 305 if (debugName && debugName[0]) {
252 SkPathOpsDebug::BumpTestName(debugName); 306 SkPathOpsDebug::BumpTestName(debugName);
253 SkPathOpsDebug::ShowPath(one, two, op, debugName); 307 SkPathOpsDebug::ShowPath(one, two, op, debugName);
254 } 308 }
255 #endif 309 #endif
256 op = gOpInverse[op][one.isInverseFillType()][two.isInverseFillType()]; 310 op = gOpInverse[op][one.isInverseFillType()][two.isInverseFillType()];
257 SkPath::FillType fillType = gOutInverse[op][one.isInverseFillType()][two.isI nverseFillType()] 311 SkPath::FillType fillType = gOutInverse[op][one.isInverseFillType()][two.isI nverseFillType()]
258 ? SkPath::kInverseEvenOdd_FillType : SkPath::kEvenOdd_FillType; 312 ? SkPath::kInverseEvenOdd_FillType : SkPath::kEvenOdd_FillType;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 { // if some edges could not be resolved, assemble remaining fragments 371 { // if some edges could not be resolved, assemble remaining fragments
318 SkPath temp; 372 SkPath temp;
319 temp.setFillType(fillType); 373 temp.setFillType(fillType);
320 SkPathWriter assembled(temp); 374 SkPathWriter assembled(temp);
321 Assemble(wrapper, &assembled); 375 Assemble(wrapper, &assembled);
322 *result = *assembled.nativePath(); 376 *result = *assembled.nativePath();
323 result->setFillType(fillType); 377 result->setFillType(fillType);
324 } 378 }
325 return true; 379 return true;
326 } 380 }
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsPoint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698