124ac42b373d9202a89538a1873df9275870c7632Hal Canary/*
224ac42b373d9202a89538a1873df9275870c7632Hal Canary * Copyright 2017 Google Inc.
324ac42b373d9202a89538a1873df9275870c7632Hal Canary *
424ac42b373d9202a89538a1873df9275870c7632Hal Canary * Use of this source code is governed by a BSD-style license that can be
524ac42b373d9202a89538a1873df9275870c7632Hal Canary * found in the LICENSE file.
624ac42b373d9202a89538a1873df9275870c7632Hal Canary */
724ac42b373d9202a89538a1873df9275870c7632Hal Canary
824ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "Fuzz.h"
924ac42b373d9202a89538a1873df9275870c7632Hal Canary
1024ac42b373d9202a89538a1873df9275870c7632Hal Canary// CORE
1124ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkCanvas.h"
1224ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkColorFilter.h"
131ac8fd25381a043681a24dc3171189db535c587dKevin Lubick#include "SkDebugCanvas.h"
141ac8fd25381a043681a24dc3171189db535c587dKevin Lubick#include "SkDocument.h"
15671e442fccaacf57b6922324e8160173a2919608Hal Canary#include "SkFontMgr.h"
1624ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkImageFilter.h"
1724ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkMaskFilter.h"
181ac8fd25381a043681a24dc3171189db535c587dKevin Lubick#include "SkNullCanvas.h"
1924ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkPathEffect.h"
2024ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkPictureRecorder.h"
215395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "SkRSXform.h"
2224ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkRegion.h"
231ac8fd25381a043681a24dc3171189db535c587dKevin Lubick#include "SkSurface.h"
2424ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkTypeface.h"
2524ac42b373d9202a89538a1873df9275870c7632Hal Canary
2624ac42b373d9202a89538a1873df9275870c7632Hal Canary// EFFECTS
275395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "Sk1DPathEffect.h"
285395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "Sk2DPathEffect.h"
29e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkAlphaThresholdFilter.h"
305395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "SkArcToPathEffect.h"
31e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkArithmeticImageFilter.h"
325395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "SkBlurMaskFilter.h"
33e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkColorFilterImageFilter.h"
3427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary#include "SkColorMatrixFilter.h"
35e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkComposeImageFilter.h"
365395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "SkCornerPathEffect.h"
375395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "SkDashPathEffect.h"
385395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "SkDiscretePathEffect.h"
39e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkDisplacementMapEffect.h"
40e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkDropShadowImageFilter.h"
4124ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkGaussianEdgeShader.h"
4224ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkGradientShader.h"
4327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary#include "SkHighContrastFilter.h"
44e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkImageSource.h"
45e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkLightingImageFilter.h"
4627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary#include "SkLumaColorFilter.h"
47e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkMagnifierImageFilter.h"
48e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkMatrixConvolutionImageFilter.h"
49e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkMergeImageFilter.h"
50e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkMorphologyImageFilter.h"
51e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkOffsetImageFilter.h"
52e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkPaintImageFilter.h"
5324ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkPerlinNoiseShader.h"
54e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkPictureImageFilter.h"
555395c598dbc3fc85b45a18752867aea65643f147Hal Canary#include "SkRRectsGaussianEdgeMaskFilter.h"
5627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary#include "SkTableColorFilter.h"
57e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkTileImageFilter.h"
58e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary#include "SkXfermodeImageFilter.h"
5924ac42b373d9202a89538a1873df9275870c7632Hal Canary
6024ac42b373d9202a89538a1873df9275870c7632Hal Canary// SRC
6124ac42b373d9202a89538a1873df9275870c7632Hal Canary#include "SkUtils.h"
6224ac42b373d9202a89538a1873df9275870c7632Hal Canary
6344801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary#if SK_SUPPORT_GPU
6444801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary#include "GrContextFactory.h"
6544801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary#endif
6644801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary
671ac8fd25381a043681a24dc3171189db535c587dKevin Lubick// MISC
681ac8fd25381a043681a24dc3171189db535c587dKevin Lubick
691ac8fd25381a043681a24dc3171189db535c587dKevin Lubick#include <iostream>
701ac8fd25381a043681a24dc3171189db535c587dKevin Lubick
7124ac42b373d9202a89538a1873df9275870c7632Hal Canary// TODO:
725395c598dbc3fc85b45a18752867aea65643f147Hal Canary//   SkTextBlob with Unicode
7344801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary//   SkImage: more types
7424ac42b373d9202a89538a1873df9275870c7632Hal Canary
75f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canarytemplate <typename T, typename Min, typename Max>
76f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canaryinline void fuzz_enum_range(Fuzz* fuzz, T* value, Min rmin, Max rmax) {
7724ac42b373d9202a89538a1873df9275870c7632Hal Canary    using U = skstd::underlying_type_t<T>;
78f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary    fuzz->nextRange((U*)value, (U)rmin, (U)rmax);
79f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary}
80f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary
811e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary// be careful: `foo(make_fuzz_t<T>(f), make_fuzz_t<U>(f))` is undefined.
821e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary// In fact, all make_fuzz_foo() functions have this potential problem.
831e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary// Use sequence points!
841e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarytemplate <typename T>
851e0138b58287c086a3085cd2b4640c713d5c9653Hal Canaryinline T make_fuzz_t(Fuzz* fuzz) {
861e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    T t;
871e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    fuzz->next(&t);
881e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    return t;
8924ac42b373d9202a89538a1873df9275870c7632Hal Canary}
9024ac42b373d9202a89538a1873df9275870c7632Hal Canary
911e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary// We don't always want to test NaNs and infinities.
92ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canarystatic void fuzz_nice_float(Fuzz* fuzz, float* f) {
931e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    float v;
941e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    fuzz->next(&v);
951e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    constexpr float kLimit = 1.0e35f;  // FLT_MAX?
961e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    *f = (v == v && v <= kLimit && v >= -kLimit) ? v : 0.0f;
97ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary}
9824ac42b373d9202a89538a1873df9275870c7632Hal Canary
99ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canarytemplate <typename... Args>
1001e0138b58287c086a3085cd2b4640c713d5c9653Hal Canaryinline void fuzz_nice_float(Fuzz* fuzz, float* f, Args... rest) {
101ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary    fuzz_nice_float(fuzz, f);
102ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary    fuzz_nice_float(fuzz, rest...);
103ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary}
104ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary
105ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canarystatic void fuzz_path(Fuzz* fuzz, SkPath* path, int maxOps) {
106ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary    if (maxOps < 2) {
107ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary        maxOps = 2;
108ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary    }
10924ac42b373d9202a89538a1873df9275870c7632Hal Canary    uint8_t fillType;
11024ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz->nextRange(&fillType, 0, (uint8_t)SkPath::kInverseEvenOdd_FillType);
11124ac42b373d9202a89538a1873df9275870c7632Hal Canary    path->setFillType((SkPath::FillType)fillType);
11224ac42b373d9202a89538a1873df9275870c7632Hal Canary    uint8_t numOps;
113ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary    fuzz->nextRange(&numOps, 2, maxOps);
11424ac42b373d9202a89538a1873df9275870c7632Hal Canary    for (uint8_t i = 0; i < numOps; ++i) {
11524ac42b373d9202a89538a1873df9275870c7632Hal Canary        uint8_t op;
11624ac42b373d9202a89538a1873df9275870c7632Hal Canary        fuzz->nextRange(&op, 0, 6);
11724ac42b373d9202a89538a1873df9275870c7632Hal Canary        SkScalar a, b, c, d, e, f;
11824ac42b373d9202a89538a1873df9275870c7632Hal Canary        switch (op) {
11924ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 0:
120ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_nice_float(fuzz, &a, &b);
12124ac42b373d9202a89538a1873df9275870c7632Hal Canary                path->moveTo(a, b);
12224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
12324ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 1:
124ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_nice_float(fuzz, &a, &b);
12524ac42b373d9202a89538a1873df9275870c7632Hal Canary                path->lineTo(a, b);
12624ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
12724ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 2:
128ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_nice_float(fuzz, &a, &b, &c, &d);
12924ac42b373d9202a89538a1873df9275870c7632Hal Canary                path->quadTo(a, b, c, d);
13024ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
13124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 3:
132ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_nice_float(fuzz, &a, &b, &c, &d, &e);
13324ac42b373d9202a89538a1873df9275870c7632Hal Canary                path->conicTo(a, b, c, d, e);
13424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
13524ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 4:
136ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_nice_float(fuzz, &a, &b, &c, &d, &e, &f);
13724ac42b373d9202a89538a1873df9275870c7632Hal Canary                path->cubicTo(a, b, c, d, e, f);
13824ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
13924ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 5:
140ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_nice_float(fuzz, &a, &b, &c, &d, &e);
14124ac42b373d9202a89538a1873df9275870c7632Hal Canary                path->arcTo(a, b, c, d, e);
14224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
14324ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 6:
14424ac42b373d9202a89538a1873df9275870c7632Hal Canary                path->close();
14524ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
14624ac42b373d9202a89538a1873df9275870c7632Hal Canary            default:
14724ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
14824ac42b373d9202a89538a1873df9275870c7632Hal Canary        }
14924ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
15024ac42b373d9202a89538a1873df9275870c7632Hal Canary}
15124ac42b373d9202a89538a1873df9275870c7632Hal Canary
152e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canarytemplate <>
153e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canaryinline void Fuzz::next(SkRegion* region) {
15424ac42b373d9202a89538a1873df9275870c7632Hal Canary    uint8_t N;
155e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    this->nextRange(&N, 0, 10);
15624ac42b373d9202a89538a1873df9275870c7632Hal Canary    for (uint8_t i = 0; i < N; ++i) {
15724ac42b373d9202a89538a1873df9275870c7632Hal Canary        SkIRect r;
15824ac42b373d9202a89538a1873df9275870c7632Hal Canary        uint8_t op;
159e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        this->next(&r);
16024ac42b373d9202a89538a1873df9275870c7632Hal Canary        r.sort();
161e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        this->nextRange(&op, 0, (uint8_t)SkRegion::kLastOp);
16224ac42b373d9202a89538a1873df9275870c7632Hal Canary        if (!region->op(r, (SkRegion::Op)op)) {
16324ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
16424ac42b373d9202a89538a1873df9275870c7632Hal Canary        }
16524ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
16624ac42b373d9202a89538a1873df9275870c7632Hal Canary}
16724ac42b373d9202a89538a1873df9275870c7632Hal Canary
168b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canarytemplate <>
169b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canaryinline void Fuzz::next(SkShader::TileMode* m) {
170f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary    fuzz_enum_range(this, m, 0, SkShader::kTileModeCount - 1);
17124ac42b373d9202a89538a1873df9275870c7632Hal Canary}
17224ac42b373d9202a89538a1873df9275870c7632Hal Canary
173b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canarytemplate <>
174e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canaryinline void Fuzz::next(SkFilterQuality* q) {
175f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary    fuzz_enum_range(this, q, SkFilterQuality::kNone_SkFilterQuality,
176f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary                    SkFilterQuality::kLast_SkFilterQuality);
177e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary}
178e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary
179e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canarytemplate <>
180b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canaryinline void Fuzz::next(SkMatrix* m) {
18124ac42b373d9202a89538a1873df9275870c7632Hal Canary    constexpr int kArrayLength = 9;
18224ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkScalar buffer[kArrayLength];
18324ac42b373d9202a89538a1873df9275870c7632Hal Canary    int matrixType;
18424ac42b373d9202a89538a1873df9275870c7632Hal Canary    this->nextRange(&matrixType, 0, 4);
18524ac42b373d9202a89538a1873df9275870c7632Hal Canary    switch (matrixType) {
18624ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 0:  // identity
18724ac42b373d9202a89538a1873df9275870c7632Hal Canary            *m = SkMatrix::I();
18824ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
18924ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 1:  // translate
19024ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextRange(&buffer[0], -4000.0f, 4000.0f);
19124ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextRange(&buffer[1], -4000.0f, 4000.0f);
19224ac42b373d9202a89538a1873df9275870c7632Hal Canary            *m = SkMatrix::MakeTrans(buffer[0], buffer[1]);
19324ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
19424ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 2:  // translate + scale
19524ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextRange(&buffer[0], -400.0f, 400.0f);
19624ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextRange(&buffer[1], -400.0f, 400.0f);
19724ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextRange(&buffer[2], -4000.0f, 4000.0f);
19824ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextRange(&buffer[3], -4000.0f, 4000.0f);
19924ac42b373d9202a89538a1873df9275870c7632Hal Canary            *m = SkMatrix::MakeScale(buffer[0], buffer[1]);
20024ac42b373d9202a89538a1873df9275870c7632Hal Canary            m->postTranslate(buffer[2], buffer[3]);
20124ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
20224ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 3:  // affine
20324ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextN(buffer, 6);
20424ac42b373d9202a89538a1873df9275870c7632Hal Canary            m->setAffine(buffer);
20524ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
20624ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 4:  // perspective
20724ac42b373d9202a89538a1873df9275870c7632Hal Canary            this->nextN(buffer, kArrayLength);
20824ac42b373d9202a89538a1873df9275870c7632Hal Canary            m->set9(buffer);
20924ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
21024ac42b373d9202a89538a1873df9275870c7632Hal Canary        default:
21124ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
21224ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
21324ac42b373d9202a89538a1873df9275870c7632Hal Canary}
21424ac42b373d9202a89538a1873df9275870c7632Hal Canary
215b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canarytemplate <>
216b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canaryinline void Fuzz::next(SkRRect* rr) {
21724ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkRect r;
21824ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkVector radii[4];
21924ac42b373d9202a89538a1873df9275870c7632Hal Canary    this->next(&r);
22027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    r.sort();
22127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    for (SkVector& vec : radii) {
22227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        this->nextRange(&vec.fX, 0.0f, 1.0f);
22327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        vec.fX *= 0.5f * r.width();
22427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        this->nextRange(&vec.fY, 0.0f, 1.0f);
22527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        vec.fY *= 0.5f * r.height();
22627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    }
22724ac42b373d9202a89538a1873df9275870c7632Hal Canary    rr->setRectRadii(r, radii);
22824ac42b373d9202a89538a1873df9275870c7632Hal Canary}
22924ac42b373d9202a89538a1873df9275870c7632Hal Canary
230b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canarytemplate <>
231b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canaryinline void Fuzz::next(SkBlendMode* mode) {
232f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary    fuzz_enum_range(this, mode, 0, SkBlendMode::kLastMode);
23324ac42b373d9202a89538a1873df9275870c7632Hal Canary}
23424ac42b373d9202a89538a1873df9275870c7632Hal Canary
2351e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkImage> make_fuzz_image(Fuzz*);
236671e442fccaacf57b6922324e8160173a2919608Hal Canary
2371e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic SkBitmap make_fuzz_bitmap(Fuzz*);
23824ac42b373d9202a89538a1873df9275870c7632Hal Canary
2391e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkPicture> make_fuzz_picture(Fuzz*, int depth);
240671e442fccaacf57b6922324e8160173a2919608Hal Canary
2411e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkColorFilter> make_fuzz_colorfilter(Fuzz* fuzz, int depth) {
24227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    if (depth <= 0) {
24327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        return nullptr;
24427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    }
24527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    int colorFilterType;
24627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    fuzz->nextRange(&colorFilterType, 0, 8);
24727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    switch (colorFilterType) {
24827bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 0:
24927bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return nullptr;
25027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 1: {
25127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            SkColor color;
25227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            SkBlendMode mode;
25327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->next(&color, &mode);
25427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkColorFilter::MakeModeFilter(color, mode);
25527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        }
25627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 2: {
2571e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkColorFilter> outer = make_fuzz_colorfilter(fuzz, depth - 1);
2581e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkColorFilter> inner = make_fuzz_colorfilter(fuzz, depth - 1);
25927bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkColorFilter::MakeComposeFilter(std::move(outer), std::move(inner));
26027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        }
26127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 3: {
26227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            SkScalar array[20];
26327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextN(array, SK_ARRAY_COUNT(array));
26427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkColorFilter::MakeMatrixFilterRowMajor255(array);
26527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        }
26627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 4: {
26727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            SkColor mul, add;
26827bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->next(&mul, &add);
26927bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkColorMatrixFilter::MakeLightingFilter(mul, add);
27027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        }
27127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 5: {
27227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            bool grayscale;
27327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            int invertStyle;
27427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            float contrast;
27527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->next(&grayscale);
27627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextRange(&invertStyle, 0, 2);
27727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextRange(&contrast, -1.0f, 1.0f);
27827bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkHighContrastFilter::Make(SkHighContrastConfig(
27927bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary                    grayscale, SkHighContrastConfig::InvertStyle(invertStyle), contrast));
28027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        }
28127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 6:
28227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkLumaColorFilter::Make();
28327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 7: {
28427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            uint8_t table[256];
28527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextN(table, SK_ARRAY_COUNT(table));
28627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkTableColorFilter::Make(table);
28727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        }
28827bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        case 8: {
28927bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            uint8_t tableA[256];
29027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            uint8_t tableR[256];
29127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            uint8_t tableG[256];
29227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            uint8_t tableB[256];
29327bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextN(tableA, SK_ARRAY_COUNT(tableA));
29427bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextN(tableR, SK_ARRAY_COUNT(tableR));
29527bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextN(tableG, SK_ARRAY_COUNT(tableG));
29627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            fuzz->nextN(tableB, SK_ARRAY_COUNT(tableB));
29727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary            return SkTableColorFilter::MakeARGB(tableA, tableR, tableG, tableB);
29827bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary        }
29927bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    }
30027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary    return nullptr;
30127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary}
30224ac42b373d9202a89538a1873df9275870c7632Hal Canary
3031e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic void fuzz_gradient_stops(Fuzz* fuzz, SkScalar* pos, int colorCount) {
30424ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkScalar totalPos = 0;
30524ac42b373d9202a89538a1873df9275870c7632Hal Canary    for (int i = 0; i < colorCount; ++i) {
30624ac42b373d9202a89538a1873df9275870c7632Hal Canary        fuzz->nextRange(&pos[i], 1.0f, 1024.0f);
30724ac42b373d9202a89538a1873df9275870c7632Hal Canary        totalPos += pos[i];
30824ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
30924ac42b373d9202a89538a1873df9275870c7632Hal Canary    totalPos = 1.0f / totalPos;
31024ac42b373d9202a89538a1873df9275870c7632Hal Canary    for (int i = 0; i < colorCount; ++i) {
31124ac42b373d9202a89538a1873df9275870c7632Hal Canary        pos[i] *= totalPos;
31224ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
313b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary    // SkASSERT(fabs(pos[colorCount - 1] - 1.0f) < 0.00001f);
31424ac42b373d9202a89538a1873df9275870c7632Hal Canary    pos[colorCount - 1] = 1.0f;
31524ac42b373d9202a89538a1873df9275870c7632Hal Canary}
31624ac42b373d9202a89538a1873df9275870c7632Hal Canary
3171e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkShader> make_fuzz_shader(Fuzz* fuzz, int depth) {
31824ac42b373d9202a89538a1873df9275870c7632Hal Canary    sk_sp<SkShader> shader1(nullptr), shader2(nullptr);
31924ac42b373d9202a89538a1873df9275870c7632Hal Canary    sk_sp<SkColorFilter> colorFilter(nullptr);
32024ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkBitmap bitmap;
32124ac42b373d9202a89538a1873df9275870c7632Hal Canary    sk_sp<SkImage> img;
32224ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkShader::TileMode tmX, tmY;
32324ac42b373d9202a89538a1873df9275870c7632Hal Canary    bool useMatrix;
32424ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkColor color;
32524ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkMatrix matrix;
32624ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkBlendMode blendMode;
32724ac42b373d9202a89538a1873df9275870c7632Hal Canary    int shaderType;
32824ac42b373d9202a89538a1873df9275870c7632Hal Canary    if (depth <= 0) {
32924ac42b373d9202a89538a1873df9275870c7632Hal Canary        return nullptr;
33024ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
331671e442fccaacf57b6922324e8160173a2919608Hal Canary    fuzz->nextRange(&shaderType, 0, 14);
33224ac42b373d9202a89538a1873df9275870c7632Hal Canary    switch (shaderType) {
33324ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 0:
33424ac42b373d9202a89538a1873df9275870c7632Hal Canary            return nullptr;
33524ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 1:
33624ac42b373d9202a89538a1873df9275870c7632Hal Canary            return SkShader::MakeEmptyShader();
33724ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 2:
33824ac42b373d9202a89538a1873df9275870c7632Hal Canary            fuzz->next(&color);
33924ac42b373d9202a89538a1873df9275870c7632Hal Canary            return SkShader::MakeColorShader(color);
34024ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 3:
3411e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            img = make_fuzz_image(fuzz);
34224ac42b373d9202a89538a1873df9275870c7632Hal Canary            fuzz->next(&tmX, &tmY, &useMatrix);
34324ac42b373d9202a89538a1873df9275870c7632Hal Canary            if (useMatrix) {
34424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&matrix);
34524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
34624ac42b373d9202a89538a1873df9275870c7632Hal Canary            return img->makeShader(tmX, tmY, useMatrix ? &matrix : nullptr);
34724ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 4:
3481e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            bitmap = make_fuzz_bitmap(fuzz);
34924ac42b373d9202a89538a1873df9275870c7632Hal Canary            fuzz->next(&tmX, &tmY, &useMatrix);
35024ac42b373d9202a89538a1873df9275870c7632Hal Canary            if (useMatrix) {
35124ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&matrix);
35224ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
35324ac42b373d9202a89538a1873df9275870c7632Hal Canary            return SkShader::MakeBitmapShader(bitmap, tmX, tmY, useMatrix ? &matrix : nullptr);
35424ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 5:
3551e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            shader1 = make_fuzz_shader(fuzz, depth - 1);  // limit recursion.
35624ac42b373d9202a89538a1873df9275870c7632Hal Canary            fuzz->next(&matrix);
35724ac42b373d9202a89538a1873df9275870c7632Hal Canary            return shader1 ? shader1->makeWithLocalMatrix(matrix) : nullptr;
35824ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 6:
3591e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            shader1 = make_fuzz_shader(fuzz, depth - 1);  // limit recursion.
3601e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            colorFilter = make_fuzz_colorfilter(fuzz, depth - 1);
36124ac42b373d9202a89538a1873df9275870c7632Hal Canary            return shader1 ? shader1->makeWithColorFilter(std::move(colorFilter)) : nullptr;
36224ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 7:
3631e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            shader1 = make_fuzz_shader(fuzz, depth - 1);  // limit recursion.
3641e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            shader2 = make_fuzz_shader(fuzz, depth - 1);
36524ac42b373d9202a89538a1873df9275870c7632Hal Canary            fuzz->next(&blendMode);
36624ac42b373d9202a89538a1873df9275870c7632Hal Canary            return SkShader::MakeComposeShader(std::move(shader1), std::move(shader2), blendMode);
367b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case 8: {
3681e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            auto pic = make_fuzz_picture(fuzz, depth - 1);
369b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            bool useTile;
370b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkRect tile;
371b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->next(&tmX, &tmY, &useMatrix, &useTile);
372b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (useMatrix) {
373b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                fuzz->next(&matrix);
374b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
375b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (useTile) {
376b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                fuzz->next(&tile);
377671e442fccaacf57b6922324e8160173a2919608Hal Canary            }
378b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            return SkShader::MakePictureShader(std::move(pic), tmX, tmY,
379b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                               useMatrix ? &matrix : nullptr,
380b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                               useTile ? &tile : nullptr);
381b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        }
382671e442fccaacf57b6922324e8160173a2919608Hal Canary        // EFFECTS:
38324ac42b373d9202a89538a1873df9275870c7632Hal Canary        case 9:
384671e442fccaacf57b6922324e8160173a2919608Hal Canary            return SkGaussianEdgeShader::Make();
385b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case 10: {
386b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            constexpr int kMaxColors = 12;
387b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkPoint pts[2];
388b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkColor colors[kMaxColors];
389b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar pos[kMaxColors];
390b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            int colorCount;
391b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            bool usePos;
392b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextN(pts, 2);
393b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextRange(&colorCount, 2, kMaxColors);
394b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextN(colors, colorCount);
395b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->next(&tmX, &useMatrix, &usePos);
396b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (useMatrix) {
397b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                fuzz->next(&matrix);
39824ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
399b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (usePos) {
4001e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_gradient_stops(fuzz, pos, colorCount);
401b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
402b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            return SkGradientShader::MakeLinear(pts, colors, usePos ? pos : nullptr, colorCount,
403b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                tmX, 0, useMatrix ? &matrix : nullptr);
404b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        }
405b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case 11: {
406b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            constexpr int kMaxColors = 12;
407b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkPoint center;
408b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar radius;
409b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            int colorCount;
410b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            bool usePos;
411b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkColor colors[kMaxColors];
412b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar pos[kMaxColors];
413b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->next(&tmX, &useMatrix, &usePos, &center, &radius);
414b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextRange(&colorCount, 2, kMaxColors);
415b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextN(colors, colorCount);
416b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (useMatrix) {
417b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                fuzz->next(&matrix);
418b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
419b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (usePos) {
4201e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_gradient_stops(fuzz, pos, colorCount);
421b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
422b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            return SkGradientShader::MakeRadial(center, radius, colors, usePos ? pos : nullptr,
423b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                colorCount, tmX, 0, useMatrix ? &matrix : nullptr);
424b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        }
425b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case 12: {
426b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            constexpr int kMaxColors = 12;
427b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkPoint start, end;
428b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar startRadius, endRadius;
429b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            int colorCount;
430b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            bool usePos;
431b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkColor colors[kMaxColors];
432b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar pos[kMaxColors];
433b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->next(&tmX, &useMatrix, &usePos, &startRadius, &endRadius, &start, &end);
434b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextRange(&colorCount, 2, kMaxColors);
435b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextN(colors, colorCount);
436b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (useMatrix) {
437b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                fuzz->next(&matrix);
438b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
439b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (usePos) {
4401e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_gradient_stops(fuzz, pos, colorCount);
441b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
442b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius, colors,
443b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                         usePos ? pos : nullptr, colorCount, tmX, 0,
444b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                         useMatrix ? &matrix : nullptr);
445b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        }
446b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case 13: {
447b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            constexpr int kMaxColors = 12;
448b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar cx, cy;
449b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            int colorCount;
450b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            bool usePos;
451b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkColor colors[kMaxColors];
452b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar pos[kMaxColors];
453b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->next(&cx, &cy, &useMatrix, &usePos);
454b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextRange(&colorCount, 2, kMaxColors);
455b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextN(colors, colorCount);
456b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (useMatrix) {
457b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                fuzz->next(&matrix);
458b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
459b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (usePos) {
4601e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_gradient_stops(fuzz, pos, colorCount);
461b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
462b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            return SkGradientShader::MakeSweep(cx, cy, colors, usePos ? pos : nullptr, colorCount,
463b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                               0, useMatrix ? &matrix : nullptr);
464b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        }
465b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case 14: {
466b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkScalar baseFrequencyX, baseFrequencyY, seed;
467b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            int numOctaves;
468b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkISize tileSize;
469b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            bool useTileSize, turbulence;
470b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->next(&baseFrequencyX, &baseFrequencyY, &seed, &useTileSize, &turbulence);
471b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (useTileSize) {
472b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                fuzz->next(&tileSize);
473b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
474b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            fuzz->nextRange(&numOctaves, 2, 7);
475b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            if (turbulence) {
476b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                return SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX, baseFrequencyY,
477b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                           numOctaves, seed,
478b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                           useTileSize ? &tileSize : nullptr);
479b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            } else {
480b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                return SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX, baseFrequencyY,
481b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                             numOctaves, seed,
482b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                                             useTileSize ? &tileSize : nullptr);
483b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
484b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        }
48524ac42b373d9202a89538a1873df9275870c7632Hal Canary        default:
48624ac42b373d9202a89538a1873df9275870c7632Hal Canary            break;
48724ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
488edbeb8b842aa86d18388f75a1dbf1e470a565680Kevin Lubick    return nullptr;
48924ac42b373d9202a89538a1873df9275870c7632Hal Canary}
49024ac42b373d9202a89538a1873df9275870c7632Hal Canary
4911e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkPathEffect> make_fuzz_patheffect(Fuzz* fuzz, int depth) {
4925395c598dbc3fc85b45a18752867aea65643f147Hal Canary    if (depth <= 0) {
4935395c598dbc3fc85b45a18752867aea65643f147Hal Canary        return nullptr;
4945395c598dbc3fc85b45a18752867aea65643f147Hal Canary    }
4955395c598dbc3fc85b45a18752867aea65643f147Hal Canary    uint8_t pathEffectType;
4965395c598dbc3fc85b45a18752867aea65643f147Hal Canary    fuzz->nextRange(&pathEffectType, 0, 9);
4975395c598dbc3fc85b45a18752867aea65643f147Hal Canary    switch (pathEffectType) {
4985395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 0: {
4995395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return nullptr;
5005395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5015395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 1: {
5021e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkPathEffect> first = make_fuzz_patheffect(fuzz, depth - 1);
5031e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkPathEffect> second = make_fuzz_patheffect(fuzz, depth - 1);
5045395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkPathEffect::MakeSum(std::move(first), std::move(second));
5055395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5065395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 2: {
5071e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkPathEffect> first = make_fuzz_patheffect(fuzz, depth - 1);
5081e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkPathEffect> second = make_fuzz_patheffect(fuzz, depth - 1);
5095395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkPathEffect::MakeCompose(std::move(first), std::move(second));
5105395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5115395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 3: {
5125395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkPath path;
5135395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz_path(fuzz, &path, 20);
5145395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar advance, phase;
5155395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&advance, &phase);
516f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            SkPath1DPathEffect::Style style;
517f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            fuzz_enum_range(fuzz, &style, 0, SkPath1DPathEffect::kLastEnum_Style);
518f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            return SkPath1DPathEffect::Make(path, advance, phase, style);
5195395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5205395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 4: {
5215395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar width;
5225395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkMatrix matrix;
5235395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&width, &matrix);
5245395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkLine2DPathEffect::Make(width, matrix);
5255395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5265395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 5: {
5275395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkPath path;
5285395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz_path(fuzz, &path, 20);
5295395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkMatrix matrix;
5305395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&matrix);
5315395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkPath2DPathEffect::Make(matrix, path);
5325395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5335395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 6: {
5345395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar radius;
5355395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&radius);
5365395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkArcToPathEffect::Make(radius);
5375395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5385395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 7: {
5395395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar radius;
5405395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&radius);
5415395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkCornerPathEffect::Make(radius);
5425395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5435395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 8: {
5445395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar phase;
5455395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&phase);
5465395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar intervals[20];
5475395c598dbc3fc85b45a18752867aea65643f147Hal Canary            int count;
5485395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->nextRange(&count, 0, (int)SK_ARRAY_COUNT(intervals));
5495395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->nextN(intervals, count);
5505395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkDashPathEffect::Make(intervals, count, phase);
5515395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5525395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 9: {
5535395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar segLength, dev;
5545395c598dbc3fc85b45a18752867aea65643f147Hal Canary            uint32_t seed;
5555395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&segLength, &dev, &seed);
5565395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkDiscretePathEffect::Make(segLength, dev, seed);
5575395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5585395c598dbc3fc85b45a18752867aea65643f147Hal Canary        default:
5595395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkASSERT(false);
5605395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return nullptr;
5615395c598dbc3fc85b45a18752867aea65643f147Hal Canary    }
5625395c598dbc3fc85b45a18752867aea65643f147Hal Canary}
56324ac42b373d9202a89538a1873df9275870c7632Hal Canary
5641e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkMaskFilter> make_fuzz_maskfilter(Fuzz* fuzz) {
5655395c598dbc3fc85b45a18752867aea65643f147Hal Canary    int maskfilterType;
5665395c598dbc3fc85b45a18752867aea65643f147Hal Canary    fuzz->nextRange(&maskfilterType, 0, 2);
5675395c598dbc3fc85b45a18752867aea65643f147Hal Canary    switch (maskfilterType) {
5685395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 0:
5695395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return nullptr;
5705395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 1: {
571f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            SkBlurStyle blurStyle;
572f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            fuzz_enum_range(fuzz, &blurStyle, 0, kLastEnum_SkBlurStyle);
5735395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar sigma;
5745395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&sigma);
5755395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkRect occluder{0.0f, 0.0f, 0.0f, 0.0f};
5761e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            if (make_fuzz_t<bool>(fuzz)) {
5775395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->next(&occluder);
5785395c598dbc3fc85b45a18752867aea65643f147Hal Canary            }
5795395c598dbc3fc85b45a18752867aea65643f147Hal Canary            uint32_t flags;
5805395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->nextRange(&flags, 0, 3);
581f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            return SkBlurMaskFilter::Make(blurStyle, sigma, occluder, flags);
5825395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5835395c598dbc3fc85b45a18752867aea65643f147Hal Canary        case 2: {
5845395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkRRect first, second;
5855395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkScalar radius;
5865395c598dbc3fc85b45a18752867aea65643f147Hal Canary            fuzz->next(&first, &second, &radius);
5875395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return SkRRectsGaussianEdgeMaskFilter::Make(first, second, radius);
5885395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
5895395c598dbc3fc85b45a18752867aea65643f147Hal Canary        default:
5905395c598dbc3fc85b45a18752867aea65643f147Hal Canary            SkASSERT(false);
5915395c598dbc3fc85b45a18752867aea65643f147Hal Canary            return nullptr;
5925395c598dbc3fc85b45a18752867aea65643f147Hal Canary    }
5935395c598dbc3fc85b45a18752867aea65643f147Hal Canary}
59424ac42b373d9202a89538a1873df9275870c7632Hal Canary
5951e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkTypeface> make_fuzz_typeface(Fuzz* fuzz) {
5961e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    if (make_fuzz_t<bool>(fuzz)) {
597671e442fccaacf57b6922324e8160173a2919608Hal Canary        return nullptr;
598671e442fccaacf57b6922324e8160173a2919608Hal Canary    }
599671e442fccaacf57b6922324e8160173a2919608Hal Canary    auto fontMugger = SkFontMgr::RefDefault();
600671e442fccaacf57b6922324e8160173a2919608Hal Canary    SkASSERT(fontMugger);
601671e442fccaacf57b6922324e8160173a2919608Hal Canary    int familyCount = fontMugger->countFamilies();
602671e442fccaacf57b6922324e8160173a2919608Hal Canary    int i, j;
603671e442fccaacf57b6922324e8160173a2919608Hal Canary    fuzz->nextRange(&i, 0, familyCount - 1);
604671e442fccaacf57b6922324e8160173a2919608Hal Canary    sk_sp<SkFontStyleSet> family(fontMugger->createStyleSet(i));
605671e442fccaacf57b6922324e8160173a2919608Hal Canary    int styleCount = family->count();
606671e442fccaacf57b6922324e8160173a2919608Hal Canary    fuzz->nextRange(&j, 0, styleCount - 1);
607671e442fccaacf57b6922324e8160173a2919608Hal Canary    return sk_sp<SkTypeface>(family->createTypeface(j));
608671e442fccaacf57b6922324e8160173a2919608Hal Canary}
60924ac42b373d9202a89538a1873df9275870c7632Hal Canary
610e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canarytemplate <>
611e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canaryinline void Fuzz::next(SkImageFilter::CropRect* cropRect) {
612e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    SkRect rect;
613e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    uint8_t flags;
614e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    this->next(&rect);
615e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    this->nextRange(&flags, 0, 0xF);
616e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    *cropRect = SkImageFilter::CropRect(rect, flags);
617e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary}
618e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary
6191e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkImageFilter> make_fuzz_imageFilter(Fuzz* fuzz, int depth);
620e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary
621e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canarystatic sk_sp<SkImageFilter> make_fuzz_lighting_imagefilter(Fuzz* fuzz, int depth) {
622e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    if (depth <= 0) {
623e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        return nullptr;
624e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    }
625e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    uint8_t imageFilterType;
626e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    fuzz->nextRange(&imageFilterType, 1, 6);
627e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    SkPoint3 p, q;
628e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    SkColor lightColor;
629e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    SkScalar surfaceScale, k, specularExponent, cutoffAngle, shininess;
630e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    sk_sp<SkImageFilter> input;
631e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    SkImageFilter::CropRect cropRect;
632e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    bool useCropRect;
633e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    fuzz->next(&useCropRect);
634e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    if (useCropRect) {
635e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        fuzz->next(&cropRect);
636e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    }
637e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    switch (imageFilterType) {
638e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 1:
639e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&p, &lightColor, &surfaceScale, &k);
6401e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            input = make_fuzz_imageFilter(fuzz, depth - 1);
641e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkLightingImageFilter::MakeDistantLitDiffuse(p, lightColor, surfaceScale, k,
642e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                                std::move(input),
643e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                                useCropRect ? &cropRect : nullptr);
644e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 2:
645e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&p, &lightColor, &surfaceScale, &k);
6461e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            input = make_fuzz_imageFilter(fuzz, depth - 1);
647e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkLightingImageFilter::MakePointLitDiffuse(p, lightColor, surfaceScale, k,
648e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                              std::move(input),
649e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                              useCropRect ? &cropRect : nullptr);
650e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 3:
651e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&p, &q, &specularExponent, &cutoffAngle, &lightColor, &surfaceScale, &k);
6521e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            input = make_fuzz_imageFilter(fuzz, depth - 1);
653e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkLightingImageFilter::MakeSpotLitDiffuse(
654e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                    p, q, specularExponent, cutoffAngle, lightColor, surfaceScale, k,
655e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                    std::move(input), useCropRect ? &cropRect : nullptr);
656e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 4:
657e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&p, &lightColor, &surfaceScale, &k, &shininess);
6581e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            input = make_fuzz_imageFilter(fuzz, depth - 1);
659e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkLightingImageFilter::MakeDistantLitSpecular(p, lightColor, surfaceScale, k,
660e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                                 shininess, std::move(input),
661e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                                 useCropRect ? &cropRect : nullptr);
662e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 5:
663e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&p, &lightColor, &surfaceScale, &k, &shininess);
6641e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            input = make_fuzz_imageFilter(fuzz, depth - 1);
665e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkLightingImageFilter::MakePointLitSpecular(p, lightColor, surfaceScale, k,
666e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                               shininess, std::move(input),
667e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                               useCropRect ? &cropRect : nullptr);
668e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 6:
669e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&p, &q, &specularExponent, &cutoffAngle, &lightColor, &surfaceScale, &k,
670e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                       &shininess);
6711e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            input = make_fuzz_imageFilter(fuzz, depth - 1);
672e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkLightingImageFilter::MakeSpotLitSpecular(
673e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                    p, q, specularExponent, cutoffAngle, lightColor, surfaceScale, k, shininess,
674e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                    std::move(input), useCropRect ? &cropRect : nullptr);
675e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        default:
676e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkASSERT(false);
677e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return nullptr;
678e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    }
679e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary}
680e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary
6811e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic void fuzz_paint(Fuzz* fuzz, SkPaint* paint, int depth);
682e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary
6831e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkImageFilter> make_fuzz_imageFilter(Fuzz* fuzz, int depth) {
684e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    if (depth <= 0) {
685e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        return nullptr;
686e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    }
687e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    uint8_t imageFilterType;
688e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    fuzz->nextRange(&imageFilterType, 0, 24);
689e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    switch (imageFilterType) {
690e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 0:
691e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return nullptr;
692e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 1: {
693e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar sigmaX, sigmaY;
6941e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
695e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
696e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&sigmaX, &sigmaY, &useCropRect);
697dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick            SkImageFilter::CropRect cropRect;
698e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
699dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
700e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
701e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkImageFilter::MakeBlur(sigmaX, sigmaY, std::move(input),
702e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                           useCropRect ? &cropRect : nullptr);
703e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
704e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 2: {
705e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkMatrix matrix;
706e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkFilterQuality quality;
707e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&matrix, &quality);
7081e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
709e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkImageFilter::MakeMatrixFilter(matrix, quality, std::move(input));
710e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
711e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 3: {
712e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkRegion region;
713e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar innerMin, outerMax;
7141e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
715e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
716e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&region, &innerMin, &outerMax, &useCropRect);
717dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick            SkImageFilter::CropRect cropRect;
718e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
719dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
720e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
721e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkAlphaThresholdFilter::Make(region, innerMin, outerMax, std::move(input),
722e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                useCropRect ? &cropRect : nullptr);
723e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
724e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 4: {
725e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            float k1, k2, k3, k4;
726e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool enforcePMColor;
727e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
728e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&k1, &k2, &k3, &k4, &enforcePMColor, &useCropRect);
7291e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> background = make_fuzz_imageFilter(fuzz, depth - 1);
7301e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> foreground = make_fuzz_imageFilter(fuzz, depth - 1);
731e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
732e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
733dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
734e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
735e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkArithmeticImageFilter::Make(k1, k2, k3, k4, enforcePMColor,
736e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                 std::move(background), std::move(foreground),
737e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                 useCropRect ? &cropRect : nullptr);
738e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
739e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 5: {
7401e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkColorFilter> cf = make_fuzz_colorfilter(fuzz, depth - 1);
7411e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
742e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
743e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
744e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect);
745e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
746dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
747e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
748e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkColorFilterImageFilter::Make(std::move(cf), std::move(input),
749e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                  useCropRect ? &cropRect : nullptr);
750e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
751e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 6: {
7521e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> ifo = make_fuzz_imageFilter(fuzz, depth - 1);
7531e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> ifi = make_fuzz_imageFilter(fuzz, depth - 1);
754e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkComposeImageFilter::Make(std::move(ifo), std::move(ifi));
755e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
756e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 7: {
757e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, yChannelSelector;
758f49b1e0ad955c437675eae6e8bd64a2e0941e204Hal Canary            fuzz_enum_range(fuzz, &xChannelSelector, 1, 4);
759f49b1e0ad955c437675eae6e8bd64a2e0941e204Hal Canary            fuzz_enum_range(fuzz, &yChannelSelector, 1, 4);
760e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar scale;
761e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
762e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&scale, &useCropRect);
763e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
764e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
765dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
766e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
7671e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> displacement = make_fuzz_imageFilter(fuzz, depth - 1);
7681e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> color = make_fuzz_imageFilter(fuzz, depth - 1);
769e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkDisplacementMapEffect::Make(xChannelSelector, yChannelSelector, scale,
770e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                 std::move(displacement), std::move(color),
771e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                 useCropRect ? &cropRect : nullptr);
772e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
773e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 8: {
774e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar dx, dy, sigmaX, sigmaY;
775e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkColor color;
776e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkDropShadowImageFilter::ShadowMode shadowMode;
777f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            fuzz_enum_range(fuzz, &shadowMode, 0, 1);
778e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
779e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&dx, &dy, &sigmaX, &sigmaY, &color, &useCropRect);
780e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
781e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
782dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
783e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
7841e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
785e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkDropShadowImageFilter::Make(dx, dy, sigmaX, sigmaY, color, shadowMode,
786e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                 std::move(input),
787e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                 useCropRect ? &cropRect : nullptr);
788e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
789e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 9:
7901e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            return SkImageSource::Make(make_fuzz_image(fuzz));
791e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 10: {
7921e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImage> image = make_fuzz_image(fuzz);
793e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkRect srcRect, dstRect;
794e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkFilterQuality filterQuality;
795e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&srcRect, &dstRect, &filterQuality);
796e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkImageSource::Make(std::move(image), srcRect, dstRect, filterQuality);
797e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
798e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 11:
799e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return make_fuzz_lighting_imagefilter(fuzz, depth - 1);
800e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 12: {
801e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkRect srcRect;
802e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar inset;
803e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
804e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
805e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&srcRect, &inset, &useCropRect);
806e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
807dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
808e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
8091e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
810e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkMagnifierImageFilter::Make(srcRect, inset, std::move(input),
811e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                useCropRect ? &cropRect : nullptr);
812e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
813e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 13: {
814e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            constexpr int kMaxKernelSize = 5;
815e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            int32_t n, m;
816e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->nextRange(&n, 1, kMaxKernelSize);
817e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->nextRange(&m, 1, kMaxKernelSize);
818e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar kernel[kMaxKernelSize * kMaxKernelSize];
819e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->nextN(kernel, n * m);
820e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            int32_t offsetX, offsetY;
821e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->nextRange(&offsetX, 0, n - 1);
822e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->nextRange(&offsetY, 0, m - 1);
823e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar gain, bias;
824e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool convolveAlpha, useCropRect;
825e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&gain, &bias, &convolveAlpha, &useCropRect);
826e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkMatrixConvolutionImageFilter::TileMode tileMode;
827f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary            fuzz_enum_range(fuzz, &tileMode, 0, 2);
828e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
829e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
830dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
831e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
8321e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
833e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkMatrixConvolutionImageFilter::Make(
834e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                    SkISize{n, m}, kernel, gain, bias, SkIPoint{offsetX, offsetY}, tileMode,
835e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                    convolveAlpha, std::move(input), useCropRect ? &cropRect : nullptr);
836e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
837e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 14: {
8381e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> first = make_fuzz_imageFilter(fuzz, depth - 1);
8391e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> second = make_fuzz_imageFilter(fuzz, depth - 1);
840e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkBlendMode blendMode;
841e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
842e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect, &blendMode);
843e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
844e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
845dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
846e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
847e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkMergeImageFilter::Make(std::move(first), std::move(second), blendMode,
848e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                            useCropRect ? &cropRect : nullptr);
849e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
850e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 15: {
851e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            constexpr int kMaxCount = 4;
852e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            sk_sp<SkImageFilter> ifs[kMaxCount];
853e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkBlendMode blendModes[kMaxCount];
854e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            int count;
855e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->nextRange(&count, 1, kMaxCount);
856e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            for (int i = 0; i < count; ++i) {
8571e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                ifs[i] = make_fuzz_imageFilter(fuzz, depth - 1);
858e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
859e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->nextN(blendModes, count);
860e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
861e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect);
862e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
863e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
864dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
865e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
866e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkMergeImageFilter::MakeN(ifs, count, blendModes,
867e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                             useCropRect ? &cropRect : nullptr);
868e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
869e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 16: {
870e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            int rx, ry;
871e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&rx, &ry);
872e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
873e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect);
874e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
875e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
876dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
877e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
8781e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
879e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkDilateImageFilter::Make(rx, ry, std::move(input),
880e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                             useCropRect ? &cropRect : nullptr);
881e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
882e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 17: {
883e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            int rx, ry;
884e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&rx, &ry);
885e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
886e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect);
887e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
888e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
889dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
890e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
8911e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
892e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkErodeImageFilter::Make(rx, ry, std::move(input),
893e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                            useCropRect ? &cropRect : nullptr);
894e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
895e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 18: {
896e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkScalar dx, dy;
897e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&dx, &dy);
898e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
899e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect);
900e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
901e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
902dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
903e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
9041e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
905e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkOffsetImageFilter::Make(dx, dy, std::move(input),
906e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                             useCropRect ? &cropRect : nullptr);
907e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
908e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 19: {
909e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkPaint paint;
9101e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            fuzz_paint(fuzz, &paint, depth - 1);
911e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
912e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect);
913e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
914e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
915dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
916e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
917e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkPaintImageFilter::Make(paint, useCropRect ? &cropRect : nullptr);
918e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
919e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 20: {
9201e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkPicture> picture = make_fuzz_picture(fuzz, depth - 1);
921e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkPictureImageFilter::Make(std::move(picture));
922e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
923e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 21: {
924e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkRect cropRect;
925e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&cropRect);
9261e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkPicture> picture = make_fuzz_picture(fuzz, depth - 1);
927e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkPictureImageFilter::Make(std::move(picture), cropRect);
928e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
929e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 22: {
930e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkRect cropRect;
931e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkFilterQuality filterQuality;
932e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&cropRect, &filterQuality);
9331e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkPicture> picture = make_fuzz_picture(fuzz, depth - 1);
934e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkPictureImageFilter::MakeForLocalSpace(std::move(picture), cropRect,
935e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                                           filterQuality);
936e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
937e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 23: {
938e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkRect src, dst;
939e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&src, &dst);
9401e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> input = make_fuzz_imageFilter(fuzz, depth - 1);
941e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkTileImageFilter::Make(src, dst, std::move(input));
942e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
943e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        case 24: {
944e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkBlendMode blendMode;
945e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            bool useCropRect;
946e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            fuzz->next(&useCropRect, &blendMode);
947e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkImageFilter::CropRect cropRect;
948e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            if (useCropRect) {
949dad29a059e11158c97e575747e7769a2a4fb9179Kevin Lubick                fuzz->next(&cropRect);
950e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            }
9511e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> bg = make_fuzz_imageFilter(fuzz, depth - 1);
9521e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary            sk_sp<SkImageFilter> fg = make_fuzz_imageFilter(fuzz, depth - 1);
953e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return SkXfermodeImageFilter::Make(blendMode, std::move(bg), std::move(fg),
954e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                                               useCropRect ? &cropRect : nullptr);
955e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        }
956e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary        default:
957e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            SkASSERT(false);
958e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary            return nullptr;
959e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary    }
960e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary}
96124ac42b373d9202a89538a1873df9275870c7632Hal Canary
9621e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkImage> make_fuzz_image(Fuzz* fuzz) {
96324ac42b373d9202a89538a1873df9275870c7632Hal Canary    int w, h;
96424ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz->nextRange(&w, 1, 1024);
96524ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz->nextRange(&h, 1, 1024);
96624ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkAutoTMalloc<SkPMColor> data(w * h);
96724ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkPixmap pixmap(SkImageInfo::MakeN32Premul(w, h), data.get(), w * sizeof(SkPMColor));
96824ac42b373d9202a89538a1873df9275870c7632Hal Canary    int n = w * h;
96924ac42b373d9202a89538a1873df9275870c7632Hal Canary    for (int i = 0; i < n; ++i) {
97024ac42b373d9202a89538a1873df9275870c7632Hal Canary        SkColor c;
97124ac42b373d9202a89538a1873df9275870c7632Hal Canary        fuzz->next(&c);
97224ac42b373d9202a89538a1873df9275870c7632Hal Canary        data[i] = SkPreMultiplyColor(c);
97324ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
97424ac42b373d9202a89538a1873df9275870c7632Hal Canary    (void)data.release();
975b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary    return SkImage::MakeFromRaster(pixmap, [](const void* p, void*) { sk_free((void*)p); },
976b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                   nullptr);
97724ac42b373d9202a89538a1873df9275870c7632Hal Canary}
97824ac42b373d9202a89538a1873df9275870c7632Hal Canary
9791e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic SkBitmap make_fuzz_bitmap(Fuzz* fuzz) {
98024ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkBitmap bitmap;
98124ac42b373d9202a89538a1873df9275870c7632Hal Canary    int w, h;
98224ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz->nextRange(&w, 1, 1024);
98324ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz->nextRange(&h, 1, 1024);
98424ac42b373d9202a89538a1873df9275870c7632Hal Canary    bitmap.allocN32Pixels(w, h);
98524ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkAutoLockPixels autoLockPixels(bitmap);
98624ac42b373d9202a89538a1873df9275870c7632Hal Canary    for (int y = 0; y < h; ++y) {
98724ac42b373d9202a89538a1873df9275870c7632Hal Canary        for (int x = 0; x < w; ++x) {
98824ac42b373d9202a89538a1873df9275870c7632Hal Canary            SkColor c;
98924ac42b373d9202a89538a1873df9275870c7632Hal Canary            fuzz->next(&c);
99024ac42b373d9202a89538a1873df9275870c7632Hal Canary            *bitmap.getAddr32(x, y) = SkPreMultiplyColor(c);
99124ac42b373d9202a89538a1873df9275870c7632Hal Canary        }
99224ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
99324ac42b373d9202a89538a1873df9275870c7632Hal Canary    return bitmap;
99424ac42b373d9202a89538a1873df9275870c7632Hal Canary}
99524ac42b373d9202a89538a1873df9275870c7632Hal Canary
9961e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarytemplate <typename T, typename Min, typename Max>
9971e0138b58287c086a3085cd2b4640c713d5c9653Hal Canaryinline T make_fuzz_t_range(Fuzz* fuzz, Min minv, Max maxv) {
9981e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    T value;
9991e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    fuzz_enum_range(fuzz, &value, minv, maxv);
10001e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    return value;
10011e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary}
10021e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary
10031e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic void fuzz_paint(Fuzz* fuzz, SkPaint* paint, int depth) {
100424ac42b373d9202a89538a1873df9275870c7632Hal Canary    if (!fuzz || !paint || depth <= 0) {
100524ac42b373d9202a89538a1873df9275870c7632Hal Canary        return;
100624ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
100724ac42b373d9202a89538a1873df9275870c7632Hal Canary
10081e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setAntiAlias(    make_fuzz_t<bool>(fuzz));
10091e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setDither(       make_fuzz_t<bool>(fuzz));
10101e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setColor(        make_fuzz_t<SkColor>(fuzz));
10111e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setBlendMode(    make_fuzz_t_range<SkBlendMode>(fuzz, 0, SkBlendMode::kLastMode));
10121e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setFilterQuality(make_fuzz_t_range<SkFilterQuality>(fuzz, 0, kLast_SkFilterQuality));
10131e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setStyle(        make_fuzz_t_range<SkPaint::Style>(fuzz, 0, 2));
10141e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setShader(       make_fuzz_shader(fuzz, depth - 1));
10151e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setPathEffect(   make_fuzz_patheffect(fuzz, depth - 1));
10161e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setMaskFilter(   make_fuzz_maskfilter(fuzz));
10171e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setImageFilter(  make_fuzz_imageFilter(fuzz, depth - 1));
10181e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setColorFilter(  make_fuzz_colorfilter(fuzz, depth - 1));
101924ac42b373d9202a89538a1873df9275870c7632Hal Canary
102024ac42b373d9202a89538a1873df9275870c7632Hal Canary    if (paint->getStyle() != SkPaint::kFill_Style) {
10211e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary        paint->setStrokeWidth(make_fuzz_t<SkScalar>(fuzz));
10221e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary        paint->setStrokeMiter(make_fuzz_t<SkScalar>(fuzz));
10231e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary        paint->setStrokeCap(  make_fuzz_t_range<SkPaint::Cap>(fuzz, 0, SkPaint::kLast_Cap));
10241e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary        paint->setStrokeJoin( make_fuzz_t_range<SkPaint::Join>(fuzz, 0, SkPaint::kLast_Join));
102524ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
102624ac42b373d9202a89538a1873df9275870c7632Hal Canary}
102724ac42b373d9202a89538a1873df9275870c7632Hal Canary
10281e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic void fuzz_paint_text(Fuzz* fuzz, SkPaint* paint) {
10291e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setTypeface(          make_fuzz_typeface(fuzz));
10301e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setTextSize(          make_fuzz_t<SkScalar>(fuzz));
10311e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setTextScaleX(        make_fuzz_t<SkScalar>(fuzz));
10321e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setTextSkewX(         make_fuzz_t<SkScalar>(fuzz));
10331e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setLinearText(        make_fuzz_t<bool>(fuzz));
10341e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setSubpixelText(      make_fuzz_t<bool>(fuzz));
10351e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setLCDRenderText(     make_fuzz_t<bool>(fuzz));
10361e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setEmbeddedBitmapText(make_fuzz_t<bool>(fuzz));
10371e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setAutohinted(        make_fuzz_t<bool>(fuzz));
10381e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setVerticalText(      make_fuzz_t<bool>(fuzz));
10391e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setFakeBoldText(      make_fuzz_t<bool>(fuzz));
10401e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setDevKernText(       make_fuzz_t<bool>(fuzz));
10411e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setHinting(           make_fuzz_t_range<SkPaint::Hinting>(fuzz, 0,
10421e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                                                                     SkPaint::kFull_Hinting));
10431e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setTextAlign(         make_fuzz_t_range<SkPaint::Align>(fuzz, 0, 2));
10445395c598dbc3fc85b45a18752867aea65643f147Hal Canary}
10455395c598dbc3fc85b45a18752867aea65643f147Hal Canary
10465395c598dbc3fc85b45a18752867aea65643f147Hal Canarystatic void fuzz_paint_text_encoding(Fuzz* fuzz, SkPaint* paint) {
10471e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary    paint->setTextEncoding(make_fuzz_t_range<SkPaint::TextEncoding>(fuzz, 0, 3));
1048671e442fccaacf57b6922324e8160173a2919608Hal Canary}
1049671e442fccaacf57b6922324e8160173a2919608Hal Canary
10505395c598dbc3fc85b45a18752867aea65643f147Hal Canaryconstexpr int kMaxGlyphCount = 30;
10515395c598dbc3fc85b45a18752867aea65643f147Hal Canary
10521e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic SkTDArray<uint8_t> make_fuzz_text(Fuzz* fuzz, const SkPaint& paint) {
1053671e442fccaacf57b6922324e8160173a2919608Hal Canary    SkTDArray<uint8_t> array;
1054671e442fccaacf57b6922324e8160173a2919608Hal Canary    if (SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()) {
1055b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        int glyphRange = paint.getTypeface() ? paint.getTypeface()->countGlyphs()
1056b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                             : SkTypeface::MakeDefault()->countGlyphs();
1057671e442fccaacf57b6922324e8160173a2919608Hal Canary        int glyphCount;
10585395c598dbc3fc85b45a18752867aea65643f147Hal Canary        fuzz->nextRange(&glyphCount, 1, kMaxGlyphCount);
1059671e442fccaacf57b6922324e8160173a2919608Hal Canary        SkGlyphID* glyphs = (SkGlyphID*)array.append(glyphCount * sizeof(SkGlyphID));
1060671e442fccaacf57b6922324e8160173a2919608Hal Canary        for (int i = 0; i < glyphCount; ++i) {
1061671e442fccaacf57b6922324e8160173a2919608Hal Canary            fuzz->nextRange(&glyphs[i], 0, glyphRange - 1);
1062671e442fccaacf57b6922324e8160173a2919608Hal Canary        }
1063671e442fccaacf57b6922324e8160173a2919608Hal Canary        return array;
1064671e442fccaacf57b6922324e8160173a2919608Hal Canary    }
1065671e442fccaacf57b6922324e8160173a2919608Hal Canary    static const SkUnichar ranges[][2] = {
1066671e442fccaacf57b6922324e8160173a2919608Hal Canary        {0x0020, 0x007F},
1067671e442fccaacf57b6922324e8160173a2919608Hal Canary        {0x00A1, 0x0250},
1068671e442fccaacf57b6922324e8160173a2919608Hal Canary        {0x0400, 0x0500},
1069671e442fccaacf57b6922324e8160173a2919608Hal Canary    };
1070671e442fccaacf57b6922324e8160173a2919608Hal Canary    int32_t count = 0;
1071b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary    for (size_t i = 0; i < SK_ARRAY_COUNT(ranges); ++i) {
1072671e442fccaacf57b6922324e8160173a2919608Hal Canary        count += (ranges[i][1] - ranges[i][0]);
1073671e442fccaacf57b6922324e8160173a2919608Hal Canary    }
10745395c598dbc3fc85b45a18752867aea65643f147Hal Canary    constexpr int kMaxLength = kMaxGlyphCount;
1075671e442fccaacf57b6922324e8160173a2919608Hal Canary    SkUnichar buffer[kMaxLength];
1076671e442fccaacf57b6922324e8160173a2919608Hal Canary    int length;
1077671e442fccaacf57b6922324e8160173a2919608Hal Canary    fuzz->nextRange(&length, 1, kMaxLength);
1078671e442fccaacf57b6922324e8160173a2919608Hal Canary    for (int j = 0; j < length; ++j) {
1079671e442fccaacf57b6922324e8160173a2919608Hal Canary        int32_t value;
1080671e442fccaacf57b6922324e8160173a2919608Hal Canary        fuzz->nextRange(&value, 0, count - 1);
1081b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        for (size_t i = 0; i < SK_ARRAY_COUNT(ranges); ++i) {
1082671e442fccaacf57b6922324e8160173a2919608Hal Canary            if (value + ranges[i][0] < ranges[i][1]) {
1083671e442fccaacf57b6922324e8160173a2919608Hal Canary                buffer[j] = value + ranges[i][0];
1084671e442fccaacf57b6922324e8160173a2919608Hal Canary                break;
1085671e442fccaacf57b6922324e8160173a2919608Hal Canary            } else {
1086671e442fccaacf57b6922324e8160173a2919608Hal Canary                value -= (ranges[i][1] - ranges[i][0]);
1087671e442fccaacf57b6922324e8160173a2919608Hal Canary            }
1088671e442fccaacf57b6922324e8160173a2919608Hal Canary        }
1089671e442fccaacf57b6922324e8160173a2919608Hal Canary    }
1090671e442fccaacf57b6922324e8160173a2919608Hal Canary    switch (paint.getTextEncoding()) {
1091b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case SkPaint::kUTF8_TextEncoding: {
1092b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            size_t utf8len = 0;
1093b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            for (int j = 0; j < length; ++j) {
1094b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                utf8len += SkUTF8_FromUnichar(buffer[j], nullptr);
1095671e442fccaacf57b6922324e8160173a2919608Hal Canary            }
1096b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            char* ptr = (char*)array.append(utf8len);
1097b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            for (int j = 0; j < length; ++j) {
1098b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                ptr += SkUTF8_FromUnichar(buffer[j], ptr);
1099671e442fccaacf57b6922324e8160173a2919608Hal Canary            }
1100b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        } break;
1101b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        case SkPaint::kUTF16_TextEncoding: {
1102b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            size_t utf16len = 0;
1103b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            for (int j = 0; j < length; ++j) {
1104b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                utf16len += SkUTF16_FromUnichar(buffer[j]);
1105b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
1106b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            uint16_t* ptr = (uint16_t*)array.append(utf16len * sizeof(uint16_t));
1107b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            for (int j = 0; j < length; ++j) {
1108b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                ptr += SkUTF16_FromUnichar(buffer[j], ptr);
1109b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            }
1110b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary        } break;
1111671e442fccaacf57b6922324e8160173a2919608Hal Canary        case SkPaint::kUTF32_TextEncoding:
1112671e442fccaacf57b6922324e8160173a2919608Hal Canary            memcpy(array.append(length * sizeof(SkUnichar)), buffer, length * sizeof(SkUnichar));
1113c1a70e2ddef9147964611e76d2e1142a7ea0ad79Hal Canary            break;
1114671e442fccaacf57b6922324e8160173a2919608Hal Canary        default:
1115b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary            SkASSERT(false);
1116671e442fccaacf57b6922324e8160173a2919608Hal Canary    }
1117671e442fccaacf57b6922324e8160173a2919608Hal Canary    return array;
111824ac42b373d9202a89538a1873df9275870c7632Hal Canary}
111924ac42b373d9202a89538a1873df9275870c7632Hal Canary
11205395c598dbc3fc85b45a18752867aea65643f147Hal Canarystatic sk_sp<SkTextBlob> make_fuzz_textblob(Fuzz* fuzz) {
11215395c598dbc3fc85b45a18752867aea65643f147Hal Canary    SkTextBlobBuilder textBlobBuilder;
11225395c598dbc3fc85b45a18752867aea65643f147Hal Canary    int8_t runCount;
11235395c598dbc3fc85b45a18752867aea65643f147Hal Canary    fuzz->nextRange(&runCount, (int8_t)1, (int8_t)8);
11245395c598dbc3fc85b45a18752867aea65643f147Hal Canary    while (runCount-- > 0) {
11255395c598dbc3fc85b45a18752867aea65643f147Hal Canary        SkPaint paint;
11265395c598dbc3fc85b45a18752867aea65643f147Hal Canary        fuzz_paint_text_encoding(fuzz, &paint);
11271e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary        paint.setAntiAlias(make_fuzz_t<bool>(fuzz));
11285395c598dbc3fc85b45a18752867aea65643f147Hal Canary        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
11295395c598dbc3fc85b45a18752867aea65643f147Hal Canary        SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
11305395c598dbc3fc85b45a18752867aea65643f147Hal Canary        int glyphCount = paint.countText(text.begin(), SkToSizeT(text.count()));
11315395c598dbc3fc85b45a18752867aea65643f147Hal Canary        SkASSERT(glyphCount <= kMaxGlyphCount);
11325395c598dbc3fc85b45a18752867aea65643f147Hal Canary        SkScalar x, y;
11335395c598dbc3fc85b45a18752867aea65643f147Hal Canary        const SkTextBlobBuilder::RunBuffer* buffer;
11345395c598dbc3fc85b45a18752867aea65643f147Hal Canary        uint8_t runType;
11355395c598dbc3fc85b45a18752867aea65643f147Hal Canary        fuzz->nextRange(&runType, (uint8_t)0, (uint8_t)2);
11365395c598dbc3fc85b45a18752867aea65643f147Hal Canary        switch (runType) {
11375395c598dbc3fc85b45a18752867aea65643f147Hal Canary            case 0:
11385395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->next(&x, &y);
11395395c598dbc3fc85b45a18752867aea65643f147Hal Canary                // TODO: Test other variations of this.
11405395c598dbc3fc85b45a18752867aea65643f147Hal Canary                buffer = &textBlobBuilder.allocRun(paint, glyphCount, x, y);
11415395c598dbc3fc85b45a18752867aea65643f147Hal Canary                memcpy(buffer->glyphs, text.begin(), SkToSizeT(text.count()));
11425395c598dbc3fc85b45a18752867aea65643f147Hal Canary                break;
11435395c598dbc3fc85b45a18752867aea65643f147Hal Canary            case 1:
11445395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->next(&y);
11455395c598dbc3fc85b45a18752867aea65643f147Hal Canary                // TODO: Test other variations of this.
11465395c598dbc3fc85b45a18752867aea65643f147Hal Canary                buffer = &textBlobBuilder.allocRunPosH(paint, glyphCount, y);
11475395c598dbc3fc85b45a18752867aea65643f147Hal Canary                memcpy(buffer->glyphs, text.begin(), SkToSizeT(text.count()));
11485395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->nextN(buffer->pos, glyphCount);
11495395c598dbc3fc85b45a18752867aea65643f147Hal Canary                break;
11505395c598dbc3fc85b45a18752867aea65643f147Hal Canary            case 2:
11515395c598dbc3fc85b45a18752867aea65643f147Hal Canary                // TODO: Test other variations of this.
11525395c598dbc3fc85b45a18752867aea65643f147Hal Canary                buffer = &textBlobBuilder.allocRunPos(paint, glyphCount);
11535395c598dbc3fc85b45a18752867aea65643f147Hal Canary                memcpy(buffer->glyphs, text.begin(), SkToSizeT(text.count()));
11545395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->nextN(buffer->pos, glyphCount * 2);
11555395c598dbc3fc85b45a18752867aea65643f147Hal Canary                break;
11565395c598dbc3fc85b45a18752867aea65643f147Hal Canary            default:
11575395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkASSERT(false);
11585395c598dbc3fc85b45a18752867aea65643f147Hal Canary        }
11595395c598dbc3fc85b45a18752867aea65643f147Hal Canary    }
11605395c598dbc3fc85b45a18752867aea65643f147Hal Canary    return textBlobBuilder.make();
11615395c598dbc3fc85b45a18752867aea65643f147Hal Canary}
11625395c598dbc3fc85b45a18752867aea65643f147Hal Canary
11631e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) {
116424ac42b373d9202a89538a1873df9275870c7632Hal Canary    if (!fuzz || !canvas || depth <= 0) {
116524ac42b373d9202a89538a1873df9275870c7632Hal Canary        return;
116624ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
116724ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkAutoCanvasRestore autoCanvasRestore(canvas, false);
116824ac42b373d9202a89538a1873df9275870c7632Hal Canary    unsigned N;
116924ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz->nextRange(&N, 0, 2000);
117024ac42b373d9202a89538a1873df9275870c7632Hal Canary    for (unsigned i = 0; i < N; ++i) {
117124ac42b373d9202a89538a1873df9275870c7632Hal Canary        if (fuzz->exhausted()) {
117224ac42b373d9202a89538a1873df9275870c7632Hal Canary            return;
117324ac42b373d9202a89538a1873df9275870c7632Hal Canary        }
117424ac42b373d9202a89538a1873df9275870c7632Hal Canary        SkPaint paint;
117524ac42b373d9202a89538a1873df9275870c7632Hal Canary        SkMatrix matrix;
117624ac42b373d9202a89538a1873df9275870c7632Hal Canary        unsigned drawCommand;
11775af600e42c5660d01e209d5634c15352202368b8Hal Canary        fuzz->nextRange(&drawCommand, 0, 53);
117824ac42b373d9202a89538a1873df9275870c7632Hal Canary        switch (drawCommand) {
117924ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 0:
118024ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->flush();
118124ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
118224ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 1:
118324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->save();
118424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
118524ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 2: {
118624ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect bounds;
118724ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&bounds);
11881e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
118924ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->saveLayer(&bounds, &paint);
119024ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
119124ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
119224ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 3: {
119324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect bounds;
119424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&bounds);
119524ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->saveLayer(&bounds, nullptr);
119624ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
119724ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
119824ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 4:
11991e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
120024ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->saveLayer(nullptr, &paint);
120124ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
120224ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 5:
120324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->saveLayer(nullptr, nullptr);
120424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
120524ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 6: {
120624ac42b373d9202a89538a1873df9275870c7632Hal Canary                uint8_t alpha;
120724ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&alpha);
120824ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->saveLayerAlpha(nullptr, (U8CPU)alpha);
120924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
121024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
121124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 7: {
121224ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect bounds;
121324ac42b373d9202a89538a1873df9275870c7632Hal Canary                uint8_t alpha;
121424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&bounds, &alpha);
121524ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->saveLayerAlpha(&bounds, (U8CPU)alpha);
121624ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
121724ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
121824ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 8: {
121924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkCanvas::SaveLayerRec saveLayerRec;
122024ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect bounds;
12211e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                if (make_fuzz_t<bool>(fuzz)) {
122224ac42b373d9202a89538a1873df9275870c7632Hal Canary                    fuzz->next(&bounds);
122324ac42b373d9202a89538a1873df9275870c7632Hal Canary                    saveLayerRec.fBounds = &bounds;
122424ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
12251e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                if (make_fuzz_t<bool>(fuzz)) {
12261e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
122724ac42b373d9202a89538a1873df9275870c7632Hal Canary                    saveLayerRec.fPaint = &paint;
122824ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
122924ac42b373d9202a89538a1873df9275870c7632Hal Canary                sk_sp<SkImageFilter> imageFilter;
12301e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                if (make_fuzz_t<bool>(fuzz)) {
12311e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    imageFilter = make_fuzz_imageFilter(fuzz, depth - 1);
123224ac42b373d9202a89538a1873df9275870c7632Hal Canary                    saveLayerRec.fBackdrop = imageFilter.get();
123324ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
12345395c598dbc3fc85b45a18752867aea65643f147Hal Canary                // _DumpCanvas can't handle this.
12351e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                // if (make_fuzz_t<bool>(fuzz)) {
12365395c598dbc3fc85b45a18752867aea65643f147Hal Canary                //     saveLayerRec.fSaveLayerFlags |= SkCanvas::kIsOpaque_SaveLayerFlag;
12375395c598dbc3fc85b45a18752867aea65643f147Hal Canary                // }
12381e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                // if (make_fuzz_t<bool>(fuzz)) {
12395395c598dbc3fc85b45a18752867aea65643f147Hal Canary                //     saveLayerRec.fSaveLayerFlags |= SkCanvas::kPreserveLCDText_SaveLayerFlag;
12405395c598dbc3fc85b45a18752867aea65643f147Hal Canary                // }
12415395c598dbc3fc85b45a18752867aea65643f147Hal Canary
124224ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->saveLayer(saveLayerRec);
124324ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
124424ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
124524ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 9:
124624ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->restore();
124724ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
124824ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 10: {
124924ac42b373d9202a89538a1873df9275870c7632Hal Canary                int saveCount;
125024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&saveCount);
125124ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->restoreToCount(saveCount);
125224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
125324ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
125424ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 11: {
125524ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar x, y;
125624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&x, &y);
125724ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->translate(x, y);
125824ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
125924ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
126024ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 12: {
126124ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar x, y;
126224ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&x, &y);
126324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->scale(x, y);
126424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
126524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
126624ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 13: {
126724ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar v;
126824ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&v);
126924ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->rotate(v);
127024ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
127124ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
127224ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 14: {
127324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar x, y, v;
127424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&x, &y, &v);
127524ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->rotate(v, x, y);
127624ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
127724ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
127824ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 15: {
127924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar x, y;
128024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&x, &y);
128124ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->skew(x, y);
128224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
128324ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
128424ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 16: {
128524ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkMatrix mat;
128624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&mat);
128724ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->concat(mat);
128824ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
128924ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
129024ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 17: {
129124ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkMatrix mat;
129224ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&mat);
129324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->setMatrix(mat);
129424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
129524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
129624ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 18:
129724ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->resetMatrix();
129824ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
129924ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 19: {
130024ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect r;
130124ac42b373d9202a89538a1873df9275870c7632Hal Canary                int op;
130224ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool doAntiAlias;
130324ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&r, &doAntiAlias);
130424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&op, 0, 1);
130524ac42b373d9202a89538a1873df9275870c7632Hal Canary                r.sort();
130624ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->clipRect(r, (SkClipOp)op, doAntiAlias);
130724ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
130824ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
130924ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 20: {
131024ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRRect rr;
131124ac42b373d9202a89538a1873df9275870c7632Hal Canary                int op;
131224ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool doAntiAlias;
131324ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&rr);
131424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&doAntiAlias);
131524ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&op, 0, 1);
131624ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->clipRRect(rr, (SkClipOp)op, doAntiAlias);
131724ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
131824ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
131924ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 21: {
132024ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkPath path;
1321ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_path(fuzz, &path, 30);
132224ac42b373d9202a89538a1873df9275870c7632Hal Canary                int op;
132324ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool doAntiAlias;
132424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&doAntiAlias);
132524ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&op, 0, 1);
132624ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->clipPath(path, (SkClipOp)op, doAntiAlias);
132724ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
132824ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
132924ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 22: {
133024ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRegion region;
133124ac42b373d9202a89538a1873df9275870c7632Hal Canary                int op;
1332e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                fuzz->next(&region);
133324ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&op, 0, 1);
133424ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->clipRegion(region, (SkClipOp)op);
133524ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
133624ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
133724ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 23:
13381e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
133924ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawPaint(paint);
134024ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
134124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 24: {
13421e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
134324ac42b373d9202a89538a1873df9275870c7632Hal Canary                uint8_t pointMode;
134424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&pointMode, 0, 3);
134524ac42b373d9202a89538a1873df9275870c7632Hal Canary                size_t count;
134624ac42b373d9202a89538a1873df9275870c7632Hal Canary                constexpr int kMaxCount = 30;
134724ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&count, 0, kMaxCount);
134824ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkPoint pts[kMaxCount];
134924ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextN(pts, count);
135024ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawPoints((SkCanvas::PointMode)pointMode, count, pts, paint);
135124ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
135224ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
135324ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 25: {
13541e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
135524ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect r;
135624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&r);
135724ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawRect(r, paint);
135824ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
135924ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
136024ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 26: {
13611e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
136224ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRegion region;
1363e03c3e5edcbcb53dcef9729ddd6bef07dc750645Hal Canary                fuzz->next(&region);
136424ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawRegion(region, paint);
136524ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
136624ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
136724ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 27: {
13681e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
136924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect r;
137024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&r);
137124ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawOval(r, paint);
137224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
137324ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
137424ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 29: {
13751e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
137624ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRRect rr;
137724ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&rr);
137824ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawRRect(rr, paint);
137924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
138024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
138124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 30: {
13821e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
138324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRRect orr, irr;
138424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&orr);
138524ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&irr);
138627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary                if (orr.getBounds().contains(irr.getBounds())) {
138727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary                    canvas->drawDRRect(orr, irr, paint);
138827bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary                }
138924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
139024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
139124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 31: {
13921e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
139324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect r;
139424ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar start, sweep;
139524ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool useCenter;
139624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&r, &start, &sweep, &useCenter);
139724ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawArc(r, start, sweep, useCenter, paint);
139824ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
139924ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
140024ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 32: {
140124ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkPath path;
1402ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_path(fuzz, &path, 60);
140324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawPath(path, paint);
140424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
140524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
140624ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 33: {
14071e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                sk_sp<SkImage> img = make_fuzz_image(fuzz);
140824ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar left, top;
140924ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
141024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&left, &top, &usePaint);
141124ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
14121e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
141324ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
141424ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawImage(img.get(), left, top, usePaint ? &paint : nullptr);
141524ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
141624ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
141724ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 34: {
14181e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                auto img = make_fuzz_image(fuzz);
141924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect src, dst;
142024ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
142124ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&src, &dst, &usePaint);
142224ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
14231e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
142424ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1425b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                SkCanvas::SrcRectConstraint constraint =
14261e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                        make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
14271e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                                                : SkCanvas::kFast_SrcRectConstraint;
142824ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawImageRect(img, src, dst, usePaint ? &paint : nullptr, constraint);
142924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
143024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
143124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 35: {
14321e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                auto img = make_fuzz_image(fuzz);
143324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkIRect src;
143424ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
143524ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
143624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&src, &dst, &usePaint);
143724ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
14381e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
143924ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1440b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                SkCanvas::SrcRectConstraint constraint =
14411e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                        make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
14421e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                                                : SkCanvas::kFast_SrcRectConstraint;
144324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawImageRect(img, src, dst, usePaint ? &paint : nullptr, constraint);
144424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
144524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
144624ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 36: {
144724ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
14481e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                auto img = make_fuzz_image(fuzz);
144924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
145024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&dst, &usePaint);
145124ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
14521e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
145324ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1454b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                SkCanvas::SrcRectConstraint constraint =
14551e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                        make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
14561e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                                                : SkCanvas::kFast_SrcRectConstraint;
145724ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawImageRect(img, dst, usePaint ? &paint : nullptr, constraint);
145824ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
145924ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
146024ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 37: {
14611e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                auto img = make_fuzz_image(fuzz);
146224ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkIRect center;
146324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
146424ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
14650361d49e2a663b9fc36352e308728a470320366bHal Canary                fuzz->next(&usePaint);
146624ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
14671e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
146824ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
14690361d49e2a663b9fc36352e308728a470320366bHal Canary                if (make_fuzz_t<bool>(fuzz)) {
14700361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->next(&center);
14710361d49e2a663b9fc36352e308728a470320366bHal Canary                } else {  // Make valid center, see SkLatticeIter::Valid().
14720361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fLeft, 0, img->width() - 1);
14730361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fTop, 0, img->height() - 1);
14740361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fRight, center.fLeft + 1, img->width());
14750361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fBottom, center.fTop + 1, img->height());
14760361d49e2a663b9fc36352e308728a470320366bHal Canary                }
14770361d49e2a663b9fc36352e308728a470320366bHal Canary                fuzz->next(&dst);
147824ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawImageNine(img, center, dst, usePaint ? &paint : nullptr);
147924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
148024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
148124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 38: {
14821e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                SkBitmap bitmap = make_fuzz_bitmap(fuzz);
148324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar left, top;
148424ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
148524ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&left, &top, &usePaint);
148624ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
14871e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
148824ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
148924ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawBitmap(bitmap, left, top, usePaint ? &paint : nullptr);
149024ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
149124ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
149224ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 39: {
14931e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                SkBitmap bitmap = make_fuzz_bitmap(fuzz);
149424ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect src, dst;
149524ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
149624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&src, &dst, &usePaint);
149724ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
14981e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
149924ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1500b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                SkCanvas::SrcRectConstraint constraint =
15011e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                        make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
15021e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                                                : SkCanvas::kFast_SrcRectConstraint;
150324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawBitmapRect(bitmap, src, dst, usePaint ? &paint : nullptr, constraint);
150424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
150524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
150624ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 40: {
15071e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                SkBitmap img = make_fuzz_bitmap(fuzz);
150824ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkIRect src;
150924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
151024ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
151124ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&src, &dst, &usePaint);
151224ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
15131e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
151424ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1515b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                SkCanvas::SrcRectConstraint constraint =
15161e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                        make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
15171e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                                                : SkCanvas::kFast_SrcRectConstraint;
151824ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawBitmapRect(img, src, dst, usePaint ? &paint : nullptr, constraint);
151924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
152024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
152124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 41: {
15221e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                SkBitmap img = make_fuzz_bitmap(fuzz);
152324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
152424ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
152524ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&dst, &usePaint);
152624ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
15271e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
152824ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1529b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                SkCanvas::SrcRectConstraint constraint =
15301e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                        make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
15311e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                                                : SkCanvas::kFast_SrcRectConstraint;
153224ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawBitmapRect(img, dst, usePaint ? &paint : nullptr, constraint);
153324ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
153424ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
153524ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 42: {
15361e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                SkBitmap img = make_fuzz_bitmap(fuzz);
153724ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkIRect center;
153824ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
153924ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
15400361d49e2a663b9fc36352e308728a470320366bHal Canary                fuzz->next(&usePaint);
154124ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
15421e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
154324ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
15440361d49e2a663b9fc36352e308728a470320366bHal Canary                if (make_fuzz_t<bool>(fuzz)) {
15450361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->next(&center);
15460361d49e2a663b9fc36352e308728a470320366bHal Canary                } else {  // Make valid center, see SkLatticeIter::Valid().
15470361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fLeft, 0, img.width() - 1);
15480361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fTop, 0, img.height() - 1);
15490361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fRight, center.fLeft + 1, img.width());
15500361d49e2a663b9fc36352e308728a470320366bHal Canary                    fuzz->nextRange(&center.fBottom, center.fTop + 1, img.height());
15510361d49e2a663b9fc36352e308728a470320366bHal Canary                }
15520361d49e2a663b9fc36352e308728a470320366bHal Canary                fuzz->next(&dst);
155324ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawBitmapNine(img, center, dst, usePaint ? &paint : nullptr);
155424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
155524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
155624ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 43: {
15571e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                SkBitmap img = make_fuzz_bitmap(fuzz);
155824ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
155924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
156024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&usePaint, &dst);
156124ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
15621e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
156324ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
156424ac42b373d9202a89538a1873df9275870c7632Hal Canary                constexpr int kMax = 6;
156524ac42b373d9202a89538a1873df9275870c7632Hal Canary                int xDivs[kMax], yDivs[kMax];
156624ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr};
156724ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&lattice.fXCount, 2, kMax);
156824ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&lattice.fYCount, 2, kMax);
156924ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextN(xDivs, lattice.fXCount);
157024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextN(yDivs, lattice.fYCount);
157124ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawBitmapLattice(img, lattice, dst, usePaint ? &paint : nullptr);
157224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
157324ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
157424ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 44: {
15751e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                auto img = make_fuzz_image(fuzz);
157624ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint;
157724ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkRect dst;
157824ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&usePaint, &dst);
157924ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
15801e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
158124ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
158224ac42b373d9202a89538a1873df9275870c7632Hal Canary                constexpr int kMax = 6;
158324ac42b373d9202a89538a1873df9275870c7632Hal Canary                int xDivs[kMax], yDivs[kMax];
158424ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr};
158524ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&lattice.fXCount, 2, kMax);
158624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&lattice.fYCount, 2, kMax);
158724ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextN(xDivs, lattice.fXCount);
158824ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextN(yDivs, lattice.fYCount);
158924ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawImageLattice(img.get(), lattice, dst, usePaint ? &paint : nullptr);
159024ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
159124ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
159224ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 45: {
15931e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
15941e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint_text(fuzz, &paint);
15955395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz_paint_text_encoding(fuzz, &paint);
159624ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar x, y;
159724ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&x, &y);
15985395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
1599671e442fccaacf57b6922324e8160173a2919608Hal Canary                canvas->drawText(text.begin(), SkToSizeT(text.count()), x, y, paint);
160024ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
160124ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
160224ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 46: {
16031e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
16041e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint_text(fuzz, &paint);
16055395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz_paint_text_encoding(fuzz, &paint);
16065395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
1607671e442fccaacf57b6922324e8160173a2919608Hal Canary                int glyphCount = paint.countText(text.begin(), SkToSizeT(text.count()));
160824ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (glyphCount < 1) {
160924ac42b373d9202a89538a1873df9275870c7632Hal Canary                    break;
161024ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
161124ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkAutoTMalloc<SkPoint> pos(glyphCount);
161224ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkAutoTMalloc<SkScalar> widths(glyphCount);
1613671e442fccaacf57b6922324e8160173a2919608Hal Canary                paint.getTextWidths(text.begin(), SkToSizeT(text.count()), widths.get());
161424ac42b373d9202a89538a1873df9275870c7632Hal Canary                pos[0] = {0, 0};
161524ac42b373d9202a89538a1873df9275870c7632Hal Canary                for (int i = 1; i < glyphCount; ++i) {
161624ac42b373d9202a89538a1873df9275870c7632Hal Canary                    float y;
1617b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                    fuzz->nextRange(&y, -0.5f * paint.getTextSize(), 0.5f * paint.getTextSize());
161824ac42b373d9202a89538a1873df9275870c7632Hal Canary                    pos[i] = {pos[i - 1].x() + widths[i - 1], y};
161924ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1620671e442fccaacf57b6922324e8160173a2919608Hal Canary                canvas->drawPosText(text.begin(), SkToSizeT(text.count()), pos.get(), paint);
162124ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
162224ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
162324ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 47: {
16241e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
16251e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint_text(fuzz, &paint);
16265395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz_paint_text_encoding(fuzz, &paint);
16275395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
1628671e442fccaacf57b6922324e8160173a2919608Hal Canary                int glyphCount = paint.countText(text.begin(), SkToSizeT(text.count()));
162924ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkAutoTMalloc<SkScalar> widths(glyphCount);
163024ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (glyphCount < 1) {
163124ac42b373d9202a89538a1873df9275870c7632Hal Canary                    break;
163224ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
1633671e442fccaacf57b6922324e8160173a2919608Hal Canary                paint.getTextWidths(text.begin(), SkToSizeT(text.count()), widths.get());
163424ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar x = widths[0];
163524ac42b373d9202a89538a1873df9275870c7632Hal Canary                for (int i = 0; i < glyphCount; ++i) {
163624ac42b373d9202a89538a1873df9275870c7632Hal Canary                    SkTSwap(x, widths[i]);
163724ac42b373d9202a89538a1873df9275870c7632Hal Canary                    x += widths[i];
163824ac42b373d9202a89538a1873df9275870c7632Hal Canary                    SkScalar offset;
163924ac42b373d9202a89538a1873df9275870c7632Hal Canary                    fuzz->nextRange(&offset, -0.125f * paint.getTextSize(),
1640b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                    0.125f * paint.getTextSize());
164124ac42b373d9202a89538a1873df9275870c7632Hal Canary                    widths[i] += offset;
164224ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
164324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar y;
164424ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&y);
1645b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                canvas->drawPosTextH(text.begin(), SkToSizeT(text.count()), widths.get(), y, paint);
164624ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
164724ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
164824ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 48: {
16491e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
16501e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint_text(fuzz, &paint);
16515395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz_paint_text_encoding(fuzz, &paint);
16525395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
165324ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkPath path;
1654ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_path(fuzz, &path, 20);
165524ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkScalar hOffset, vOffset;
165624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&hOffset, &vOffset);
1657b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                canvas->drawTextOnPathHV(text.begin(), SkToSizeT(text.count()), path, hOffset,
1658b69c4b8bdeb30e74c88b6ce3f3792d825992b03dHal Canary                                         vOffset, paint);
165924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
166024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
166124ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 49: {
166224ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkMatrix matrix;
16631e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                bool useMatrix = make_fuzz_t<bool>(fuzz);
166424ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (useMatrix) {
166524ac42b373d9202a89538a1873df9275870c7632Hal Canary                    fuzz->next(&matrix);
166624ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
16671e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
16681e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint_text(fuzz, &paint);
16695395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz_paint_text_encoding(fuzz, &paint);
16705395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
167124ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkPath path;
1672ce540eae37a4e6aab8e888991e4d40c83a93f427Hal Canary                fuzz_path(fuzz, &path, 20);
1673671e442fccaacf57b6922324e8160173a2919608Hal Canary                canvas->drawTextOnPath(text.begin(), SkToSizeT(text.count()), path,
167424ac42b373d9202a89538a1873df9275870c7632Hal Canary                                       useMatrix ? &matrix : nullptr, paint);
167524ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
167624ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
167724ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 50: {
16781e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
16791e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint_text(fuzz, &paint);
16805395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz_paint_text_encoding(fuzz, &paint);
16815395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkTDArray<uint8_t> text = make_fuzz_text(fuzz, paint);
16825395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkRSXform rSXform[kMaxGlyphCount];
16835395c598dbc3fc85b45a18752867aea65643f147Hal Canary                int glyphCount = paint.countText(text.begin(), SkToSizeT(text.count()));
16845395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkASSERT(glyphCount <= kMaxGlyphCount);
16855395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->nextN(rSXform, glyphCount);
16865395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkRect cullRect;
16875395c598dbc3fc85b45a18752867aea65643f147Hal Canary                bool useCullRect;
16885395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->next(&useCullRect);
16895395c598dbc3fc85b45a18752867aea65643f147Hal Canary                if (useCullRect) {
16905395c598dbc3fc85b45a18752867aea65643f147Hal Canary                    fuzz->next(&cullRect);
16915395c598dbc3fc85b45a18752867aea65643f147Hal Canary                }
16925395c598dbc3fc85b45a18752867aea65643f147Hal Canary                canvas->drawTextRSXform(text.begin(), SkToSizeT(text.count()), rSXform,
16935395c598dbc3fc85b45a18752867aea65643f147Hal Canary                                        useCullRect ? &cullRect : nullptr, paint);
169424ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
169524ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
169624ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 51: {
16975395c598dbc3fc85b45a18752867aea65643f147Hal Canary                sk_sp<SkTextBlob> blob = make_fuzz_textblob(fuzz);
16981e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
16995395c598dbc3fc85b45a18752867aea65643f147Hal Canary                SkScalar x, y;
17005395c598dbc3fc85b45a18752867aea65643f147Hal Canary                fuzz->next(&x, &y);
17015395c598dbc3fc85b45a18752867aea65643f147Hal Canary                canvas->drawTextBlob(blob, x, y, paint);
170224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
170324ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
170424ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 52: {
170524ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool usePaint, useMatrix;
170624ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&usePaint, &useMatrix);
170724ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (usePaint) {
17081e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                    fuzz_paint(fuzz, &paint, depth - 1);
170924ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
171024ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (useMatrix) {
171124ac42b373d9202a89538a1873df9275870c7632Hal Canary                    fuzz->next(&matrix);
171224ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
17131e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                auto pic = make_fuzz_picture(fuzz, depth - 1);
171424ac42b373d9202a89538a1873df9275870c7632Hal Canary                canvas->drawPicture(pic, useMatrix ? &matrix : nullptr,
171524ac42b373d9202a89538a1873df9275870c7632Hal Canary                                    usePaint ? &paint : nullptr);
171624ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
171724ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
171824ac42b373d9202a89538a1873df9275870c7632Hal Canary            case 53: {
17191e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                fuzz_paint(fuzz, &paint, depth - 1);
172024ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkCanvas::VertexMode vertexMode;
17215af600e42c5660d01e209d5634c15352202368b8Hal Canary                SkBlendMode blendMode;
1722f7005200725f1a96c7174be3e9a3175f9aa19151Hal Canary                fuzz_enum_range(fuzz, &vertexMode, 0, SkCanvas::kTriangleFan_VertexMode);
17235af600e42c5660d01e209d5634c15352202368b8Hal Canary                fuzz->next(&blendMode);
172424ac42b373d9202a89538a1873df9275870c7632Hal Canary                constexpr int kMaxCount = 100;
172524ac42b373d9202a89538a1873df9275870c7632Hal Canary                int vertexCount;
172624ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkPoint vertices[kMaxCount];
172724ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkPoint texs[kMaxCount];
172824ac42b373d9202a89538a1873df9275870c7632Hal Canary                SkColor colors[kMaxCount];
172924ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextRange(&vertexCount, 3, kMaxCount);
173024ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->nextN(vertices, vertexCount);
173124ac42b373d9202a89538a1873df9275870c7632Hal Canary                bool useTexs, useColors;
173224ac42b373d9202a89538a1873df9275870c7632Hal Canary                fuzz->next(&useTexs, &useColors);
173324ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (useTexs) {
173424ac42b373d9202a89538a1873df9275870c7632Hal Canary                    fuzz->nextN(texs, vertexCount);
173524ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
173624ac42b373d9202a89538a1873df9275870c7632Hal Canary                if (useColors) {
173724ac42b373d9202a89538a1873df9275870c7632Hal Canary                    fuzz->nextN(colors, vertexCount);
173824ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
173924ac42b373d9202a89538a1873df9275870c7632Hal Canary                int indexCount = 0;
174068b9b57638d3c27587c21aefef7c36c4ed4e78e5Hal Canary                uint16_t indices[kMaxCount * 2];
17411e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                if (make_fuzz_t<bool>(fuzz)) {
174268b9b57638d3c27587c21aefef7c36c4ed4e78e5Hal Canary                    fuzz->nextRange(&indexCount, vertexCount, vertexCount + kMaxCount);
174368b9b57638d3c27587c21aefef7c36c4ed4e78e5Hal Canary                    for (int i = 0; i < indexCount; ++i) {
174468b9b57638d3c27587c21aefef7c36c4ed4e78e5Hal Canary                        fuzz->nextRange(&indices[i], 0, vertexCount - 1);
174568b9b57638d3c27587c21aefef7c36c4ed4e78e5Hal Canary                    }
174624ac42b373d9202a89538a1873df9275870c7632Hal Canary                }
17471e0138b58287c086a3085cd2b4640c713d5c9653Hal Canary                if (make_fuzz_t<bool>(fuzz)) {
17485af600e42c5660d01e209d5634c15352202368b8Hal Canary                    canvas->drawVertices(vertexMode, vertexCount, vertices,
17495af600e42c5660d01e209d5634c15352202368b8Hal Canary                                         useTexs ? texs : nullptr, useColors ? colors : nullptr,
17505af600e42c5660d01e209d5634c15352202368b8Hal Canary                                         blendMode, indexCount > 0 ? indices : nullptr, indexCount,
17515af600e42c5660d01e209d5634c15352202368b8Hal Canary                                         paint);
17525af600e42c5660d01e209d5634c15352202368b8Hal Canary                } else {
175397eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                    canvas->drawVertices(SkVertices::MakeCopy(vertexMode, vertexCount, vertices,
175497eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                                              useTexs ? texs : nullptr,
175597eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                                              useColors ? colors : nullptr,
175697eb4feb112967ba7fcb00d6995adda1002873c2Mike Reed                                                              indexCount, indices),
17575fa6645dbe4f56a51ce0f59c13c99afb12ff3f5cMike Reed                                         blendMode, paint);
17585af600e42c5660d01e209d5634c15352202368b8Hal Canary                }
175924ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
176024ac42b373d9202a89538a1873df9275870c7632Hal Canary            }
176124ac42b373d9202a89538a1873df9275870c7632Hal Canary            default:
176224ac42b373d9202a89538a1873df9275870c7632Hal Canary                break;
176324ac42b373d9202a89538a1873df9275870c7632Hal Canary        }
176424ac42b373d9202a89538a1873df9275870c7632Hal Canary    }
176524ac42b373d9202a89538a1873df9275870c7632Hal Canary}
176624ac42b373d9202a89538a1873df9275870c7632Hal Canary
17671e0138b58287c086a3085cd2b4640c713d5c9653Hal Canarystatic sk_sp<SkPicture> make_fuzz_picture(Fuzz* fuzz, int depth) {
176824ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkScalar w, h;
176924ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz->next(&w, &h);
177024ac42b373d9202a89538a1873df9275870c7632Hal Canary    SkPictureRecorder pictureRecorder;
177124ac42b373d9202a89538a1873df9275870c7632Hal Canary    fuzz_canvas(fuzz, pictureRecorder.beginRecording(w, h), depth - 1);
177224ac42b373d9202a89538a1873df9275870c7632Hal Canary    return pictureRecorder.finishRecordingAsPicture();
177324ac42b373d9202a89538a1873df9275870c7632Hal Canary}
177424ac42b373d9202a89538a1873df9275870c7632Hal Canary
17751ac8fd25381a043681a24dc3171189db535c587dKevin LubickDEF_FUZZ(NullCanvas, fuzz) {
17761ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    fuzz_canvas(fuzz, SkMakeNullCanvas().get());
17771ac8fd25381a043681a24dc3171189db535c587dKevin Lubick}
17781ac8fd25381a043681a24dc3171189db535c587dKevin Lubick
177944801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary// 8.5x11 letter paper at 72ppi.
178044801cac9a7a83711e1b04b14e90364e02a6de49Hal Canaryconstexpr SkISize kCanvasSize = {612, 792};
178144801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary
17821ac8fd25381a043681a24dc3171189db535c587dKevin LubickDEF_FUZZ(RasterN32Canvas, fuzz) {
178344801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary    auto surface = SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height());
178444801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary    SkASSERT(surface && surface->getCanvas());
178544801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary    fuzz_canvas(fuzz, surface->getCanvas());
178644801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary}
178744801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary
178844801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary#if SK_SUPPORT_GPU
17895aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canarystatic void fuzz_ganesh(Fuzz* fuzz, GrContext* context) {
17905aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary    SkASSERT(context);
17915aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary    auto surface = SkSurface::MakeRenderTarget(
17925aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary            context,
17935aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary            SkBudgeted::kNo,
17945aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary            SkImageInfo::Make(kCanvasSize.width(), kCanvasSize.height(), kRGBA_8888_SkColorType, kPremul_SkAlphaType));
17955aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary    SkASSERT(surface && surface->getCanvas());
17965aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary    fuzz_canvas(fuzz, surface->getCanvas());
17975aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary}
17985aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary
179944801cac9a7a83711e1b04b14e90364e02a6de49Hal CanaryDEF_FUZZ(NativeGLCanvas, fuzz) {
18006405e71279e99731f89db69325c6763ec62a98e1Brian Salomon    GrContext* context = sk_gpu_test::GrContextFactory().get(
18016405e71279e99731f89db69325c6763ec62a98e1Brian Salomon            sk_gpu_test::GrContextFactory::kGL_ContextType);
18026405e71279e99731f89db69325c6763ec62a98e1Brian Salomon    if (!context) {
18036405e71279e99731f89db69325c6763ec62a98e1Brian Salomon        context = sk_gpu_test::GrContextFactory().get(
18046405e71279e99731f89db69325c6763ec62a98e1Brian Salomon                sk_gpu_test::GrContextFactory::kGLES_ContextType);
18056405e71279e99731f89db69325c6763ec62a98e1Brian Salomon    }
18065aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary    fuzz_ganesh(fuzz, context);
18075aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary}
18085aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary
18095aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal CanaryDEF_FUZZ(NullGLCanvas, fuzz) {
18105aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary    fuzz_ganesh(fuzz, sk_gpu_test::GrContextFactory().get(
18115aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary            sk_gpu_test::GrContextFactory::kNullGL_ContextType));
18125aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary}
18135aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary
18145aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal CanaryDEF_FUZZ(DebugGLCanvas, fuzz) {
18155aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary    fuzz_ganesh(fuzz, sk_gpu_test::GrContextFactory().get(
18165aa9158a24bc0bd27db7d740e4ec07f6aa64f060Hal Canary            sk_gpu_test::GrContextFactory::kDebugGL_ContextType));
181724ac42b373d9202a89538a1873df9275870c7632Hal Canary}
181844801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary#endif
181924ac42b373d9202a89538a1873df9275870c7632Hal Canary
18201ac8fd25381a043681a24dc3171189db535c587dKevin LubickDEF_FUZZ(PDFCanvas, fuzz) {
18211ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    struct final : public SkWStream {
18221ac8fd25381a043681a24dc3171189db535c587dKevin Lubick        bool write(const void*, size_t n) override { fN += n; return true; }
18231ac8fd25381a043681a24dc3171189db535c587dKevin Lubick        size_t bytesWritten() const override { return fN; }
18241ac8fd25381a043681a24dc3171189db535c587dKevin Lubick        size_t fN = 0;
18251ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    } stream;
18261ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    auto doc = SkDocument::MakePDF(&stream);
182744801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary    fuzz_canvas(fuzz, doc->beginPage(SkIntToScalar(kCanvasSize.width()),
182844801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary                                     SkIntToScalar(kCanvasSize.height())));
18291ac8fd25381a043681a24dc3171189db535c587dKevin Lubick}
18301ac8fd25381a043681a24dc3171189db535c587dKevin Lubick
18311ac8fd25381a043681a24dc3171189db535c587dKevin Lubick// not a "real" thing to fuzz, used to debug errors found while fuzzing.
18321ac8fd25381a043681a24dc3171189db535c587dKevin LubickDEF_FUZZ(_DumpCanvas, fuzz) {
183344801cac9a7a83711e1b04b14e90364e02a6de49Hal Canary    SkDebugCanvas debugCanvas(kCanvasSize.width(), kCanvasSize.height());
18341ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    fuzz_canvas(fuzz, &debugCanvas);
18351ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    std::unique_ptr<SkCanvas> nullCanvas = SkMakeNullCanvas();
18361ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    UrlDataManager dataManager(SkString("data"));
18371ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    Json::Value json = debugCanvas.toJSON(dataManager, debugCanvas.getSize(), nullCanvas.get());
18381ac8fd25381a043681a24dc3171189db535c587dKevin Lubick    Json::StyledStreamWriter("  ").write(std::cout, json);
18391ac8fd25381a043681a24dc3171189db535c587dKevin Lubick}
1840