in fuzz/FuzzCanvas.cpp [994:1498]
static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) {
if (!fuzz || !canvas || depth <= 0) {
return;
}
SkAutoCanvasRestore autoCanvasRestore(canvas, false);
unsigned N;
fuzz->nextRange(&N, 0, 2000);
for (unsigned loop = 0; loop < N; ++loop) {
if (fuzz->exhausted()) {
return;
}
SkPaint paint;
SkFont font = ToolUtils::DefaultFont();
unsigned drawCommand;
fuzz->nextRange(&drawCommand, 0, 62);
switch (drawCommand) {
case 0:
#if defined(SK_GANESH)
if (auto dContext = GrAsDirectContext(canvas->recordingContext())) {
dContext->flushAndSubmit();
}
#endif
break;
case 1:
canvas->save();
break;
case 2: {
SkRect bounds;
fuzz->next(&bounds);
fuzz_paint(fuzz, &paint, depth - 1);
canvas->saveLayer(&bounds, &paint);
break;
}
case 3: {
SkRect bounds;
fuzz->next(&bounds);
canvas->saveLayer(&bounds, nullptr);
break;
}
case 4:
fuzz_paint(fuzz, &paint, depth - 1);
canvas->saveLayer(nullptr, &paint);
break;
case 5:
canvas->saveLayer(nullptr, nullptr);
break;
case 6: {
uint8_t alpha;
fuzz->next(&alpha);
canvas->saveLayerAlpha(nullptr, (U8CPU)alpha);
break;
}
case 7: {
SkRect bounds;
uint8_t alpha;
fuzz->next(&bounds, &alpha);
canvas->saveLayerAlpha(&bounds, (U8CPU)alpha);
break;
}
case 8: {
SkCanvas::SaveLayerRec saveLayerRec;
SkRect bounds;
if (make_fuzz_t<bool>(fuzz)) {
fuzz->next(&bounds);
saveLayerRec.fBounds = &bounds;
}
if (make_fuzz_t<bool>(fuzz)) {
fuzz_paint(fuzz, &paint, depth - 1);
saveLayerRec.fPaint = &paint;
}
sk_sp<SkImageFilter> imageFilter;
if (make_fuzz_t<bool>(fuzz)) {
imageFilter = make_fuzz_imageFilter(fuzz, depth - 1);
saveLayerRec.fBackdrop = imageFilter.get();
}
// _DumpCanvas can't handle this.
// if (make_fuzz_t<bool>(fuzz)) {
// saveLayerRec.fSaveLayerFlags |= SkCanvas::kPreserveLCDText_SaveLayerFlag;
// }
canvas->saveLayer(saveLayerRec);
break;
}
case 9:
canvas->restore();
break;
case 10: {
int saveCount;
fuzz->next(&saveCount);
canvas->restoreToCount(saveCount);
break;
}
case 11: {
SkScalar x, y;
fuzz->next(&x, &y);
canvas->translate(x, y);
break;
}
case 12: {
SkScalar x, y;
fuzz->next(&x, &y);
canvas->scale(x, y);
break;
}
case 13: {
SkScalar v;
fuzz->next(&v);
canvas->rotate(v);
break;
}
case 14: {
SkScalar x, y, v;
fuzz->next(&x, &y, &v);
canvas->rotate(v, x, y);
break;
}
case 15: {
SkScalar x, y;
fuzz->next(&x, &y);
canvas->skew(x, y);
break;
}
case 16: {
SkMatrix mat;
FuzzNiceMatrix(fuzz, &mat);
canvas->concat(mat);
break;
}
case 17: {
SkMatrix mat;
FuzzNiceMatrix(fuzz, &mat);
canvas->setMatrix(mat);
break;
}
case 18:
canvas->resetMatrix();
break;
case 19: {
SkRect r;
int op;
bool doAntiAlias;
fuzz->next(&r, &doAntiAlias);
fuzz->nextRange(&op, 0, 1);
r.sort();
canvas->clipRect(r, (SkClipOp)op, doAntiAlias);
break;
}
case 20: {
SkRRect rr;
int op;
bool doAntiAlias;
FuzzNiceRRect(fuzz, &rr);
fuzz->next(&doAntiAlias);
fuzz->nextRange(&op, 0, 1);
canvas->clipRRect(rr, (SkClipOp)op, doAntiAlias);
break;
}
case 21: {
SkPath path;
FuzzNicePath(fuzz, &path, 30);
int op;
bool doAntiAlias;
fuzz->next(&doAntiAlias);
fuzz->nextRange(&op, 0, 1);
canvas->clipPath(path, (SkClipOp)op, doAntiAlias);
break;
}
case 22: {
SkRegion region;
int op;
fuzz->next(®ion);
fuzz->nextRange(&op, 0, 1);
canvas->clipRegion(region, (SkClipOp)op);
break;
}
case 23:
fuzz_paint(fuzz, &paint, depth - 1);
canvas->drawPaint(paint);
break;
case 24: {
fuzz_paint(fuzz, &paint, depth - 1);
SkCanvas::PointMode pointMode;
fuzz->nextRange(&pointMode,
SkCanvas::kPoints_PointMode, SkCanvas::kPolygon_PointMode);
size_t count;
constexpr int kMaxCount = 30;
fuzz->nextRange(&count, 0, kMaxCount);
SkPoint pts[kMaxCount];
fuzz->nextN(pts, count);
canvas->drawPoints(pointMode, count, pts, paint);
break;
}
case 25: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRect r;
fuzz->next(&r);
if (!r.isFinite()) {
break;
}
canvas->drawRect(r, paint);
break;
}
case 26: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRegion region;
fuzz->next(®ion);
canvas->drawRegion(region, paint);
break;
}
case 27: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRect r;
fuzz->next(&r);
if (!r.isFinite()) {
break;
}
canvas->drawOval(r, paint);
break;
}
case 28: break; // must have deleted this some time earlier
case 29: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRRect rr;
FuzzNiceRRect(fuzz, &rr);
canvas->drawRRect(rr, paint);
break;
}
case 30: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRRect orr, irr;
FuzzNiceRRect(fuzz, &orr);
FuzzNiceRRect(fuzz, &irr);
if (orr.getBounds().contains(irr.getBounds())) {
canvas->drawDRRect(orr, irr, paint);
}
break;
}
case 31: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRect r;
SkScalar start, sweep;
bool useCenter;
fuzz->next(&r, &start, &sweep, &useCenter);
canvas->drawArc(r, start, sweep, useCenter, paint);
break;
}
case 32: {
fuzz_paint(fuzz, &paint, depth - 1);
SkPath path;
FuzzNicePath(fuzz, &path, 60);
canvas->drawPath(path, paint);
break;
}
case 33: {
sk_sp<SkImage> img = make_fuzz_image(fuzz);
SkScalar left, top;
bool usePaint;
fuzz->next(&left, &top, &usePaint);
if (usePaint) {
fuzz_paint(fuzz, &paint, depth - 1);
}
canvas->drawImage(img.get(), left, top, SkSamplingOptions(),
usePaint ? &paint : nullptr);
break;
}
case 35: {
auto img = make_fuzz_image(fuzz);
SkIRect src;
SkRect dst;
bool usePaint;
fuzz->next(&src, &dst, &usePaint);
if (usePaint) {
fuzz_paint(fuzz, &paint, depth - 1);
}
SkCanvas::SrcRectConstraint constraint =
make_fuzz_t<bool>(fuzz) ? SkCanvas::kStrict_SrcRectConstraint
: SkCanvas::kFast_SrcRectConstraint;
canvas->drawImageRect(img.get(), SkRect::Make(src), dst, SkSamplingOptions(),
usePaint ? &paint : nullptr, constraint);
break;
}
case 37: {
auto img = make_fuzz_image(fuzz);
SkIRect center;
SkRect dst;
bool usePaint;
fuzz->next(&usePaint);
if (usePaint) {
fuzz_paint(fuzz, &paint, depth - 1);
}
if (make_fuzz_t<bool>(fuzz)) {
fuzz->next(¢er);
} else { // Make valid center, see SkLatticeIter::Valid().
fuzz->nextRange(¢er.fLeft, 0, img->width() - 1);
fuzz->nextRange(¢er.fTop, 0, img->height() - 1);
fuzz->nextRange(¢er.fRight, center.fLeft + 1, img->width());
fuzz->nextRange(¢er.fBottom, center.fTop + 1, img->height());
}
fuzz->next(&dst);
canvas->drawImageNine(img.get(), center, dst, SkFilterMode::kNearest,
usePaint ? &paint : nullptr);
break;
}
case 44: {
auto img = make_fuzz_image(fuzz);
bool usePaint;
SkRect dst;
fuzz->next(&usePaint, &dst);
if (usePaint) {
fuzz_paint(fuzz, &paint, depth - 1);
}
constexpr int kMax = 6;
int xDivs[kMax], yDivs[kMax];
SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr, nullptr};
fuzz->nextRange(&lattice.fXCount, 2, kMax);
fuzz->nextRange(&lattice.fYCount, 2, kMax);
fuzz->nextN(xDivs, lattice.fXCount);
fuzz->nextN(yDivs, lattice.fYCount);
canvas->drawImageLattice(img.get(), lattice, dst, SkFilterMode::kLinear,
usePaint ? &paint : nullptr);
break;
}
case 45: {
fuzz_paint(fuzz, &paint, depth - 1);
font = fuzz_font(fuzz);
SkTextEncoding encoding = fuzz_paint_text_encoding(fuzz);
SkScalar x, y;
fuzz->next(&x, &y);
SkTDArray<uint8_t> text = make_fuzz_text(fuzz, font, encoding);
canvas->drawSimpleText(text.begin(), SkToSizeT(text.size()), encoding, x, y,
font, paint);
break;
}
case 46: {
// was drawPosText
break;
}
case 47: {
// was drawPosTextH
break;
}
case 48: {
// was drawtextonpath
break;
}
case 49: {
// was drawtextonpath
break;
}
case 50: {
// was drawTextRSXform
break;
}
case 51: {
sk_sp<SkTextBlob> blob = make_fuzz_textblob(fuzz);
fuzz_paint(fuzz, &paint, depth - 1);
SkScalar x, y;
fuzz->next(&x, &y);
canvas->drawTextBlob(blob, x, y, paint);
break;
}
case 52: {
SkMatrix matrix;
bool usePaint, useMatrix;
fuzz->next(&usePaint, &useMatrix);
if (usePaint) {
fuzz_paint(fuzz, &paint, depth - 1);
}
if (useMatrix) {
FuzzNiceMatrix(fuzz, &matrix);
}
auto pic = make_fuzz_picture(fuzz, depth - 1);
canvas->drawPicture(pic, useMatrix ? &matrix : nullptr,
usePaint ? &paint : nullptr);
break;
}
case 53: {
fuzz_paint(fuzz, &paint, depth - 1);
SkVertices::VertexMode vertexMode;
SkBlendMode blendMode;
fuzz->nextRange(&vertexMode, 0, SkVertices::kTriangleFan_VertexMode);
fuzz->nextRange(&blendMode, 0, SkBlendMode::kLastMode);
constexpr int kMaxCount = 100;
int vertexCount;
SkPoint vertices[kMaxCount];
SkPoint texs[kMaxCount];
SkColor colors[kMaxCount];
fuzz->nextRange(&vertexCount, 3, kMaxCount);
fuzz->nextN(vertices, vertexCount);
bool useTexs, useColors;
fuzz->next(&useTexs, &useColors);
if (useTexs) {
fuzz->nextN(texs, vertexCount);
}
if (useColors) {
fuzz->nextN(colors, vertexCount);
}
int indexCount = 0;
uint16_t indices[kMaxCount * 2];
if (make_fuzz_t<bool>(fuzz)) {
fuzz->nextRange(&indexCount, vertexCount, vertexCount + kMaxCount);
for (int index = 0; index < indexCount; ++index) {
fuzz->nextRange(&indices[index], 0, vertexCount - 1);
}
}
canvas->drawVertices(SkVertices::MakeCopy(vertexMode, vertexCount, vertices,
useTexs ? texs : nullptr,
useColors ? colors : nullptr,
indexCount, indices),
blendMode, paint);
break;
}
case 54: {
SkColor color;
SkBlendMode blendMode;
fuzz->nextRange(&blendMode, 0, SkBlendMode::kSrcOver);
fuzz->next(&color);
canvas->drawColor(color, blendMode);
break;
}
case 55: {
SkColor4f color;
SkBlendMode blendMode;
float R, G, B, Alpha;
fuzz->nextRange(&blendMode, 0, SkBlendMode::kSrcOver);
fuzz->nextRange(&R, -1, 2);
fuzz->nextRange(&G, -1, 2);
fuzz->nextRange(&B, -1, 2);
fuzz->nextRange(&Alpha, 0, 1);
color = {R, G, B, Alpha};
canvas->drawColor(color, blendMode);
break;
}
case 56: {
fuzz_paint(fuzz, &paint, depth - 1);
SkPoint p0, p1;
fuzz->next(&p0, &p1);
canvas->drawLine(p0, p1, paint);
break;
}
case 57: {
fuzz_paint(fuzz, &paint, depth - 1);
SkIRect r;
fuzz->next(&r);
canvas->drawIRect(r, paint);
break;
}
case 58: {
fuzz_paint(fuzz, &paint, depth - 1);
SkScalar radius;
SkPoint center;
fuzz->next(&radius, ¢er);
canvas->drawCircle(center, radius, paint);
break;
}
case 59: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRect oval;
SkScalar startAngle, sweepAngle;
bool useCenter;
fuzz->next(&oval, &startAngle, &sweepAngle, &useCenter);
canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
break;
}
case 60: {
fuzz_paint(fuzz, &paint, depth - 1);
SkRect rect;
SkScalar rx, ry;
fuzz->next(&rect, &rx, &ry);
canvas->drawRoundRect(rect, rx, ry, paint);
break;
}
case 61: {
fuzz_paint(fuzz, &paint, depth - 1);
font = fuzz_font(fuzz);
std::string str = make_fuzz_string(fuzz);
SkScalar x, y;
fuzz->next(&x, &y);
canvas->drawString(str.c_str(), x, y, font, paint);
break;
}
case 62: {
fuzz_paint(fuzz, &paint, depth - 1);
SkPoint cubics[12];
SkColor colors[4];
SkPoint texCoords[4];
bool useTexCoords;
fuzz->nextN(cubics, 12);
fuzz->nextN(colors, 4);
fuzz->next(&useTexCoords);
if (useTexCoords) {
fuzz->nextN(texCoords, 4);
}
SkBlendMode mode;
fuzz->nextEnum(&mode, SkBlendMode::kLastMode);
canvas->drawPatch(cubics, colors, useTexCoords ? texCoords : nullptr
, mode, paint);
break;
}
default:
SkASSERT(false);
break;
}
}
}