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 19 static 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 29 static SkRandom gRand; 30 static bool return_large; 31 static bool return_undef; 32 static bool quick; 33 static bool scale_large; 34 static int scval = 1; 35 static float transval = 0; 36 37 static 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 48 static 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 58 static 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 94 static SkColor make_color() { 95 if (R(2) == 1) return 0xFFC0F0A0; else return 0xFF000090; 96 } 97 98 99 static 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 140 static 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 364 class FuzzView : public SampleView { 365 public: 366 FuzzView() { 367 this->setBGColor(0xFFDDDDDD); 368 } 369 370 protected: 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(nullptr); 387 } 388 389 private: 390 typedef SkView INHERITED; 391 }; 392 393 ////////////////////////////////////////////////////////////////////////////// 394 395 static SkView* MyFactory() { return new FuzzView; } 396 static SkViewRegister reg(MyFactory); 397