LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkPicturePlayback.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 493 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2014 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #include "SkCanvas.h"
       9             : #include "SkPatchUtils.h"
      10             : #include "SkPictureData.h"
      11             : #include "SkPicturePlayback.h"
      12             : #include "SkPictureRecord.h"
      13             : #include "SkReadBuffer.h"
      14             : #include "SkRSXform.h"
      15             : #include "SkTextBlob.h"
      16             : #include "SkTDArray.h"
      17             : #include "SkTypes.h"
      18             : 
      19             : // matches old SkCanvas::SaveFlags
      20             : enum LegacySaveFlags {
      21             :     kHasAlphaLayer_LegacySaveFlags    = 0x04,
      22             :     kClipToLayer_LegacySaveFlags      = 0x10,
      23             : };
      24             : 
      25           0 : SkCanvas::SaveLayerFlags SkCanvas::LegacySaveFlagsToSaveLayerFlags(uint32_t flags) {
      26           0 :     uint32_t layerFlags = 0;
      27             : 
      28           0 :     if (0 == (flags & kClipToLayer_LegacySaveFlags)) {
      29           0 :         layerFlags |= SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag;
      30             :     }
      31           0 :     if (0 == (flags & kHasAlphaLayer_LegacySaveFlags)) {
      32           0 :         layerFlags |= kIsOpaque_SaveLayerFlag;
      33             :     }
      34           0 :     return layerFlags;
      35             : }
      36             : 
      37             : /*
      38             :  * Read the next op code and chunk size from 'reader'. The returned size
      39             :  * is the entire size of the chunk (including the opcode). Thus, the
      40             :  * offset just prior to calling ReadOpAndSize + 'size' is the offset
      41             :  * to the next chunk's op code. This also means that the size of a chunk
      42             :  * with no arguments (just an opcode) will be 4.
      43             :  */
      44           0 : DrawType SkPicturePlayback::ReadOpAndSize(SkReadBuffer* reader, uint32_t* size) {
      45           0 :     uint32_t temp = reader->readInt();
      46             :     uint32_t op;
      47           0 :     if (((uint8_t)temp) == temp) {
      48             :         // old skp file - no size information
      49           0 :         op = temp;
      50           0 :         *size = 0;
      51             :     } else {
      52           0 :         UNPACK_8_24(temp, op, *size);
      53           0 :         if (MASK_24 == *size) {
      54           0 :             *size = reader->readInt();
      55             :         }
      56             :     }
      57           0 :     return (DrawType)op;
      58             : }
      59             : 
      60             : 
      61           0 : static const SkRect* get_rect_ptr(SkReadBuffer* reader, SkRect* storage) {
      62           0 :     if (reader->readBool()) {
      63           0 :         reader->readRect(storage);
      64           0 :         return storage;
      65             :     } else {
      66           0 :         return nullptr;
      67             :     }
      68             : }
      69             : 
      70             : class TextContainer {
      71             : public:
      72           0 :     size_t length() { return fByteLength; }
      73           0 :     const void* text() { return (const void*)fText; }
      74             :     size_t fByteLength;
      75             :     const char* fText;
      76             : };
      77             : 
      78           0 : void get_text(SkReadBuffer* reader, TextContainer* text) {
      79           0 :     size_t length = text->fByteLength = reader->readInt();
      80           0 :     text->fText = (const char*)reader->skip(length);
      81           0 : }
      82             : 
      83           0 : void SkPicturePlayback::draw(SkCanvas* canvas,
      84             :                              SkPicture::AbortCallback* callback,
      85             :                              SkReadBuffer* buffer) {
      86           0 :     AutoResetOpID aroi(this);
      87           0 :     SkASSERT(0 == fCurOffset);
      88             : 
      89           0 :     std::unique_ptr<SkReadBuffer> reader;
      90           0 :     if (buffer) {
      91           0 :         reader.reset(buffer->clone(fPictureData->opData()->bytes(),
      92           0 :                                    fPictureData->opData()->size()));
      93             :     } else {
      94           0 :         reader.reset(new SkReadBuffer(fPictureData->opData()->bytes(),
      95           0 :                                       fPictureData->opData()->size()));
      96             :     }
      97             : 
      98             :     // Record this, so we can concat w/ it if we encounter a setMatrix()
      99           0 :     SkMatrix initialMatrix = canvas->getTotalMatrix();
     100             : 
     101           0 :     SkAutoCanvasRestore acr(canvas, false);
     102             : 
     103           0 :     while (!reader->eof()) {
     104           0 :         if (callback && callback->abort()) {
     105           0 :             return;
     106             :         }
     107             : 
     108           0 :         fCurOffset = reader->offset();
     109             :         uint32_t size;
     110           0 :         DrawType op = ReadOpAndSize(reader.get(), &size);
     111           0 :         if (!reader->validate(op > UNUSED && op <= LAST_DRAWTYPE_ENUM)) {
     112           0 :             return;
     113             :         }
     114             : 
     115           0 :         this->handleOp(reader.get(), op, size, canvas, initialMatrix);
     116             :     }
     117             : 
     118             :     // need to propagate invalid state to the parent reader
     119           0 :     if (buffer) {
     120           0 :         buffer->validate(reader->isValid());
     121             :     }
     122             : }
     123             : 
     124           0 : void SkPicturePlayback::handleOp(SkReadBuffer* reader,
     125             :                                  DrawType op,
     126             :                                  uint32_t size,
     127             :                                  SkCanvas* canvas,
     128             :                                  const SkMatrix& initialMatrix) {
     129             : #define BREAK_ON_READ_ERROR(r) if (!r->isValid()) { break; }
     130             : 
     131           0 :     switch (op) {
     132             :         case NOOP: {
     133           0 :             SkASSERT(size >= 4);
     134           0 :             reader->skip(size - 4);
     135           0 :         } break;
     136             :         case CLIP_PATH: {
     137           0 :             const SkPath& path = fPictureData->getPath(reader); 
     138           0 :             uint32_t packed = reader->readInt(); 
     139           0 :             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
     140           0 :             bool doAA = ClipParams_unpackDoAA(packed);
     141           0 :             size_t offsetToRestore = reader->readInt();
     142           0 :             BREAK_ON_READ_ERROR(reader);
     143             : 
     144           0 :             SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
     145           0 :             canvas->clipPath(path, clipOp, doAA);
     146           0 :             if (canvas->isClipEmpty() && offsetToRestore) {
     147           0 :                 reader->skip(offsetToRestore - reader->offset());
     148             :             }
     149           0 :         } break;
     150             :         case CLIP_REGION: {
     151           0 :             SkRegion region;
     152           0 :             reader->readRegion(&region);
     153           0 :             uint32_t packed = reader->readInt();
     154           0 :             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
     155           0 :             size_t offsetToRestore = reader->readInt();
     156           0 :             BREAK_ON_READ_ERROR(reader);
     157             : 
     158           0 :             SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
     159           0 :             canvas->clipRegion(region, clipOp);
     160           0 :             if (canvas->isClipEmpty() && offsetToRestore) {
     161           0 :                 reader->skip(offsetToRestore - reader->offset());
     162             :             }
     163           0 :         } break;
     164             :         case CLIP_RECT: {
     165             :             SkRect rect;
     166           0 :             reader->readRect(&rect);
     167           0 :             uint32_t packed = reader->readInt();
     168           0 :             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
     169           0 :             bool doAA = ClipParams_unpackDoAA(packed);
     170           0 :             size_t offsetToRestore = reader->readInt();
     171           0 :             BREAK_ON_READ_ERROR(reader);
     172             : 
     173           0 :             SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
     174           0 :             canvas->clipRect(rect, clipOp, doAA);
     175           0 :             if (canvas->isClipEmpty() && offsetToRestore) {
     176           0 :                 reader->skip(offsetToRestore - reader->offset());
     177             :             }
     178           0 :         } break;
     179             :         case CLIP_RRECT: {
     180           0 :             SkRRect rrect;
     181           0 :             reader->readRRect(&rrect);
     182           0 :             uint32_t packed = reader->readInt();
     183           0 :             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
     184           0 :             bool doAA = ClipParams_unpackDoAA(packed);
     185           0 :             size_t offsetToRestore = reader->readInt();
     186           0 :             BREAK_ON_READ_ERROR(reader);
     187             : 
     188           0 :             SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
     189           0 :             canvas->clipRRect(rrect, clipOp, doAA);
     190           0 :             if (canvas->isClipEmpty() && offsetToRestore) {
     191           0 :                 reader->skip(offsetToRestore - reader->offset());
     192             :             }
     193           0 :         } break;
     194           0 :         case PUSH_CULL: break;  // Deprecated, safe to ignore both push and pop.
     195           0 :         case POP_CULL:  break;
     196             :         case CONCAT: {
     197             :             SkMatrix matrix;
     198           0 :             reader->readMatrix(&matrix);
     199           0 :             BREAK_ON_READ_ERROR(reader);
     200             : 
     201           0 :             canvas->concat(matrix);
     202           0 :             break;
     203             :         }
     204             :         case DRAW_ANNOTATION: {
     205             :             SkRect rect;
     206           0 :             reader->readRect(&rect);
     207           0 :             SkString key;
     208           0 :             reader->readString(&key);
     209           0 :             sk_sp<SkData> data = reader->readByteArrayAsData();
     210           0 :             BREAK_ON_READ_ERROR(reader);
     211             : 
     212           0 :             canvas->drawAnnotation(rect, key.c_str(), data.get());
     213           0 :         } break;
     214             :         case DRAW_ARC: {
     215           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     216             :             SkRect rect;
     217           0 :             reader->readRect(&rect);
     218           0 :             SkScalar startAngle = reader->readScalar();
     219           0 :             SkScalar sweepAngle = reader->readScalar();
     220           0 :             int useCenter = reader->readInt();
     221           0 :             BREAK_ON_READ_ERROR(reader);
     222             : 
     223           0 :             if (paint) {
     224           0 :                 canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), *paint);
     225             :             }
     226           0 :         } break;
     227             :         case DRAW_ATLAS: {
     228           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     229           0 :             const SkImage* atlas = fPictureData->getImage(reader);
     230           0 :             const uint32_t flags = reader->readUInt();
     231           0 :             const int count = reader->readUInt();
     232           0 :             const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform));
     233           0 :             const SkRect* tex = (const SkRect*)reader->skip(count * sizeof(SkRect));
     234           0 :             const SkColor* colors = nullptr;
     235           0 :             SkBlendMode mode = SkBlendMode::kDst;
     236           0 :             if (flags & DRAW_ATLAS_HAS_COLORS) {
     237           0 :                 colors = (const SkColor*)reader->skip(count * sizeof(SkColor));
     238           0 :                 mode = (SkBlendMode)reader->readUInt();
     239             :             }
     240           0 :             const SkRect* cull = nullptr;
     241           0 :             if (flags & DRAW_ATLAS_HAS_CULL) {
     242           0 :                 cull = (const SkRect*)reader->skip(sizeof(SkRect));
     243             :             }
     244           0 :             BREAK_ON_READ_ERROR(reader);
     245             : 
     246           0 :             canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
     247           0 :         } break;
     248             :         case DRAW_BITMAP: {
     249           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     250           0 :             const SkImage* image = fPictureData->getBitmapAsImage(reader);
     251             :             SkPoint loc;
     252           0 :             reader->readPoint(&loc);
     253           0 :             BREAK_ON_READ_ERROR(reader);
     254             : 
     255           0 :             canvas->drawImage(image, loc.fX, loc.fY, paint);
     256           0 :         } break;
     257             :         case DRAW_BITMAP_RECT: {
     258           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     259           0 :             const SkImage* image = fPictureData->getBitmapAsImage(reader);
     260             :             SkRect storage;
     261           0 :             const SkRect* src = get_rect_ptr(reader, &storage);   // may be null
     262             :             SkRect dst;
     263           0 :             reader->readRect(&dst);     // required
     264           0 :             SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
     265           0 :             BREAK_ON_READ_ERROR(reader);
     266             : 
     267           0 :             if (src) {
     268           0 :                 canvas->drawImageRect(image, *src, dst, paint, constraint);
     269             :             } else {
     270           0 :                 canvas->drawImageRect(image, dst, paint, constraint);
     271             :             }
     272           0 :         } break;
     273             :         case DRAW_BITMAP_MATRIX: {
     274           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     275           0 :             const SkImage* image = fPictureData->getBitmapAsImage(reader);
     276             :             SkMatrix matrix;
     277           0 :             reader->readMatrix(&matrix);
     278           0 :             BREAK_ON_READ_ERROR(reader);
     279             : 
     280           0 :             SkAutoCanvasRestore acr(canvas, true);
     281           0 :             canvas->concat(matrix);
     282           0 :             canvas->drawImage(image, 0, 0, paint);
     283           0 :         } break;
     284             :         case DRAW_BITMAP_NINE: {
     285           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     286           0 :             const SkImage* image = fPictureData->getBitmapAsImage(reader);
     287             :             SkIRect src;
     288           0 :             reader->readIRect(&src);
     289             :             SkRect dst;
     290           0 :             reader->readRect(&dst);
     291           0 :             BREAK_ON_READ_ERROR(reader);
     292             : 
     293           0 :             canvas->drawImageNine(image, src, dst, paint);
     294           0 :         } break;
     295             :         case DRAW_CLEAR: {
     296           0 :             auto c = reader->readInt();
     297           0 :             BREAK_ON_READ_ERROR(reader);
     298             : 
     299           0 :             canvas->clear(c);
     300           0 :         } break;
     301             :         case DRAW_DATA: {
     302             :             // This opcode is now dead, just need to skip it for backwards compatibility
     303           0 :             size_t length = reader->readInt();
     304           0 :             (void)reader->skip(length);
     305             :             // skip handles padding the read out to a multiple of 4
     306           0 :         } break;
     307             :         case DRAW_DRAWABLE: {
     308           0 :             auto* d = fPictureData->getDrawable(reader);
     309           0 :             BREAK_ON_READ_ERROR(reader);
     310             : 
     311           0 :             canvas->drawDrawable(d);
     312           0 :         } break;
     313             :         case DRAW_DRAWABLE_MATRIX: {
     314             :             SkMatrix matrix;
     315           0 :             reader->readMatrix(&matrix);
     316           0 :             SkDrawable* drawable = fPictureData->getDrawable(reader);
     317           0 :             BREAK_ON_READ_ERROR(reader);
     318             : 
     319           0 :             canvas->drawDrawable(drawable, &matrix);
     320           0 :         } break;
     321             :         case DRAW_DRRECT: {
     322           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     323           0 :             SkRRect outer, inner;
     324           0 :             reader->readRRect(&outer);
     325           0 :             reader->readRRect(&inner);
     326           0 :             BREAK_ON_READ_ERROR(reader);
     327             : 
     328           0 :             if (paint) {
     329           0 :                 canvas->drawDRRect(outer, inner, *paint);
     330             :             }
     331           0 :         } break;
     332             :         case BEGIN_COMMENT_GROUP: {
     333           0 :             SkString tmp;
     334           0 :             reader->readString(&tmp);
     335             :             // deprecated (M44)
     336           0 :             break;
     337             :         }
     338             :         case COMMENT: {
     339           0 :             SkString tmp;
     340           0 :             reader->readString(&tmp);
     341           0 :             reader->readString(&tmp);
     342             :             // deprecated (M44)
     343           0 :             break;
     344             :         }
     345             :         case END_COMMENT_GROUP:
     346             :             // deprecated (M44)
     347           0 :             break;
     348             :         case DRAW_IMAGE: {
     349           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     350           0 :             const SkImage* image = fPictureData->getImage(reader);
     351             :             SkPoint loc;
     352           0 :             reader->readPoint(&loc);
     353           0 :             BREAK_ON_READ_ERROR(reader);
     354             : 
     355           0 :             canvas->drawImage(image, loc.fX, loc.fY, paint);
     356           0 :         } break;
     357             :         case DRAW_IMAGE_LATTICE: {
     358           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     359           0 :             const SkImage* image = fPictureData->getImage(reader);
     360             :             SkCanvas::Lattice lattice;
     361           0 :             lattice.fXCount = reader->readInt();
     362           0 :             lattice.fXDivs = (const int*) reader->skip(lattice.fXCount * sizeof(int32_t));
     363           0 :             lattice.fYCount = reader->readInt();
     364           0 :             lattice.fYDivs = (const int*) reader->skip(lattice.fYCount * sizeof(int32_t));
     365           0 :             int flagCount = reader->readInt();
     366           0 :             lattice.fFlags = (0 == flagCount) ? nullptr : (const SkCanvas::Lattice::Flags*)
     367           0 :                     reader->skip(SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags)));
     368             :             SkIRect src;
     369           0 :             reader->readIRect(&src);
     370           0 :             lattice.fBounds = &src;
     371             :             SkRect dst;
     372           0 :             reader->readRect(&dst);
     373           0 :             BREAK_ON_READ_ERROR(reader);
     374             : 
     375           0 :             canvas->drawImageLattice(image, lattice, dst, paint);
     376           0 :         } break;
     377             :         case DRAW_IMAGE_NINE: {
     378           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     379           0 :             const SkImage* image = fPictureData->getImage(reader);
     380             :             SkIRect center;
     381           0 :             reader->readIRect(&center);
     382             :             SkRect dst;
     383           0 :             reader->readRect(&dst);
     384           0 :             BREAK_ON_READ_ERROR(reader);
     385             : 
     386           0 :             canvas->drawImageNine(image, center, dst, paint);
     387           0 :         } break;
     388             :         case DRAW_IMAGE_RECT_STRICT:
     389             :         case DRAW_IMAGE_RECT: {
     390           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     391           0 :             const SkImage* image = fPictureData->getImage(reader);
     392             :             SkRect storage;
     393           0 :             const SkRect* src = get_rect_ptr(reader, &storage);   // may be null
     394             :             SkRect dst;
     395           0 :             reader->readRect(&dst);     // required
     396             :             // DRAW_IMAGE_RECT_STRICT assumes this constraint, and doesn't store it
     397           0 :             SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
     398           0 :             if (DRAW_IMAGE_RECT == op) {
     399             :                 // newer op-code stores the constraint explicitly
     400           0 :                 constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
     401             :             }
     402           0 :             BREAK_ON_READ_ERROR(reader);
     403             : 
     404           0 :             canvas->legacy_drawImageRect(image, src, dst, paint, constraint);
     405           0 :         } break;
     406             :         case DRAW_OVAL: {
     407           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     408             :             SkRect rect;
     409           0 :             reader->readRect(&rect);
     410           0 :             BREAK_ON_READ_ERROR(reader);
     411             : 
     412           0 :             if (paint) {
     413           0 :                 canvas->drawOval(rect, *paint);
     414             :             }
     415           0 :         } break;
     416             :         case DRAW_PAINT: {
     417           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     418           0 :             BREAK_ON_READ_ERROR(reader);
     419             : 
     420           0 :             if (paint) {
     421           0 :                 canvas->drawPaint(*paint);
     422             :             }
     423           0 :         } break;
     424             :         case DRAW_PATCH: {
     425           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     426             : 
     427             :             const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts *
     428           0 :                                                                  sizeof(SkPoint));
     429           0 :             uint32_t flag = reader->readInt();
     430           0 :             const SkColor* colors = nullptr;
     431           0 :             if (flag & DRAW_VERTICES_HAS_COLORS) {
     432           0 :                 colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners * sizeof(SkColor));
     433             :             }
     434           0 :             const SkPoint* texCoords = nullptr;
     435           0 :             if (flag & DRAW_VERTICES_HAS_TEXS) {
     436             :                 texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners *
     437           0 :                                                          sizeof(SkPoint));
     438             :             }
     439           0 :             SkBlendMode bmode = SkBlendMode::kModulate;
     440           0 :             if (flag & DRAW_VERTICES_HAS_XFER) {
     441           0 :                 unsigned mode = reader->readInt();
     442           0 :                 if (mode <= (unsigned)SkBlendMode::kLastMode) {
     443           0 :                     bmode = (SkBlendMode)mode;
     444             :                 }
     445             :             }
     446           0 :             BREAK_ON_READ_ERROR(reader);
     447             : 
     448           0 :             if (paint) {
     449           0 :                 canvas->drawPatch(cubics, colors, texCoords, bmode, *paint);
     450             :             }
     451           0 :         } break;
     452             :         case DRAW_PATH: {
     453           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     454           0 :             const auto& path = fPictureData->getPath(reader);
     455           0 :             BREAK_ON_READ_ERROR(reader);
     456             : 
     457           0 :             if (paint) {
     458           0 :                 canvas->drawPath(path, *paint);
     459             :             }
     460           0 :         } break;
     461             :         case DRAW_PICTURE: {
     462           0 :             const auto* pic = fPictureData->getPicture(reader);
     463           0 :             BREAK_ON_READ_ERROR(reader);
     464             : 
     465           0 :             canvas->drawPicture(pic);
     466           0 :         } break;
     467             :         case DRAW_PICTURE_MATRIX_PAINT: {
     468           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     469             :             SkMatrix matrix;
     470           0 :             reader->readMatrix(&matrix);
     471           0 :             const SkPicture* pic = fPictureData->getPicture(reader);
     472           0 :             BREAK_ON_READ_ERROR(reader);
     473             : 
     474           0 :             canvas->drawPicture(pic, &matrix, paint);
     475           0 :         } break;
     476             :         case DRAW_POINTS: {
     477           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     478           0 :             SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt();
     479           0 :             size_t count = reader->readInt();
     480           0 :             const SkPoint* pts = (const SkPoint*)reader->skip(sizeof(SkPoint)* count);
     481           0 :             BREAK_ON_READ_ERROR(reader);
     482             : 
     483           0 :             if (paint) {
     484           0 :                 canvas->drawPoints(mode, count, pts, *paint);
     485             :             }
     486           0 :         } break;
     487             :         case DRAW_POS_TEXT: {
     488           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     489             :             TextContainer text;
     490           0 :             get_text(reader, &text);
     491           0 :             size_t points = reader->readInt();
     492           0 :             const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
     493           0 :             BREAK_ON_READ_ERROR(reader);
     494             : 
     495           0 :             if (paint && text.text()) {
     496           0 :                 canvas->drawPosText(text.text(), text.length(), pos, *paint);
     497             :             }
     498           0 :         } break;
     499             :         case DRAW_POS_TEXT_TOP_BOTTOM: {
     500           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     501             :             TextContainer text;
     502           0 :             get_text(reader, &text);
     503           0 :             size_t points = reader->readInt();
     504           0 :             const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
     505           0 :             const SkScalar top = reader->readScalar();
     506           0 :             const SkScalar bottom = reader->readScalar();
     507           0 :             BREAK_ON_READ_ERROR(reader);
     508             : 
     509           0 :             SkRect clip = canvas->getLocalClipBounds();
     510           0 :             if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
     511           0 :                 canvas->drawPosText(text.text(), text.length(), pos, *paint);
     512             :             }
     513           0 :         } break;
     514             :         case DRAW_POS_TEXT_H: {
     515           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     516             :             TextContainer text;
     517           0 :             get_text(reader, &text);
     518           0 :             size_t xCount = reader->readInt();
     519           0 :             const SkScalar constY = reader->readScalar();
     520           0 :             const SkScalar* xpos = (const SkScalar*)reader->skip(xCount * sizeof(SkScalar));
     521           0 :             BREAK_ON_READ_ERROR(reader);
     522             : 
     523           0 :             if (paint && text.text()) {
     524           0 :                 canvas->drawPosTextH(text.text(), text.length(), xpos, constY, *paint);
     525             :             }
     526           0 :         } break;
     527             :         case DRAW_POS_TEXT_H_TOP_BOTTOM: {
     528           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     529             :             TextContainer text;
     530           0 :             get_text(reader, &text);
     531           0 :             size_t xCount = reader->readInt();
     532           0 :             const SkScalar* xpos = (const SkScalar*)reader->skip((3 + xCount) * sizeof(SkScalar));
     533           0 :             BREAK_ON_READ_ERROR(reader);
     534             : 
     535           0 :             const SkScalar top = *xpos++;
     536           0 :             const SkScalar bottom = *xpos++;
     537           0 :             const SkScalar constY = *xpos++;
     538           0 :             SkRect clip = canvas->getLocalClipBounds();
     539           0 :             if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
     540           0 :                 canvas->drawPosTextH(text.text(), text.length(), xpos, constY, *paint);
     541             :             }
     542           0 :         } break;
     543             :         case DRAW_RECT: {
     544           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     545             :             SkRect rect;
     546           0 :             reader->readRect(&rect);
     547           0 :             BREAK_ON_READ_ERROR(reader);
     548             : 
     549           0 :             if (paint) {
     550           0 :                 canvas->drawRect(rect, *paint);
     551             :             }
     552           0 :         } break;
     553             :         case DRAW_REGION: {
     554           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     555           0 :             SkRegion region;
     556           0 :             reader->readRegion(&region);
     557           0 :             BREAK_ON_READ_ERROR(reader);
     558             : 
     559           0 :             if (paint) {
     560           0 :                 canvas->drawRegion(region, *paint);
     561             :             }
     562           0 :         } break;
     563             :         case DRAW_RRECT: {
     564           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     565           0 :             SkRRect rrect;
     566           0 :             reader->readRRect(&rrect);
     567           0 :             BREAK_ON_READ_ERROR(reader);
     568             : 
     569           0 :             if (paint) {
     570           0 :                 canvas->drawRRect(rrect, *paint);
     571             :             }
     572           0 :         } break;
     573             :         case DRAW_SPRITE: {
     574           0 :             /* const SkPaint* paint = */ fPictureData->getPaint(reader);
     575           0 :             /* const SkImage* image = */ fPictureData->getBitmapAsImage(reader);
     576           0 :             /* int left = */ reader->readInt();
     577           0 :             /* int top = */ reader->readInt();
     578             :             // drawSprite removed dec-2015
     579           0 :         } break;
     580             :         case DRAW_TEXT: {
     581           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     582             :             TextContainer text;
     583           0 :             get_text(reader, &text);
     584           0 :             SkScalar x = reader->readScalar();
     585           0 :             SkScalar y = reader->readScalar();
     586           0 :             BREAK_ON_READ_ERROR(reader);
     587             : 
     588           0 :             if (paint && text.text()) {
     589           0 :                 canvas->drawText(text.text(), text.length(), x, y, *paint);
     590             :             }
     591           0 :         } break;
     592             :         case DRAW_TEXT_BLOB: {
     593           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     594           0 :             const SkTextBlob* blob = fPictureData->getTextBlob(reader);
     595           0 :             SkScalar x = reader->readScalar();
     596           0 :             SkScalar y = reader->readScalar();
     597           0 :             BREAK_ON_READ_ERROR(reader);
     598             : 
     599           0 :             if (paint) {
     600           0 :                 canvas->drawTextBlob(blob, x, y, *paint);
     601             :             }
     602           0 :         } break;
     603             :         case DRAW_TEXT_TOP_BOTTOM: {
     604           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     605             :             TextContainer text;
     606           0 :             get_text(reader, &text);
     607           0 :             const SkScalar* ptr = (const SkScalar*)reader->skip(4 * sizeof(SkScalar));
     608           0 :             BREAK_ON_READ_ERROR(reader);
     609             : 
     610             :             // ptr[0] == x
     611             :             // ptr[1] == y
     612             :             // ptr[2] == top
     613             :             // ptr[3] == bottom
     614           0 :             SkRect clip = canvas->getLocalClipBounds();
     615           0 :             float top = ptr[2];
     616           0 :             float bottom = ptr[3];
     617           0 :             if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
     618           0 :                 canvas->drawText(text.text(), text.length(), ptr[0], ptr[1], *paint);
     619             :             }
     620           0 :         } break;
     621             :         case DRAW_TEXT_ON_PATH: {
     622           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     623             :             TextContainer text;
     624           0 :             get_text(reader, &text);
     625           0 :             const SkPath& path = fPictureData->getPath(reader);
     626             :             SkMatrix matrix;
     627           0 :             reader->readMatrix(&matrix);
     628           0 :             BREAK_ON_READ_ERROR(reader);
     629             : 
     630           0 :             if (paint && text.text()) {
     631           0 :                 canvas->drawTextOnPath(text.text(), text.length(), path, &matrix, *paint);
     632             :             }
     633           0 :         } break;
     634             :         case DRAW_TEXT_RSXFORM: {
     635           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     636           0 :             int count = reader->readInt();
     637           0 :             uint32_t flags = reader->read32();
     638             :             TextContainer text;
     639           0 :             get_text(reader, &text);
     640           0 :             const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform));
     641           0 :             const SkRect* cull = nullptr;
     642           0 :             if (flags & DRAW_TEXT_RSXFORM_HAS_CULL) {
     643           0 :                 cull = (const SkRect*)reader->skip(sizeof(SkRect));
     644             :             }
     645           0 :             BREAK_ON_READ_ERROR(reader);
     646             : 
     647           0 :             if (text.text()) {
     648           0 :                 canvas->drawTextRSXform(text.text(), text.length(), xform, cull, *paint);
     649             :             }
     650           0 :         } break;
     651             :         case DRAW_VERTICES_RETIRED_03_2017: {
     652           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     653           0 :             DrawVertexFlags flags = (DrawVertexFlags)reader->readInt();
     654           0 :             SkVertices::VertexMode vmode = (SkVertices::VertexMode)reader->readInt();
     655           0 :             int vCount = reader->readInt();
     656           0 :             const SkPoint* verts = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint));
     657           0 :             const SkPoint* texs = nullptr;
     658           0 :             const SkColor* colors = nullptr;
     659           0 :             const uint16_t* indices = nullptr;
     660           0 :             int iCount = 0;
     661           0 :             if (flags & DRAW_VERTICES_HAS_TEXS) {
     662           0 :                 texs = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint));
     663             :             }
     664           0 :             if (flags & DRAW_VERTICES_HAS_COLORS) {
     665           0 :                 colors = (const SkColor*)reader->skip(vCount * sizeof(SkColor));
     666             :             }
     667           0 :             if (flags & DRAW_VERTICES_HAS_INDICES) {
     668           0 :                 iCount = reader->readInt();
     669           0 :                 indices = (const uint16_t*)reader->skip(iCount * sizeof(uint16_t));
     670             :             }
     671           0 :             SkBlendMode bmode = SkBlendMode::kModulate;
     672           0 :             if (flags & DRAW_VERTICES_HAS_XFER) {
     673           0 :                 unsigned mode = reader->readInt();
     674           0 :                 if (mode <= (unsigned)SkBlendMode::kLastMode) {
     675           0 :                     bmode = (SkBlendMode)mode;
     676             :                 }
     677             :             }
     678           0 :             BREAK_ON_READ_ERROR(reader);
     679             : 
     680           0 :             if (paint) {
     681           0 :                 canvas->drawVertices(SkVertices::MakeCopy(vmode, vCount, verts, texs, colors,
     682           0 :                                                           iCount, indices), bmode, *paint);
     683             :             }
     684           0 :         } break;
     685             :         case DRAW_VERTICES_OBJECT: {
     686           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     687           0 :             const SkVertices* vertices = fPictureData->getVertices(reader);
     688           0 :             SkBlendMode bmode = static_cast<SkBlendMode>(reader->readInt());
     689             : 
     690           0 :             BREAK_ON_READ_ERROR(reader);
     691             : 
     692           0 :             if (paint && vertices) {
     693           0 :                 canvas->drawVertices(vertices, bmode, *paint);
     694             :             }
     695           0 :         } break;
     696             :         case RESTORE:
     697           0 :             canvas->restore();
     698           0 :             break;
     699             :         case ROTATE: {
     700           0 :             auto deg = reader->readScalar();
     701           0 :             BREAK_ON_READ_ERROR(reader);
     702             : 
     703           0 :             canvas->rotate(deg);
     704           0 :         } break;
     705             :         case SAVE:
     706           0 :             canvas->save();
     707           0 :             break;
     708             :         case SAVE_LAYER_SAVEFLAGS_DEPRECATED: {
     709             :             SkRect storage;
     710           0 :             const SkRect* boundsPtr = get_rect_ptr(reader, &storage);
     711           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     712           0 :             auto flags = SkCanvas::LegacySaveFlagsToSaveLayerFlags(reader->readInt());
     713           0 :             BREAK_ON_READ_ERROR(reader);
     714             : 
     715           0 :             canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
     716           0 :         } break;
     717             :         case SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016: {
     718             :             SkRect storage;
     719           0 :             const SkRect* boundsPtr = get_rect_ptr(reader, &storage);
     720           0 :             const SkPaint* paint = fPictureData->getPaint(reader);
     721           0 :             auto flags = reader->readInt();
     722           0 :             BREAK_ON_READ_ERROR(reader);
     723             : 
     724           0 :             canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
     725           0 :         } break;
     726             :         case SAVE_LAYER_SAVELAYERREC: {
     727           0 :             SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0);
     728           0 :             const uint32_t flatFlags = reader->readInt();
     729             :             SkRect bounds;
     730           0 :             if (flatFlags & SAVELAYERREC_HAS_BOUNDS) {
     731           0 :                 reader->readRect(&bounds);
     732           0 :                 rec.fBounds = &bounds;
     733             :             }
     734           0 :             if (flatFlags & SAVELAYERREC_HAS_PAINT) {
     735           0 :                 rec.fPaint = fPictureData->getPaint(reader);
     736             :             }
     737           0 :             if (flatFlags & SAVELAYERREC_HAS_BACKDROP) {
     738           0 :                 if (const auto* paint = fPictureData->getPaint(reader)) {
     739           0 :                     rec.fBackdrop = paint->getImageFilter();
     740             :                 }
     741             :             }
     742           0 :             if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
     743           0 :                 rec.fSaveLayerFlags = reader->readInt();
     744             :             }
     745           0 :             BREAK_ON_READ_ERROR(reader);
     746             : 
     747           0 :             canvas->saveLayer(rec);
     748           0 :         } break;
     749             :         case SCALE: {
     750           0 :             SkScalar sx = reader->readScalar();
     751           0 :             SkScalar sy = reader->readScalar();
     752           0 :             BREAK_ON_READ_ERROR(reader);
     753             : 
     754           0 :             canvas->scale(sx, sy);
     755           0 :         } break;
     756             :         case SET_MATRIX: {
     757             :             SkMatrix matrix;
     758           0 :             reader->readMatrix(&matrix);
     759           0 :             BREAK_ON_READ_ERROR(reader);
     760             : 
     761           0 :             matrix.postConcat(initialMatrix);
     762           0 :             canvas->setMatrix(matrix);
     763           0 :         } break;
     764             :         case SKEW: {
     765           0 :             SkScalar sx = reader->readScalar();
     766           0 :             SkScalar sy = reader->readScalar();
     767           0 :             BREAK_ON_READ_ERROR(reader);
     768             : 
     769           0 :             canvas->skew(sx, sy);
     770           0 :         } break;
     771             :         case TRANSLATE: {
     772           0 :             SkScalar dx = reader->readScalar();
     773           0 :             SkScalar dy = reader->readScalar();
     774           0 :             BREAK_ON_READ_ERROR(reader);
     775             : 
     776           0 :             canvas->translate(dx, dy);
     777           0 :         } break;
     778             :         case TRANSLATE_Z: {
     779             : #ifdef SK_EXPERIMENTAL_SHADOWING
     780             :             SkScalar dz = reader->readScalar();
     781             :             BREAK_ON_READ_ERROR(reader);
     782             : 
     783             :             canvas->translateZ(dz);
     784             : #endif
     785           0 :         } break;
     786             :         default:
     787           0 :             SkASSERTF(false, "Unknown draw type: %d", op);
     788             :     }
     789             : 
     790             : #undef BREAK_ON_READ_ERROR
     791           0 : }

Generated by: LCOV version 1.13