FuzzGradients.cpp revision 2f535cecd0e5a19a3dfb76649b1d90c7e158e24c
1/* 2 * Copyright 2016 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 "Fuzz.h" 9#include "SkCanvas.h" 10#include "SkGradientShader.h" 11#include "SkSurface.h" 12#include "SkTLazy.h" 13 14#include <algorithm> 15#include <vector> 16 17const int MAX_COUNT = 400; 18 19void makeMatrix(Fuzz* fuzz, SkMatrix* m) { 20 m->setAll(fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), 21 fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), 22 fuzz->next<SkScalar>(), fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); 23} 24 25void initGradientParams(Fuzz* fuzz, std::vector<SkColor>* colors, 26 std::vector<SkScalar>* pos, SkShader::TileMode* mode) { 27 int count = fuzz->nextRange(0, MAX_COUNT); 28 29 *mode = static_cast<SkShader::TileMode>(fuzz->nextRange(0, 2)); 30 31 colors->clear(); 32 pos ->clear(); 33 for (int i = 0; i < count; i++) { 34 colors->push_back(fuzz->next<SkColor>()); 35 pos ->push_back(fuzz->next<SkScalar>()); 36 } 37 if (count) { 38 std::sort(pos->begin(), pos->end()); 39 // The order matters. If count == 1, we want pos == 0. 40 (*pos)[count - 1] = 1; 41 (*pos)[0] = 0; 42 } 43} 44 45void fuzzLinearGradient(Fuzz* fuzz) { 46 SkPoint pts[2] = {SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()), 47 SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>())}; 48 bool useLocalMatrix = fuzz->next<bool>(); 49 bool useGlobalMatrix = fuzz->next<bool>(); 50 51 std::vector<SkColor> colors; 52 std::vector<SkScalar> pos; 53 SkShader::TileMode mode; 54 initGradientParams(fuzz, &colors, &pos, &mode); 55 56 SkPaint p; 57 uint32_t flags = fuzz->next<uint32_t>(); 58 59 SkTLazy<SkMatrix> localMatrix; 60 if (useLocalMatrix) { 61 makeMatrix(fuzz, localMatrix.init()); 62 } 63 p.setShader(SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), 64 colors.size(), mode, flags, localMatrix.getMaybeNull())); 65 66 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); 67 if (useGlobalMatrix) { 68 SkMatrix gm; 69 makeMatrix(fuzz, &gm); 70 SkCanvas* c = surface->getCanvas(); 71 c->setMatrix(gm); 72 c->drawPaint(p); 73 } else { 74 surface->getCanvas()->drawPaint(p); 75 } 76} 77 78void fuzzRadialGradient(Fuzz* fuzz) { 79 SkPoint center = SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); 80 SkScalar radius = fuzz->next<SkScalar>(); 81 bool useLocalMatrix = fuzz->next<bool>(); 82 bool useGlobalMatrix = fuzz->next<bool>(); 83 84 85 std::vector<SkColor> colors; 86 std::vector<SkScalar> pos; 87 SkShader::TileMode mode; 88 initGradientParams(fuzz, &colors, &pos, &mode); 89 90 SkPaint p; 91 uint32_t flags = fuzz->next<uint32_t>(); 92 93 SkTLazy<SkMatrix> localMatrix; 94 if (useLocalMatrix) { 95 makeMatrix(fuzz, localMatrix.init()); 96 } 97 p.setShader(SkGradientShader::MakeRadial(center, radius, colors.data(), 98 pos.data(), colors.size(), mode, flags, localMatrix.getMaybeNull())); 99 100 101 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); 102 if (useGlobalMatrix) { 103 SkMatrix gm; 104 makeMatrix(fuzz, &gm); 105 SkCanvas* c = surface->getCanvas(); 106 c->setMatrix(gm); 107 c->drawPaint(p); 108 } else { 109 surface->getCanvas()->drawPaint(p); 110 } 111} 112 113void fuzzTwoPointConicalGradient(Fuzz* fuzz) { 114 SkPoint start = SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); 115 SkPoint end = SkPoint::Make(fuzz->next<SkScalar>(), fuzz->next<SkScalar>()); 116 SkScalar startRadius = fuzz->next<SkScalar>(); 117 SkScalar endRadius = fuzz->next<SkScalar>(); 118 bool useLocalMatrix = fuzz->next<bool>(); 119 bool useGlobalMatrix = fuzz->next<bool>(); 120 121 std::vector<SkColor> colors; 122 std::vector<SkScalar> pos; 123 SkShader::TileMode mode; 124 initGradientParams(fuzz, &colors, &pos, &mode); 125 126 SkPaint p; 127 uint32_t flags = fuzz->next<uint32_t>(); 128 129 SkTLazy<SkMatrix> localMatrix; 130 if (useLocalMatrix) { 131 makeMatrix(fuzz, localMatrix.init()); 132 } 133 p.setShader(SkGradientShader::MakeTwoPointConical(start, startRadius, 134 end, endRadius, colors.data(), pos.data(), colors.size(), mode, 135 flags, localMatrix.getMaybeNull())); 136 137 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); 138 if (useGlobalMatrix) { 139 SkMatrix gm; 140 makeMatrix(fuzz, &gm); 141 SkCanvas* c = surface->getCanvas(); 142 c->setMatrix(gm); 143 c->drawPaint(p); 144 } else { 145 surface->getCanvas()->drawPaint(p); 146 } 147} 148 149void fuzzSweepGradient(Fuzz* fuzz) { 150 SkScalar cx = fuzz->next<SkScalar>(); 151 SkScalar cy = fuzz->next<SkScalar>(); 152 bool useLocalMatrix = fuzz->next<bool>(); 153 bool useGlobalMatrix = fuzz->next<bool>(); 154 155 std::vector<SkColor> colors; 156 std::vector<SkScalar> pos; 157 SkShader::TileMode mode; 158 initGradientParams(fuzz, &colors, &pos, &mode); 159 160 SkPaint p; 161 if (useLocalMatrix) { 162 SkMatrix m; 163 makeMatrix(fuzz, &m); 164 uint32_t flags = fuzz->next<uint32_t>(); 165 166 p.setShader(SkGradientShader::MakeSweep(cx, cy, colors.data(), 167 pos.data(), colors.size(), flags, &m)); 168 } else { 169 p.setShader(SkGradientShader::MakeSweep(cx, cy, colors.data(), 170 pos.data(), colors.size())); 171 } 172 173 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(50, 50)); 174 if (useGlobalMatrix) { 175 SkMatrix gm; 176 makeMatrix(fuzz, &gm); 177 SkCanvas* c = surface->getCanvas(); 178 c->setMatrix(gm); 179 c->drawPaint(p); 180 } else { 181 surface->getCanvas()->drawPaint(p); 182 } 183} 184 185DEF_FUZZ(Gradients, fuzz) { 186 uint8_t i = fuzz->next<uint8_t>(); 187 188 switch(i) { 189 case 0: 190 SkDebugf("LinearGradient\n"); 191 fuzzLinearGradient(fuzz); 192 return; 193 case 1: 194 SkDebugf("RadialGradient\n"); 195 fuzzRadialGradient(fuzz); 196 return; 197 case 2: 198 SkDebugf("TwoPointConicalGradient\n"); 199 fuzzTwoPointConicalGradient(fuzz); 200 return; 201 } 202 SkDebugf("SweepGradient\n"); 203 fuzzSweepGradient(fuzz); 204 return; 205} 206