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

Side by Side Diff: samplecode/SamplePathFuzz.cpp

Issue 953383002: fuzzer fixes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix up width and height in initializer Created 5 years, 9 months 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 | « samplecode/SamplePathEffects.cpp ('k') | samplecode/SampleStrokePath.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 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 "SampleCode.h"
9 #include "SkView.h"
10 #include "SkCanvas.h"
11 #include "SkPaint.h"
12 #include "SkPath.h"
13 #include "SkMatrix.h"
14 #include "SkColor.h"
15 #include "SkTDArray.h"
16 #include "SkRandom.h"
17
18 enum RandomAddPath {
19 kMoveToPath,
20 kRMoveToPath,
21 kLineToPath,
22 kRLineToPath,
23 kQuadToPath,
24 kRQuadToPath,
25 kConicToPath,
26 kRConicToPath,
27 kCubicToPath,
28 kRCubicToPath,
29 kArcToPath,
30 kArcTo2Path,
31 kClosePath,
32 kAddArc,
33 kAddRoundRect1,
34 kAddRoundRect2,
35 kAddRRect,
36 kAddPoly,
37 kAddPath1,
38 kAddPath2,
39 kAddPath3,
40 kReverseAddPath,
41 };
42
43 const int kRandomAddPath_Last = kReverseAddPath;
44
45 const char* gRandomAddPathNames[] = {
46 "kMoveToPath",
47 "kRMoveToPath",
48 "kLineToPath",
49 "kRLineToPath",
50 "kQuadToPath",
51 "kRQuadToPath",
52 "kConicToPath",
53 "kRConicToPath",
54 "kCubicToPath",
55 "kRCubicToPath",
56 "kArcToPath",
57 "kArcTo2Path",
58 "kClosePath",
59 "kAddArc",
60 "kAddRoundRect1",
61 "kAddRoundRect2",
62 "kAddRRect",
63 "kAddPoly",
64 "kAddPath1",
65 "kAddPath2",
66 "kAddPath3",
67 "kReverseAddPath",
68 };
69
70 enum RandomSetRRect {
71 kSetEmpty,
72 kSetRect,
73 kSetOval,
74 kSetRectXY,
75 kSetNinePatch,
76 kSetRectRadii,
77 };
78
79 const char* gRandomSetRRectNames[] = {
80 "kSetEmpty",
81 "kSetRect",
82 "kSetOval",
83 "kSetRectXY",
84 "kSetNinePatch",
85 "kSetRectRadii",
86 };
87
88 int kRandomSetRRect_Last = kSetRectRadii;
89
90 enum RandomSetMatrix {
91 kSetIdentity,
92 kSetTranslate,
93 kSetTranslateX,
94 kSetTranslateY,
95 kSetScale,
96 kSetScaleTranslate,
97 kSetScaleX,
98 kSetScaleY,
99 kSetSkew,
100 kSetSkewTranslate,
101 kSetSkewX,
102 kSetSkewY,
103 kSetRotate,
104 kSetRotateTranslate,
105 kSetPerspectiveX,
106 kSetPerspectiveY,
107 kSetAll,
108 };
109
110 int kRandomSetMatrix_Last = kSetAll;
111
112 const char* gRandomSetMatrixNames[] = {
113 "kSetIdentity",
114 "kSetTranslate",
115 "kSetTranslateX",
116 "kSetTranslateY",
117 "kSetScale",
118 "kSetScaleTranslate",
119 "kSetScaleX",
120 "kSetScaleY",
121 "kSetSkew",
122 "kSetSkewTranslate",
123 "kSetSkewX",
124 "kSetSkewY",
125 "kSetRotate",
126 "kSetRotateTranslate",
127 "kSetPerspectiveX",
128 "kSetPerspectiveY",
129 "kSetAll",
130 };
131
132 class FuzzPath {
133 public:
134 FuzzPath()
135 : fFloatMin(0)
136 , fFloatMax(800)
137 , fAddCount(0)
138 , fPrintName(false)
139 , fValidate(false)
140 {
141 fTab = " ";
142 }
143 void randomize() {
144 fPathDepth = 0;
145 fPathDepthLimit = fRand.nextRangeU(1, 2);
146 fPathContourCount = fRand.nextRangeU(1, 4);
147 fPathSegmentLimit = fRand.nextRangeU(1, 8);
148 fClip = makePath();
149 SkASSERT(!fPathDepth);
150 fMatrix = makeMatrix();
151 fPaint = makePaint();
152 fPathDepthLimit = fRand.nextRangeU(1, 3);
153 fPathContourCount = fRand.nextRangeU(1, 6);
154 fPathSegmentLimit = fRand.nextRangeU(1, 16);
155 fPath = makePath();
156 SkASSERT(!fPathDepth);
157 }
158
159 const SkPath& getClip() const {
160 return fClip;
161 }
162
163 const SkMatrix& getMatrix() const {
164 return fMatrix;
165 }
166
167 const SkPaint& getPaint() const {
168 return fPaint;
169 }
170
171 const SkPath& getPath() const {
172 return fPath;
173 }
174
175 private:
176
177 SkPath::AddPathMode makeAddPathMode() {
178 return (SkPath::AddPathMode) fRand.nextRangeU(SkPath::kAppend_AddPathMode,
179 SkPath::kExtend_AddPathMode);
180 }
181
182 RandomAddPath makeAddPathType() {
183 return (RandomAddPath) fRand.nextRangeU(0, kRandomAddPath_Last);
184 }
185
186 SkScalar makeAngle() {
187 SkScalar angle;
188 angle = fRand.nextF();
189 return angle;
190 }
191
192 bool makeBool() {
193 return fRand.nextBool();
194 }
195
196 SkPath::Direction makeDirection() {
197 return (SkPath::Direction) fRand.nextRangeU(SkPath::kCW_Direction, SkPath::k CCW_Direction);
198 }
199
200 SkMatrix makeMatrix() {
201 SkMatrix matrix;
202 matrix.reset();
203 RandomSetMatrix setMatrix = (RandomSetMatrix) fRand.nextRangeU(0, kRandomSet Matrix_Last);
204 if (fPrintName) {
205 SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomSetMatrixNames[setMatr ix]);
206 }
207 switch (setMatrix) {
208 case kSetIdentity:
209 break;
210 case kSetTranslateX:
211 matrix.setTranslateX(makeScalar());
212 break;
213 case kSetTranslateY:
214 matrix.setTranslateY(makeScalar());
215 break;
216 case kSetTranslate:
217 matrix.setTranslate(makeScalar(), makeScalar());
218 break;
219 case kSetScaleX:
220 matrix.setScaleX(makeScalar());
221 break;
222 case kSetScaleY:
223 matrix.setScaleY(makeScalar());
224 break;
225 case kSetScale:
226 matrix.setScale(makeScalar(), makeScalar());
227 break;
228 case kSetScaleTranslate:
229 matrix.setScale(makeScalar(), makeScalar(), makeScalar(), makeScalar ());
230 break;
231 case kSetSkewX:
232 matrix.setSkewX(makeScalar());
233 break;
234 case kSetSkewY:
235 matrix.setSkewY(makeScalar());
236 break;
237 case kSetSkew:
238 matrix.setSkew(makeScalar(), makeScalar());
239 break;
240 case kSetSkewTranslate:
241 matrix.setSkew(makeScalar(), makeScalar(), makeScalar(), makeScalar( ));
242 break;
243 case kSetRotate:
244 matrix.setRotate(makeScalar());
245 break;
246 case kSetRotateTranslate:
247 matrix.setRotate(makeScalar(), makeScalar(), makeScalar());
248 break;
249 case kSetPerspectiveX:
250 matrix.setPerspX(makeScalar());
251 break;
252 case kSetPerspectiveY:
253 matrix.setPerspY(makeScalar());
254 break;
255 case kSetAll:
256 matrix.setAll(makeScalar(), makeScalar(), makeScalar(),
257 makeScalar(), makeScalar(), makeScalar(),
258 makeScalar(), makeScalar(), makeScalar());
259 break;
260 }
261 return matrix;
262 }
263
264 SkPaint makePaint() {
265 SkPaint paint;
266 bool antiAlias = fRand.nextBool();
267 paint.setAntiAlias(antiAlias);
268 SkPaint::Style style = (SkPaint::Style) fRand.nextRangeU(SkPaint::kFill_Styl e,
269 SkPaint::kStrokeAndFill_Style);
270 paint.setStyle(style);
271 SkColor color = (SkColor) fRand.nextU();
272 paint.setColor(color);
273 SkScalar width = fRand.nextF();
274 paint.setStrokeWidth(width);
275 SkScalar miter = fRand.nextF();
276 paint.setStrokeMiter(miter);
277 SkPaint::Cap cap = (SkPaint::Cap) fRand.nextRangeU(SkPaint::kButt_Cap, SkPai nt::kSquare_Cap);
278 paint.setStrokeCap(cap);
279 SkPaint::Join join = (SkPaint::Join) fRand.nextRangeU(SkPaint::kMiter_Join,
280 SkPaint::kBevel_Join);
281 paint.setStrokeJoin(join);
282 return paint;
283 }
284
285 SkPoint makePoint() {
286 SkPoint result;
287 makeScalarArray(2, &result.fX);
288 return result;
289 }
290
291 void makePointArray(size_t arrayCount, SkPoint* points) {
292 for (size_t index = 0; index < arrayCount; ++index) {
293 points[index] = makePoint();
294 }
295 }
296
297 void makePointArray(SkTDArray<SkPoint>* points) {
298 size_t arrayCount = fRand.nextRangeU(1, 10);
299 for (size_t index = 0; index < arrayCount; ++index) {
300 *points->append() = makePoint();
301 }
302 }
303
304 SkRect makeRect() {
305 SkRect result;
306 makeScalarArray(4, &result.fLeft);
307 return result;
308 }
309
310 SkRRect makeRRect() {
311 SkRRect rrect;
312 RandomSetRRect rrectType = makeSetRRectType();
313 if (fPrintName) {
314 SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomSetRRectNames[rrectTyp e]);
315 }
316 switch (rrectType) {
317 case kSetEmpty:
318 rrect.setEmpty();
319 break;
320 case kSetRect: {
321 SkRect rect = makeRect();
322 rrect.setRect(rect);
323 } break;
324 case kSetOval: {
325 SkRect oval = makeRect();
326 rrect.setOval(oval);
327 } break;
328 case kSetRectXY: {
329 SkRect rect = makeRect();
330 SkScalar xRad = makeScalar();
331 SkScalar yRad = makeScalar();
332 rrect.setRectXY(rect, xRad, yRad);
333 } break;
334 case kSetNinePatch: {
335 SkRect rect = makeRect();
336 SkScalar leftRad = makeScalar();
337 SkScalar topRad = makeScalar();
338 SkScalar rightRad = makeScalar();
339 SkScalar bottomRad = makeScalar();
340 rrect.setNinePatch(rect, leftRad, topRad, rightRad, bottomRad);
341 SkDebugf(""); // keep locals in scope
342 } break;
343 case kSetRectRadii: {
344 SkRect rect = makeRect();
345 SkVector radii[4];
346 makeVectorArray(SK_ARRAY_COUNT(radii), radii);
347 rrect.setRectRadii(rect, radii);
348 } break;
349 }
350 return rrect;
351 }
352
353 SkPath makePath() {
354 SkPath path;
355 for (uint32_t cIndex = 0; cIndex < fPathContourCount; ++cIndex) {
356 uint32_t segments = makeSegmentCount();
357 for (uint32_t sIndex = 0; sIndex < segments; ++sIndex) {
358 RandomAddPath addPathType = makeAddPathType();
359 ++fAddCount;
360 if (fPrintName) {
361 SkDebugf("%.*s%s\n", fPathDepth * 3, fTab,
362 gRandomAddPathNames[addPathType]);
363 }
364 switch (addPathType) {
365 case kAddArc: {
366 SkRect oval = makeRect();
367 SkScalar startAngle = makeAngle();
368 SkScalar sweepAngle = makeAngle();
369 path.addArc(oval, startAngle, sweepAngle);
370 validate(path);
371 } break;
372 case kAddRoundRect1: {
373 SkRect rect = makeRect();
374 SkScalar rx = makeScalar(), ry = makeScalar();
375 SkPath::Direction dir = makeDirection();
376 path.addRoundRect(rect, rx, ry, dir);
377 validate(path);
378 } break;
379 case kAddRoundRect2: {
380 SkRect rect = makeRect();
381 SkScalar radii[8];
382 makeScalarArray(SK_ARRAY_COUNT(radii), radii);
383 SkPath::Direction dir = makeDirection();
384 path.addRoundRect(rect, radii, dir);
385 validate(path);
386 } break;
387 case kAddRRect: {
388 SkRRect rrect = makeRRect();
389 SkPath::Direction dir = makeDirection();
390 path.addRRect(rrect, dir);
391 validate(path);
392 } break;
393 case kAddPoly: {
394 SkTDArray<SkPoint> points;
395 makePointArray(&points);
396 bool close = makeBool();
397 path.addPoly(&points[0], points.count(), close);
398 validate(path);
399 } break;
400 case kAddPath1:
401 if (fPathDepth < fPathDepthLimit) {
402 ++fPathDepth;
403 SkPath src = makePath();
404 validate(src);
405 SkScalar dx = makeScalar();
406 SkScalar dy = makeScalar();
407 SkPath::AddPathMode mode = makeAddPathMode();
408 path.addPath(src, dx, dy, mode);
409 --fPathDepth;
410 validate(path);
411 }
412 break;
413 case kAddPath2:
414 if (fPathDepth < fPathDepthLimit) {
415 ++fPathDepth;
416 SkPath src = makePath();
417 validate(src);
418 SkPath::AddPathMode mode = makeAddPathMode();
419 path.addPath(src, mode);
420 --fPathDepth;
421 validate(path);
422 }
423 break;
424 case kAddPath3:
425 if (fPathDepth < fPathDepthLimit) {
426 ++fPathDepth;
427 SkPath src = makePath();
428 validate(src);
429 SkMatrix matrix = makeMatrix();
430 SkPath::AddPathMode mode = makeAddPathMode();
431 path.addPath(src, matrix, mode);
432 --fPathDepth;
433 validate(path);
434 }
435 break;
436 case kReverseAddPath:
437 if (fPathDepth < fPathDepthLimit) {
438 ++fPathDepth;
439 SkPath src = makePath();
440 validate(src);
441 path.reverseAddPath(src);
442 --fPathDepth;
443 validate(path);
444 }
445 break;
446 case kMoveToPath: {
447 SkScalar x = makeScalar();
448 SkScalar y = makeScalar();
449 path.moveTo(x, y);
450 validate(path);
451 } break;
452 case kRMoveToPath: {
453 SkScalar x = makeScalar();
454 SkScalar y = makeScalar();
455 path.rMoveTo(x, y);
456 validate(path);
457 } break;
458 case kLineToPath: {
459 SkScalar x = makeScalar();
460 SkScalar y = makeScalar();
461 path.lineTo(x, y);
462 validate(path);
463 } break;
464 case kRLineToPath: {
465 SkScalar x = makeScalar();
466 SkScalar y = makeScalar();
467 path.rLineTo(x, y);
468 validate(path);
469 } break;
470 case kQuadToPath: {
471 SkPoint pt[2];
472 makePointArray(SK_ARRAY_COUNT(pt), pt);
473 path.quadTo(pt[0], pt[1]);
474 validate(path);
475 } break;
476 case kRQuadToPath: {
477 SkPoint pt[2];
478 makePointArray(SK_ARRAY_COUNT(pt), pt);
479 path.rQuadTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY);
480 validate(path);
481 } break;
482 case kConicToPath: {
483 SkPoint pt[2];
484 makePointArray(SK_ARRAY_COUNT(pt), pt);
485 SkScalar weight = makeScalar();
486 path.conicTo(pt[0], pt[1], weight);
487 validate(path);
488 } break;
489 case kRConicToPath: {
490 SkPoint pt[2];
491 makePointArray(SK_ARRAY_COUNT(pt), pt);
492 SkScalar weight = makeScalar();
493 path.rConicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, weight );
494 validate(path);
495 } break;
496 case kCubicToPath: {
497 SkPoint pt[3];
498 makePointArray(SK_ARRAY_COUNT(pt), pt);
499 path.cubicTo(pt[0], pt[1], pt[2]);
500 validate(path);
501 } break;
502 case kRCubicToPath: {
503 SkPoint pt[3];
504 makePointArray(SK_ARRAY_COUNT(pt), pt);
505 path.rCubicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, pt[2]. fX, pt[2].fY);
506 validate(path);
507 } break;
508 case kArcToPath: {
509 SkPoint pt[2];
510 makePointArray(SK_ARRAY_COUNT(pt), pt);
511 SkScalar radius = makeScalar();
512 path.arcTo(pt[0], pt[1], radius);
513 validate(path);
514 } break;
515 case kArcTo2Path: {
516 SkRect oval = makeRect();
517 SkScalar startAngle = makeAngle();
518 SkScalar sweepAngle = makeAngle();
519 bool forceMoveTo = makeBool();
520 path.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
521 validate(path);
522 } break;
523 case kClosePath:
524 path.close();
525 validate(path);
526 break;
527 }
528 }
529 }
530 return path;
531 }
532
533 uint32_t makeSegmentCount() {
534 return fRand.nextRangeU(1, fPathSegmentLimit);
535 }
536
537 RandomSetRRect makeSetRRectType() {
538 return (RandomSetRRect) fRand.nextRangeU(0, kRandomSetRRect_Last);
539 }
540
541 SkScalar makeScalar() {
542 SkScalar scalar;
543 scalar = fRand.nextRangeF(fFloatMin, fFloatMax);
544 return scalar;
545 }
546
547 void makeScalarArray(size_t arrayCount, SkScalar* array) {
548 for (size_t index = 0; index < arrayCount; ++index) {
549 array[index] = makeScalar();
550 }
551 }
552
553 void makeVectorArray(size_t arrayCount, SkVector* array) {
554 for (size_t index = 0; index < arrayCount; ++index) {
555 array[index] = makeVector();
556 }
557 }
558
559 SkVector makeVector() {
560 SkVector result;
561 makeScalarArray(2, &result.fX);
562 return result;
563 }
564
565 void validate(const SkPath& path) {
566 if (fValidate) {
567 SkDEBUGCODE(path.experimentalValidateRef());
568 }
569 }
570
571 SkRandom fRand;
572 SkMatrix fMatrix;
573 SkPath fClip;
574 SkPaint fPaint;
575 SkPath fPath;
576 SkScalar fFloatMin;
577 SkScalar fFloatMax;
578 uint32_t fPathContourCount;
579 int fPathDepth;
580 int fPathDepthLimit;
581 uint32_t fPathSegmentLimit;
582 int fAddCount;
583 bool fPrintName;
584 bool fValidate;
585 const char* fTab;
586 };
587
588 //////////////////////////////////////////////////////////////////////////////
589 static bool contains_only_moveTo(const SkPath& path) {
590 int verbCount = path.countVerbs();
591 if (verbCount == 0) {
592 return true;
593 }
594 SkTDArray<uint8_t> verbs;
595 verbs.setCount(verbCount);
596 SkDEBUGCODE(int getVerbResult = ) path.getVerbs(verbs.begin(), verbCount);
597 SkASSERT(getVerbResult == verbCount);
598 for (int index = 0; index < verbCount; ++index) {
599 if (verbs[index] != SkPath::kMove_Verb) {
600 return false;
601 }
602 }
603 return true;
604 }
605
606 class PathFuzzView : public SampleView {
607 public:
608 PathFuzzView() {
609 fDots = 0;
610 }
611 protected:
612 // overrides from SkEventSink
613 virtual bool onQuery(SkEvent* evt) {
614 if (SampleCode::TitleQ(*evt)) {
615 SampleCode::TitleR(evt, "PathFuzzer");
616 return true;
617 }
618 return this->INHERITED::onQuery(evt);
619 }
620
621 virtual void onDrawContent(SkCanvas* canvas) {
622 fuzzPath.randomize();
623 const SkPath& path = fuzzPath.getPath();
624 const SkPaint& paint = fuzzPath.getPaint();
625 const SkPath& clip = fuzzPath.getClip();
626 const SkMatrix& matrix = fuzzPath.getMatrix();
627 if (!contains_only_moveTo(clip)) {
628 canvas->clipPath(clip);
629 }
630 canvas->setMatrix(matrix);
631 canvas->drawPath(path, paint);
632 this->inval(NULL);
633 if (++fDots == 8000) {
634 SkDebugf("\n");
635 fDots = 0;
636 }
637 if ((fDots % 100) == 99) {
638 SkDebugf(".");
639 }
640 }
641
642 private:
643 FuzzPath fuzzPath;
644 int fDots;
645 typedef SkView INHERITED;
646 };
647
648 //////////////////////////////////////////////////////////////////////////////
649
650 static SkView* MyFactory() { return new PathFuzzView; }
651 static SkViewRegister reg(MyFactory);
OLDNEW
« no previous file with comments | « samplecode/SamplePathEffects.cpp ('k') | samplecode/SampleStrokePath.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698