1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SampleCode.h"
9#include "SkView.h"
10#include "SkCanvas.h"
11#include "SkBlurMaskFilter.h"
12#include "SkPaint.h"
13#include "SkPath.h"
14#include "SkXfermode.h"
15#include "SkMatrix.h"
16#include "SkColor.h"
17#include "SkRandom.h"
18
19static void set2x3(SkMatrix* m, float a, float b, float c, float d, float e, float f) {
20    m->reset();
21    m->set(0, a);
22    m->set(1, b);
23    m->set(2, c);
24    m->set(3, d);
25    m->set(4, e);
26    m->set(5, f);
27}
28
29static SkRandom gRand;
30static bool return_large;
31static bool return_undef;
32static bool quick;
33static bool scale_large;
34static int scval = 1;
35static float transval = 0;
36
37static int R(float x) {
38  return (int)floor(SkScalarToFloat(gRand.nextUScalar1()) * x);
39}
40
41#if defined _WIN32
42#pragma warning ( push )
43// we are intentionally causing an overflow here
44//      (warning C4756: overflow in constant arithmetic)
45#pragma warning ( disable : 4756 )
46#endif
47
48static float huge() {
49    double d = 1e100;
50    float f = (float)d;
51    return f;
52}
53
54#if defined _WIN32
55#pragma warning ( pop )
56#endif
57
58static float make_number() {
59  float v = 0;
60  int sel;
61
62  if (return_large == true && R(3) == 1) {
63      sel = R(6);
64  } else {
65      sel = R(4);
66  }
67
68  if (return_undef == false && sel == 0) {
69      sel = 1;
70  }
71
72  if (R(2) == 1) {
73      v = (float)R(100);
74  } else {
75
76      switch (sel) {
77        case 0: break;
78        case 1: v = 0; break;
79        case 2: v = 0.000001f; break;
80        case 3: v = 10000; break;
81        case 4: v = 2000000000; break;
82        case 5: v = huge(); break;
83      }
84
85  }
86
87  if (R(4) == 1) {
88      v = -v;
89  }
90
91  return v;
92}
93
94static SkColor make_color() {
95  if (R(2) == 1) return 0xFFC0F0A0; else return 0xFF000090;
96}
97
98
99static SkColor make_fill() {
100#if 0
101  int sel;
102
103  if (quick == true) sel = 0; else sel = R(6);
104
105  switch (sel) {
106
107    case 0:
108    case 1:
109    case 2:
110      return make_color();
111      break;
112
113    case 3:
114      var r = ctx.createLinearGradient(make_number(),make_number(),make_number(),make_number());
115      for (i=0;i<4;i++)
116        r.addColorStop(make_number(),make_color());
117      return r;
118      break;
119
120    case 4:
121      var r = ctx.createRadialGradient(make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
122      for (i=0;i<4;i++)
123        r.addColorStop(make_number(),make_color());
124      return r;
125      break;
126
127    case 5:
128      var r = ctx.createPattern(imgObj,"repeat");
129      if (R(6) == 0)
130        r.addColorStop(make_number(),make_color());
131      return r;
132      break;
133  }
134#else
135    return make_color();
136#endif
137}
138
139
140static void do_fuzz(SkCanvas* canvas) {
141    SkPath path;
142    SkPaint paint;
143    paint.setAntiAlias(true);
144
145  for (int i=0;i<100;i++) {
146  switch (R(33)) {
147
148    case 0:
149          paint.setColor(make_fill());
150      break;
151
152    case 1:
153      paint.setAlpha(gRand.nextU() & 0xFF);
154      break;
155
156      case 2: {
157          SkXfermode::Mode mode;
158          switch (R(3)) {
159            case 0: mode = SkXfermode::kSrc_Mode; break;
160            case 1: mode = SkXfermode::kXor_Mode; break;
161            case 2:
162            default:  // silence warning
163              mode = SkXfermode::kSrcOver_Mode; break;
164          }
165          paint.setXfermodeMode(mode);
166      }
167      break;
168
169    case 3:
170      switch (R(2)) {
171          case 0: paint.setStrokeCap(SkPaint::kRound_Cap); break;
172        case 1: paint.setStrokeCap(SkPaint::kButt_Cap); break;
173      }
174      break;
175
176    case 4:
177      switch (R(2)) {
178          case 0: paint.setStrokeJoin(SkPaint::kRound_Join); break;
179        case 1: paint.setStrokeJoin(SkPaint::kMiter_Join); break;
180      }
181      break;
182
183    case 5:
184      paint.setStrokeWidth(make_number());
185      break;
186
187    case 6:
188      paint.setStrokeMiter(make_number());
189      break;
190
191    case 7:
192      if (quick == true) break;
193          SkSafeUnref(paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
194                                                                   make_number())));
195      break;
196
197    case 8:
198      if (quick == true) break;
199      //ctx.shadowColor = make_fill();
200      break;
201
202    case 9:
203      if (quick == true) break;
204      //ctx.shadowOffsetX = make_number();
205      //ctx.shadowOffsetY = make_number();
206      break;
207
208    case 10:
209      canvas->restore();
210      break;
211
212    case 11:
213      canvas->rotate(make_number());
214      break;
215
216    case 12:
217      canvas->save();
218      break;
219
220    case 13:
221      canvas->scale(-1,-1);
222      break;
223
224    case 14:
225
226      if (quick == true) break;
227
228      if (transval == 0) {
229        transval = make_number();
230        canvas->translate(transval,0);
231      } else {
232        canvas->translate(-transval,0);
233        transval = 0;
234      }
235
236      break;
237
238          case 15: {
239              SkRect r;
240              r.set(make_number(),make_number(),make_number(),make_number());
241              SkPaint::Style s = paint.getStyle();
242              paint.setStyle(SkPaint::kFill_Style);
243              canvas->drawRect(r, paint);
244              paint.setStyle(s);
245              // clearrect
246          } break;
247
248    case 16:
249      if (quick == true) break;
250//      ctx.drawImage(imgObj,make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
251      break;
252
253          case 17: {
254          SkRect r;
255          r.set(make_number(),make_number(),make_number(),make_number());
256              SkPaint::Style s = paint.getStyle();
257              paint.setStyle(SkPaint::kFill_Style);
258          canvas->drawRect(r, paint);
259              paint.setStyle(s);
260          } break;
261
262    case 18:
263          path.reset();
264      break;
265
266    case 19:
267      // ctx.clip() is evil.
268      break;
269
270    case 20:
271          path.close();
272      break;
273
274          case 21: {
275          SkPaint::Style s = paint.getStyle();
276          paint.setStyle(SkPaint::kFill_Style);
277          canvas->drawPath(path, paint);
278          paint.setStyle(s);
279          } break;
280
281          case 22: {
282              SkPaint::Style s = paint.getStyle();
283              paint.setStyle(SkPaint::kFill_Style);
284              canvas->drawPath(path, paint);
285              paint.setStyle(s);
286          } break;
287
288          case 23: {
289              SkRect r;
290              r.set(make_number(),make_number(),make_number(),make_number());
291              SkPaint::Style s = paint.getStyle();
292              paint.setStyle(SkPaint::kStroke_Style);
293              canvas->drawRect(r, paint);
294              paint.setStyle(s);
295          } break;
296
297    case 24:
298      if (quick == true) break;
299      //ctx.arc(make_number(),make_number(),make_number(),make_number(),make_number(),true);
300      break;
301
302    case 25:
303      if (quick == true) break;
304      //ctx.arcTo(make_number(),make_number(),make_number(),make_number(),make_number());
305      break;
306
307    case 26:
308      if (quick == true) break;
309      //ctx.bezierCurveTo(make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
310      break;
311
312    case 27:
313      path.lineTo(make_number(),make_number());
314      break;
315
316    case 28:
317      path.moveTo(make_number(),make_number());
318      break;
319
320    case 29:
321      if (quick == true) break;
322      path.quadTo(make_number(),make_number(),make_number(),make_number());
323      break;
324
325          case 30: {
326      if (quick == true) break;
327              SkMatrix matrix;
328      set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
329              canvas->concat(matrix);
330          } break;
331
332          case 31: {
333      if (quick == true) break;
334          SkMatrix matrix;
335          set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
336          canvas->setMatrix(matrix);
337          } break;
338
339    case 32:
340
341      if (scale_large == true) {
342
343        switch (scval) {
344          case 0: canvas->scale(-1000000000,1);
345                  canvas->scale(-1000000000,1);
346                  scval = 1; break;
347          case 1: canvas->scale(-.000000001f,1); scval = 2; break;
348          case 2: canvas->scale(-.000000001f,1); scval = 0; break;
349        }
350
351      }
352
353      break;
354
355
356
357  }
358  }
359
360}
361
362//////////////////////////////////////////////////////////////////////////////
363
364class FuzzView : public SampleView {
365public:
366    FuzzView() {
367        this->setBGColor(0xFFDDDDDD);
368    }
369
370protected:
371    // overrides from SkEventSink
372    virtual bool onQuery(SkEvent* evt) {
373        if (SampleCode::TitleQ(*evt)) {
374            SampleCode::TitleR(evt, "Fuzzer");
375            return true;
376        }
377        return this->INHERITED::onQuery(evt);
378    }
379
380    void drawBG(SkCanvas* canvas) {
381        canvas->drawColor(0xFFDDDDDD);
382    }
383
384    virtual void onDrawContent(SkCanvas* canvas) {
385        do_fuzz(canvas);
386        this->inval(NULL);
387    }
388
389private:
390    typedef SkView INHERITED;
391};
392
393//////////////////////////////////////////////////////////////////////////////
394
395static SkView* MyFactory() { return new FuzzView; }
396static SkViewRegister reg(MyFactory);
397