| Index: src/core/SkPicturePlayback.cpp
|
| diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
|
| index a246a306e6b1f1ded8714a90b0d0be142c92ce9e..bede60111ed07da9da2ba51f97c816de2c19c8e8 100644
|
| --- a/src/core/SkPicturePlayback.cpp
|
| +++ b/src/core/SkPicturePlayback.cpp
|
| @@ -126,6 +126,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| uint32_t size,
|
| SkCanvas* canvas,
|
| const SkMatrix& initialMatrix) {
|
| +#define BREAK_ON_READ_ERROR(r) if (!r->isValid()) { break; }
|
| +
|
| switch (op) {
|
| case NOOP: {
|
| SkASSERT(size >= 4);
|
| @@ -137,6 +139,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| SkCanvas::ClipOp clipOp = ClipParams_unpackRegionOp(packed);
|
| bool doAA = ClipParams_unpackDoAA(packed);
|
| size_t offsetToRestore = reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
|
| canvas->clipPath(path, clipOp, doAA);
|
| if (canvas->isClipEmpty() && offsetToRestore) {
|
| @@ -149,6 +153,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| uint32_t packed = reader->readInt();
|
| SkCanvas::ClipOp clipOp = ClipParams_unpackRegionOp(packed);
|
| size_t offsetToRestore = reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
|
| canvas->clipRegion(region, clipOp);
|
| if (canvas->isClipEmpty() && offsetToRestore) {
|
| @@ -162,6 +168,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| SkCanvas::ClipOp clipOp = ClipParams_unpackRegionOp(packed);
|
| bool doAA = ClipParams_unpackDoAA(packed);
|
| size_t offsetToRestore = reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
|
| canvas->clipRect(rect, clipOp, doAA);
|
| if (canvas->isClipEmpty() && offsetToRestore) {
|
| @@ -175,6 +183,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| SkCanvas::ClipOp clipOp = ClipParams_unpackRegionOp(packed);
|
| bool doAA = ClipParams_unpackDoAA(packed);
|
| size_t offsetToRestore = reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
|
| canvas->clipRRect(rrect, clipOp, doAA);
|
| if (canvas->isClipEmpty() && offsetToRestore) {
|
| @@ -186,6 +196,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| case CONCAT: {
|
| SkMatrix matrix;
|
| reader->readMatrix(&matrix);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->concat(matrix);
|
| break;
|
| }
|
| @@ -194,7 +206,10 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| reader->readRect(&rect);
|
| SkString key;
|
| reader->readString(&key);
|
| - canvas->drawAnnotation(rect, key.c_str(), reader->readByteArrayAsData().get());
|
| + sk_sp<SkData> data = reader->readByteArrayAsData();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| + canvas->drawAnnotation(rect, key.c_str(), data.get());
|
| } break;
|
| case DRAW_ARC: {
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| @@ -203,6 +218,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| SkScalar startAngle = reader->readScalar();
|
| SkScalar sweepAngle = reader->readScalar();
|
| int useCenter = reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), *paint);
|
| }
|
| @@ -224,6 +241,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| if (flags & DRAW_ATLAS_HAS_CULL) {
|
| cull = (const SkRect*)reader->skip(sizeof(SkRect));
|
| }
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
|
| } break;
|
| case DRAW_BITMAP: {
|
| @@ -231,6 +250,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkImage* image = fPictureData->getBitmapAsImage(reader);
|
| SkPoint loc;
|
| reader->readPoint(&loc);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawImage(image, loc.fX, loc.fY, paint);
|
| } break;
|
| case DRAW_BITMAP_RECT: {
|
| @@ -241,6 +262,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| SkRect dst;
|
| reader->readRect(&dst); // required
|
| SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (src) {
|
| canvas->drawImageRect(image, *src, dst, paint, constraint);
|
| } else {
|
| @@ -252,6 +275,7 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkImage* image = fPictureData->getBitmapAsImage(reader);
|
| SkMatrix matrix;
|
| reader->readMatrix(&matrix);
|
| + BREAK_ON_READ_ERROR(reader);
|
|
|
| SkAutoCanvasRestore acr(canvas, true);
|
| canvas->concat(matrix);
|
| @@ -264,24 +288,34 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| reader->readIRect(&src);
|
| SkRect dst;
|
| reader->readRect(&dst);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawImageNine(image, src, dst, paint);
|
| } break;
|
| - case DRAW_CLEAR:
|
| - canvas->clear(reader->readInt());
|
| - break;
|
| + case DRAW_CLEAR: {
|
| + auto c = reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| + canvas->clear(c);
|
| + } break;
|
| case DRAW_DATA: {
|
| // This opcode is now dead, just need to skip it for backwards compatibility
|
| size_t length = reader->readInt();
|
| (void)reader->skip(length);
|
| // skip handles padding the read out to a multiple of 4
|
| } break;
|
| - case DRAW_DRAWABLE:
|
| - canvas->drawDrawable(fPictureData->getDrawable(reader));
|
| - break;
|
| + case DRAW_DRAWABLE: {
|
| + auto* d = fPictureData->getDrawable(reader);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| + canvas->drawDrawable(d);
|
| + } break;
|
| case DRAW_DRAWABLE_MATRIX: {
|
| SkMatrix matrix;
|
| reader->readMatrix(&matrix);
|
| SkDrawable* drawable = fPictureData->getDrawable(reader);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawDrawable(drawable, &matrix);
|
| } break;
|
| case DRAW_DRRECT: {
|
| @@ -289,6 +323,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| SkRRect outer, inner;
|
| reader->readRRect(&outer);
|
| reader->readRRect(&inner);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawDRRect(outer, inner, *paint);
|
| }
|
| @@ -314,6 +350,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkImage* image = fPictureData->getImage(reader);
|
| SkPoint loc;
|
| reader->readPoint(&loc);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawImage(image, loc.fX, loc.fY, paint);
|
| } break;
|
| case DRAW_IMAGE_LATTICE: {
|
| @@ -332,6 +370,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| lattice.fBounds = &src;
|
| SkRect dst;
|
| reader->readRect(&dst);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawImageLattice(image, lattice, dst, paint);
|
| } break;
|
| case DRAW_IMAGE_NINE: {
|
| @@ -341,6 +381,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| reader->readIRect(¢er);
|
| SkRect dst;
|
| reader->readRect(&dst);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawImageNine(image, center, dst, paint);
|
| } break;
|
| case DRAW_IMAGE_RECT_STRICT:
|
| @@ -357,18 +399,24 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| // newer op-code stores the constraint explicitly
|
| constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
|
| }
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->legacy_drawImageRect(image, src, dst, paint, constraint);
|
| } break;
|
| case DRAW_OVAL: {
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| SkRect rect;
|
| reader->readRect(&rect);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawOval(rect, *paint);
|
| }
|
| } break;
|
| case DRAW_PAINT: {
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawPaint(*paint);
|
| }
|
| @@ -396,24 +444,34 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| }
|
| xfer = SkXfermode::Make((SkXfermode::Mode)mode);
|
| }
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawPatch(cubics, colors, texCoords, std::move(xfer), *paint);
|
| }
|
| } break;
|
| case DRAW_PATH: {
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| + const auto& path = fPictureData->getPath(reader);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| - canvas->drawPath(fPictureData->getPath(reader), *paint);
|
| + canvas->drawPath(path, *paint);
|
| }
|
| } break;
|
| - case DRAW_PICTURE:
|
| - canvas->drawPicture(fPictureData->getPicture(reader));
|
| - break;
|
| + case DRAW_PICTURE: {
|
| + const auto* pic = fPictureData->getPicture(reader);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| + canvas->drawPicture(pic);
|
| + } break;
|
| case DRAW_PICTURE_MATRIX_PAINT: {
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| SkMatrix matrix;
|
| reader->readMatrix(&matrix);
|
| const SkPicture* pic = fPictureData->getPicture(reader);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->drawPicture(pic, &matrix, paint);
|
| } break;
|
| case DRAW_POINTS: {
|
| @@ -421,6 +479,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt();
|
| size_t count = reader->readInt();
|
| const SkPoint* pts = (const SkPoint*)reader->skip(sizeof(SkPoint)* count);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawPoints(mode, count, pts, *paint);
|
| }
|
| @@ -431,6 +491,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| get_text(reader, &text);
|
| size_t points = reader->readInt();
|
| const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint && text.text()) {
|
| canvas->drawPosText(text.text(), text.length(), pos, *paint);
|
| }
|
| @@ -443,6 +505,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
|
| const SkScalar top = reader->readScalar();
|
| const SkScalar bottom = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| SkRect clip;
|
| canvas->getClipBounds(&clip);
|
| if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
|
| @@ -456,6 +520,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| size_t xCount = reader->readInt();
|
| const SkScalar constY = reader->readScalar();
|
| const SkScalar* xpos = (const SkScalar*)reader->skip(xCount * sizeof(SkScalar));
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint && text.text()) {
|
| canvas->drawPosTextH(text.text(), text.length(), xpos, constY, *paint);
|
| }
|
| @@ -466,6 +532,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| get_text(reader, &text);
|
| size_t xCount = reader->readInt();
|
| const SkScalar* xpos = (const SkScalar*)reader->skip((3 + xCount) * sizeof(SkScalar));
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| const SkScalar top = *xpos++;
|
| const SkScalar bottom = *xpos++;
|
| const SkScalar constY = *xpos++;
|
| @@ -479,6 +547,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| SkRect rect;
|
| reader->readRect(&rect);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawRect(rect, *paint);
|
| }
|
| @@ -487,6 +557,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| SkRegion region;
|
| reader->readRegion(®ion);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawRegion(region, *paint);
|
| }
|
| @@ -495,6 +567,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| SkRRect rrect;
|
| reader->readRRect(&rrect);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawRRect(rrect, *paint);
|
| }
|
| @@ -512,6 +586,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| get_text(reader, &text);
|
| SkScalar x = reader->readScalar();
|
| SkScalar y = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint && text.text()) {
|
| canvas->drawText(text.text(), text.length(), x, y, *paint);
|
| }
|
| @@ -521,6 +597,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkTextBlob* blob = fPictureData->getTextBlob(reader);
|
| SkScalar x = reader->readScalar();
|
| SkScalar y = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawTextBlob(blob, x, y, *paint);
|
| }
|
| @@ -530,6 +608,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| TextContainer text;
|
| get_text(reader, &text);
|
| const SkScalar* ptr = (const SkScalar*)reader->skip(4 * sizeof(SkScalar));
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| // ptr[0] == x
|
| // ptr[1] == y
|
| // ptr[2] == top
|
| @@ -549,6 +629,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkPath& path = fPictureData->getPath(reader);
|
| SkMatrix matrix;
|
| reader->readMatrix(&matrix);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint && text.text()) {
|
| canvas->drawTextOnPath(text.text(), text.length(), path, &matrix, *paint);
|
| }
|
| @@ -564,6 +646,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| if (flags & DRAW_TEXT_RSXFORM_HAS_CULL) {
|
| cull = (const SkRect*)reader->skip(sizeof(SkRect));
|
| }
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (text.text()) {
|
| canvas->drawTextRSXform(text.text(), text.length(), xform, cull, *paint);
|
| }
|
| @@ -596,6 +680,8 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| }
|
| xfer = SkXfermode::Make((SkXfermode::Mode)mode);
|
| }
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| if (paint) {
|
| canvas->drawVertices(vmode, vCount, verts, texs, colors,
|
| xfer, indices, iCount, *paint);
|
| @@ -604,16 +690,13 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| case RESTORE:
|
| canvas->restore();
|
| break;
|
| - case ROTATE:
|
| - canvas->rotate(reader->readScalar());
|
| - break;
|
| + case ROTATE: {
|
| + auto deg = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| + canvas->rotate(deg);
|
| + } break;
|
| case SAVE:
|
| - // SKPs with version < 29 also store a SaveFlags param.
|
| - if (size > 4) {
|
| - if (reader->validate(8 == size)) {
|
| - reader->readInt();
|
| - }
|
| - }
|
| canvas->save();
|
| break;
|
| case SAVE_LAYER_SAVEFLAGS_DEPRECATED: {
|
| @@ -621,13 +704,18 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| const SkRect* boundsPtr = get_rect_ptr(reader, &storage);
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| auto flags = SkCanvas::LegacySaveFlagsToSaveLayerFlags(reader->readInt());
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
|
| } break;
|
| case SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016: {
|
| SkRect storage;
|
| const SkRect* boundsPtr = get_rect_ptr(reader, &storage);
|
| const SkPaint* paint = fPictureData->getPaint(reader);
|
| - canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, reader->readInt()));
|
| + auto flags = reader->readInt();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| + canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
|
| } break;
|
| case SAVE_LAYER_SAVELAYERREC: {
|
| SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0);
|
| @@ -641,42 +729,57 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
|
| rec.fPaint = fPictureData->getPaint(reader);
|
| }
|
| if (flatFlags & SAVELAYERREC_HAS_BACKDROP) {
|
| - const SkPaint* paint = fPictureData->getPaint(reader);
|
| - rec.fBackdrop = paint->getImageFilter();
|
| + if (const auto* paint = fPictureData->getPaint(reader)) {
|
| + rec.fBackdrop = paint->getImageFilter();
|
| + }
|
| }
|
| if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
|
| rec.fSaveLayerFlags = reader->readInt();
|
| }
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->saveLayer(rec);
|
| } break;
|
| case SCALE: {
|
| SkScalar sx = reader->readScalar();
|
| SkScalar sy = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->scale(sx, sy);
|
| } break;
|
| case SET_MATRIX: {
|
| SkMatrix matrix;
|
| reader->readMatrix(&matrix);
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| matrix.postConcat(initialMatrix);
|
| canvas->setMatrix(matrix);
|
| } break;
|
| case SKEW: {
|
| SkScalar sx = reader->readScalar();
|
| SkScalar sy = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->skew(sx, sy);
|
| } break;
|
| case TRANSLATE: {
|
| SkScalar dx = reader->readScalar();
|
| SkScalar dy = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->translate(dx, dy);
|
| } break;
|
| case TRANSLATE_Z: {
|
| #ifdef SK_EXPERIMENTAL_SHADOWING
|
| SkScalar dz = reader->readScalar();
|
| + BREAK_ON_READ_ERROR(reader);
|
| +
|
| canvas->translateZ(dz);
|
| #endif
|
| } break;
|
| default:
|
| SkASSERTF(false, "Unknown draw type: %d", op);
|
| }
|
| +
|
| +#undef BREAK_ON_READ_ERROR
|
| }
|
|
|