blob: c0adaaa941056b8afe99c255e328eb8242b0f36b [file] [log] [blame]
robertphillipsce4dd3d2014-07-07 13:46:35 -07001/*
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"
Jim Van Verth1af03d42017-07-31 09:34:58 -04009#include "SkDrawShadowInfo.h"
dandovb3c9d1c2014-08-12 08:34:29 -070010#include "SkPatchUtils.h"
robertphillipsce4dd3d2014-07-07 13:46:35 -070011#include "SkPictureData.h"
12#include "SkPicturePlayback.h"
13#include "SkPictureRecord.h"
robertphillips9ca06c42016-04-20 11:43:33 -070014#include "SkReadBuffer.h"
reed71c3c762015-06-24 10:29:17 -070015#include "SkRSXform.h"
fmalitab7425172014-08-26 07:56:44 -070016#include "SkTextBlob.h"
robertphillipsce4dd3d2014-07-07 13:46:35 -070017#include "SkTDArray.h"
18#include "SkTypes.h"
19
reedbada1882015-12-21 13:09:44 -080020// matches old SkCanvas::SaveFlags
21enum LegacySaveFlags {
22 kHasAlphaLayer_LegacySaveFlags = 0x04,
23 kClipToLayer_LegacySaveFlags = 0x10,
24};
reedbada1882015-12-21 13:09:44 -080025
26SkCanvas::SaveLayerFlags SkCanvas::LegacySaveFlagsToSaveLayerFlags(uint32_t flags) {
27 uint32_t layerFlags = 0;
halcanary9d524f22016-03-29 09:03:52 -070028
reedbada1882015-12-21 13:09:44 -080029 if (0 == (flags & kClipToLayer_LegacySaveFlags)) {
30 layerFlags |= SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag;
31 }
32 if (0 == (flags & kHasAlphaLayer_LegacySaveFlags)) {
33 layerFlags |= kIsOpaque_SaveLayerFlag;
34 }
35 return layerFlags;
36}
37
robertphillipsce4dd3d2014-07-07 13:46:35 -070038/*
robertphillips1ad00e42014-07-08 08:28:08 -070039 * Read the next op code and chunk size from 'reader'. The returned size
40 * is the entire size of the chunk (including the opcode). Thus, the
41 * offset just prior to calling ReadOpAndSize + 'size' is the offset
42 * to the next chunk's op code. This also means that the size of a chunk
43 * with no arguments (just an opcode) will be 4.
44 */
robertphillips9ca06c42016-04-20 11:43:33 -070045DrawType SkPicturePlayback::ReadOpAndSize(SkReadBuffer* reader, uint32_t* size) {
robertphillipsce4dd3d2014-07-07 13:46:35 -070046 uint32_t temp = reader->readInt();
47 uint32_t op;
48 if (((uint8_t)temp) == temp) {
49 // old skp file - no size information
50 op = temp;
51 *size = 0;
52 } else {
53 UNPACK_8_24(temp, op, *size);
54 if (MASK_24 == *size) {
55 *size = reader->readInt();
56 }
57 }
58 return (DrawType)op;
59}
60
61
robertphillips9ca06c42016-04-20 11:43:33 -070062static const SkRect* get_rect_ptr(SkReadBuffer* reader, SkRect* storage) {
robertphillips3afef1f2014-07-08 06:12:22 -070063 if (reader->readBool()) {
robertphillips9ca06c42016-04-20 11:43:33 -070064 reader->readRect(storage);
65 return storage;
robertphillipsce4dd3d2014-07-07 13:46:35 -070066 } else {
halcanary96fcdcc2015-08-27 07:41:13 -070067 return nullptr;
robertphillipsce4dd3d2014-07-07 13:46:35 -070068 }
69}
70
71class TextContainer {
72public:
73 size_t length() { return fByteLength; }
74 const void* text() { return (const void*)fText; }
75 size_t fByteLength;
76 const char* fText;
77};
78
robertphillips9ca06c42016-04-20 11:43:33 -070079void get_text(SkReadBuffer* reader, TextContainer* text) {
robertphillipsce4dd3d2014-07-07 13:46:35 -070080 size_t length = text->fByteLength = reader->readInt();
81 text->fText = (const char*)reader->skip(length);
82}
83
robertphillips99e20892016-04-22 11:40:42 -070084void SkPicturePlayback::draw(SkCanvas* canvas,
85 SkPicture::AbortCallback* callback,
reedd921dbb2016-09-30 09:27:20 -070086 SkReadBuffer* buffer) {
robertphillipsec66e622014-07-09 13:00:07 -070087 AutoResetOpID aroi(this);
88 SkASSERT(0 == fCurOffset);
89
Ben Wagner145dbcd2016-11-03 14:40:50 -040090 std::unique_ptr<SkReadBuffer> reader;
robertphillips99e20892016-04-22 11:40:42 -070091 if (buffer) {
92 reader.reset(buffer->clone(fPictureData->opData()->bytes(),
93 fPictureData->opData()->size()));
94 } else {
95 reader.reset(new SkReadBuffer(fPictureData->opData()->bytes(),
96 fPictureData->opData()->size()));
97 }
robertphillipsec66e622014-07-09 13:00:07 -070098
robertphillipsce4dd3d2014-07-07 13:46:35 -070099 // Record this, so we can concat w/ it if we encounter a setMatrix()
100 SkMatrix initialMatrix = canvas->getTotalMatrix();
101
102 SkAutoCanvasRestore acr(canvas, false);
103
robertphillips99e20892016-04-22 11:40:42 -0700104 while (!reader->eof()) {
robertphillips783fe162015-01-07 07:28:41 -0800105 if (callback && callback->abort()) {
robertphillipsce4dd3d2014-07-07 13:46:35 -0700106 return;
107 }
108
robertphillips99e20892016-04-22 11:40:42 -0700109 fCurOffset = reader->offset();
robertphillipsce4dd3d2014-07-07 13:46:35 -0700110 uint32_t size;
Ben Wagner145dbcd2016-11-03 14:40:50 -0400111 DrawType op = ReadOpAndSize(reader.get(), &size);
Robert Phillipsb2526042016-09-26 09:00:36 -0400112 if (!reader->validate(op > UNUSED && op <= LAST_DRAWTYPE_ENUM)) {
113 return;
114 }
robertphillipsce4dd3d2014-07-07 13:46:35 -0700115
Ben Wagner145dbcd2016-11-03 14:40:50 -0400116 this->handleOp(reader.get(), op, size, canvas, initialMatrix);
robertphillipsce4dd3d2014-07-07 13:46:35 -0700117 }
reedd921dbb2016-09-30 09:27:20 -0700118
119 // need to propagate invalid state to the parent reader
120 if (buffer) {
121 buffer->validate(reader->isValid());
122 }
robertphillips3afef1f2014-07-08 06:12:22 -0700123}
robertphillipsce4dd3d2014-07-07 13:46:35 -0700124
robertphillips9ca06c42016-04-20 11:43:33 -0700125void SkPicturePlayback::handleOp(SkReadBuffer* reader,
mtklein533eb782014-08-27 10:39:42 -0700126 DrawType op,
127 uint32_t size,
robertphillips3afef1f2014-07-08 06:12:22 -0700128 SkCanvas* canvas,
129 const SkMatrix& initialMatrix) {
fmalitad87bd7c2016-10-06 12:09:50 -0700130#define BREAK_ON_READ_ERROR(r) if (!r->isValid()) { break; }
131
robertphillips3afef1f2014-07-08 06:12:22 -0700132 switch (op) {
mtklein46616af2014-09-30 14:47:10 -0700133 case NOOP: {
134 SkASSERT(size >= 4);
135 reader->skip(size - 4);
136 } break;
Mike Klein7cc49d62017-08-14 10:39:28 -0400137 case FLUSH:
138 canvas->flush();
139 break;
robertphillips3afef1f2014-07-08 06:12:22 -0700140 case CLIP_PATH: {
Mike Klein7cc49d62017-08-14 10:39:28 -0400141 const SkPath& path = fPictureData->getPath(reader);
142 uint32_t packed = reader->readInt();
Robert Phillips98624d22016-12-19 11:37:37 -0500143 SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
robertphillips3afef1f2014-07-08 06:12:22 -0700144 bool doAA = ClipParams_unpackDoAA(packed);
145 size_t offsetToRestore = reader->readInt();
fmalitad87bd7c2016-10-06 12:09:50 -0700146 BREAK_ON_READ_ERROR(reader);
147
robertphillips3afef1f2014-07-08 06:12:22 -0700148 SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
reed73603f32016-09-20 08:42:38 -0700149 canvas->clipPath(path, clipOp, doAA);
robertphillips3afef1f2014-07-08 06:12:22 -0700150 if (canvas->isClipEmpty() && offsetToRestore) {
robertphillips9ca06c42016-04-20 11:43:33 -0700151 reader->skip(offsetToRestore - reader->offset());
robertphillips3afef1f2014-07-08 06:12:22 -0700152 }
153 } break;
154 case CLIP_REGION: {
155 SkRegion region;
156 reader->readRegion(&region);
157 uint32_t packed = reader->readInt();
Robert Phillips98624d22016-12-19 11:37:37 -0500158 SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
robertphillips3afef1f2014-07-08 06:12:22 -0700159 size_t offsetToRestore = reader->readInt();
fmalitad87bd7c2016-10-06 12:09:50 -0700160 BREAK_ON_READ_ERROR(reader);
161
robertphillips3afef1f2014-07-08 06:12:22 -0700162 SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
reed73603f32016-09-20 08:42:38 -0700163 canvas->clipRegion(region, clipOp);
robertphillips3afef1f2014-07-08 06:12:22 -0700164 if (canvas->isClipEmpty() && offsetToRestore) {
robertphillips9ca06c42016-04-20 11:43:33 -0700165 reader->skip(offsetToRestore - reader->offset());
robertphillips3afef1f2014-07-08 06:12:22 -0700166 }
167 } break;
168 case CLIP_RECT: {
robertphillips9ca06c42016-04-20 11:43:33 -0700169 SkRect rect;
170 reader->readRect(&rect);
robertphillips3afef1f2014-07-08 06:12:22 -0700171 uint32_t packed = reader->readInt();
Robert Phillips98624d22016-12-19 11:37:37 -0500172 SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
robertphillips3afef1f2014-07-08 06:12:22 -0700173 bool doAA = ClipParams_unpackDoAA(packed);
174 size_t offsetToRestore = reader->readInt();
fmalitad87bd7c2016-10-06 12:09:50 -0700175 BREAK_ON_READ_ERROR(reader);
176
robertphillips3afef1f2014-07-08 06:12:22 -0700177 SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
reed73603f32016-09-20 08:42:38 -0700178 canvas->clipRect(rect, clipOp, doAA);
robertphillips3afef1f2014-07-08 06:12:22 -0700179 if (canvas->isClipEmpty() && offsetToRestore) {
robertphillips9ca06c42016-04-20 11:43:33 -0700180 reader->skip(offsetToRestore - reader->offset());
robertphillips3afef1f2014-07-08 06:12:22 -0700181 }
182 } break;
183 case CLIP_RRECT: {
184 SkRRect rrect;
185 reader->readRRect(&rrect);
186 uint32_t packed = reader->readInt();
Robert Phillips98624d22016-12-19 11:37:37 -0500187 SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
robertphillips3afef1f2014-07-08 06:12:22 -0700188 bool doAA = ClipParams_unpackDoAA(packed);
189 size_t offsetToRestore = reader->readInt();
fmalitad87bd7c2016-10-06 12:09:50 -0700190 BREAK_ON_READ_ERROR(reader);
191
robertphillips3afef1f2014-07-08 06:12:22 -0700192 SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset());
reed73603f32016-09-20 08:42:38 -0700193 canvas->clipRRect(rrect, clipOp, doAA);
robertphillips3afef1f2014-07-08 06:12:22 -0700194 if (canvas->isClipEmpty() && offsetToRestore) {
robertphillips9ca06c42016-04-20 11:43:33 -0700195 reader->skip(offsetToRestore - reader->offset());
robertphillips3afef1f2014-07-08 06:12:22 -0700196 }
197 } break;
mtkleinf0f14112014-12-12 08:46:25 -0800198 case PUSH_CULL: break; // Deprecated, safe to ignore both push and pop.
199 case POP_CULL: break;
robertphillips3afef1f2014-07-08 06:12:22 -0700200 case CONCAT: {
201 SkMatrix matrix;
202 reader->readMatrix(&matrix);
fmalitad87bd7c2016-10-06 12:09:50 -0700203 BREAK_ON_READ_ERROR(reader);
204
robertphillips3afef1f2014-07-08 06:12:22 -0700205 canvas->concat(matrix);
206 break;
207 }
reedf70b5312016-03-04 16:36:20 -0800208 case DRAW_ANNOTATION: {
robertphillips9ca06c42016-04-20 11:43:33 -0700209 SkRect rect;
210 reader->readRect(&rect);
211 SkString key;
212 reader->readString(&key);
fmalitad87bd7c2016-10-06 12:09:50 -0700213 sk_sp<SkData> data = reader->readByteArrayAsData();
214 BREAK_ON_READ_ERROR(reader);
215
216 canvas->drawAnnotation(rect, key.c_str(), data.get());
reedf70b5312016-03-04 16:36:20 -0800217 } break;
bsalomonac3aa242016-08-19 11:25:19 -0700218 case DRAW_ARC: {
219 const SkPaint* paint = fPictureData->getPaint(reader);
220 SkRect rect;
221 reader->readRect(&rect);
222 SkScalar startAngle = reader->readScalar();
223 SkScalar sweepAngle = reader->readScalar();
224 int useCenter = reader->readInt();
fmalitad87bd7c2016-10-06 12:09:50 -0700225 BREAK_ON_READ_ERROR(reader);
226
bsalomonac3aa242016-08-19 11:25:19 -0700227 if (paint) {
228 canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), *paint);
229 }
230 } break;
reed71c3c762015-06-24 10:29:17 -0700231 case DRAW_ATLAS: {
232 const SkPaint* paint = fPictureData->getPaint(reader);
233 const SkImage* atlas = fPictureData->getImage(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700234 const uint32_t flags = reader->readUInt();
235 const int count = reader->readUInt();
reed71c3c762015-06-24 10:29:17 -0700236 const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform));
237 const SkRect* tex = (const SkRect*)reader->skip(count * sizeof(SkRect));
halcanary96fcdcc2015-08-27 07:41:13 -0700238 const SkColor* colors = nullptr;
Mike Reed7d954ad2016-10-28 15:42:34 -0400239 SkBlendMode mode = SkBlendMode::kDst;
reed71c3c762015-06-24 10:29:17 -0700240 if (flags & DRAW_ATLAS_HAS_COLORS) {
241 colors = (const SkColor*)reader->skip(count * sizeof(SkColor));
Mike Reed7d954ad2016-10-28 15:42:34 -0400242 mode = (SkBlendMode)reader->readUInt();
reed71c3c762015-06-24 10:29:17 -0700243 }
halcanary96fcdcc2015-08-27 07:41:13 -0700244 const SkRect* cull = nullptr;
reed71c3c762015-06-24 10:29:17 -0700245 if (flags & DRAW_ATLAS_HAS_CULL) {
246 cull = (const SkRect*)reader->skip(sizeof(SkRect));
247 }
fmalitad87bd7c2016-10-06 12:09:50 -0700248 BREAK_ON_READ_ERROR(reader);
249
reed71c3c762015-06-24 10:29:17 -0700250 canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
251 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700252 case DRAW_BITMAP: {
253 const SkPaint* paint = fPictureData->getPaint(reader);
reeda9ca05c2016-08-11 03:55:15 -0700254 const SkImage* image = fPictureData->getBitmapAsImage(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700255 SkPoint loc;
256 reader->readPoint(&loc);
fmalitad87bd7c2016-10-06 12:09:50 -0700257 BREAK_ON_READ_ERROR(reader);
258
reeda9ca05c2016-08-11 03:55:15 -0700259 canvas->drawImage(image, loc.fX, loc.fY, paint);
robertphillips3afef1f2014-07-08 06:12:22 -0700260 } break;
reeda5517e22015-07-14 10:54:12 -0700261 case DRAW_BITMAP_RECT: {
robertphillips3afef1f2014-07-08 06:12:22 -0700262 const SkPaint* paint = fPictureData->getPaint(reader);
reeda9ca05c2016-08-11 03:55:15 -0700263 const SkImage* image = fPictureData->getBitmapAsImage(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700264 SkRect storage;
265 const SkRect* src = get_rect_ptr(reader, &storage); // may be null
266 SkRect dst;
267 reader->readRect(&dst); // required
reeda5517e22015-07-14 10:54:12 -0700268 SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
fmalitad87bd7c2016-10-06 12:09:50 -0700269 BREAK_ON_READ_ERROR(reader);
270
reeda9ca05c2016-08-11 03:55:15 -0700271 if (src) {
272 canvas->drawImageRect(image, *src, dst, paint, constraint);
273 } else {
274 canvas->drawImageRect(image, dst, paint, constraint);
275 }
robertphillips3afef1f2014-07-08 06:12:22 -0700276 } break;
277 case DRAW_BITMAP_MATRIX: {
278 const SkPaint* paint = fPictureData->getPaint(reader);
reeda9ca05c2016-08-11 03:55:15 -0700279 const SkImage* image = fPictureData->getBitmapAsImage(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700280 SkMatrix matrix;
281 reader->readMatrix(&matrix);
fmalitad87bd7c2016-10-06 12:09:50 -0700282 BREAK_ON_READ_ERROR(reader);
Florin Malitac54d8db2014-12-10 12:02:16 -0500283
284 SkAutoCanvasRestore acr(canvas, true);
285 canvas->concat(matrix);
reeda9ca05c2016-08-11 03:55:15 -0700286 canvas->drawImage(image, 0, 0, paint);
robertphillips3afef1f2014-07-08 06:12:22 -0700287 } break;
288 case DRAW_BITMAP_NINE: {
289 const SkPaint* paint = fPictureData->getPaint(reader);
reeda9ca05c2016-08-11 03:55:15 -0700290 const SkImage* image = fPictureData->getBitmapAsImage(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700291 SkIRect src;
292 reader->readIRect(&src);
293 SkRect dst;
294 reader->readRect(&dst);
fmalitad87bd7c2016-10-06 12:09:50 -0700295 BREAK_ON_READ_ERROR(reader);
296
reeda9ca05c2016-08-11 03:55:15 -0700297 canvas->drawImageNine(image, src, dst, paint);
robertphillips3afef1f2014-07-08 06:12:22 -0700298 } break;
fmalitad87bd7c2016-10-06 12:09:50 -0700299 case DRAW_CLEAR: {
300 auto c = reader->readInt();
301 BREAK_ON_READ_ERROR(reader);
302
303 canvas->clear(c);
304 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700305 case DRAW_DATA: {
reedc4fda922015-01-02 06:39:51 -0800306 // This opcode is now dead, just need to skip it for backwards compatibility
robertphillips3afef1f2014-07-08 06:12:22 -0700307 size_t length = reader->readInt();
reedc4fda922015-01-02 06:39:51 -0800308 (void)reader->skip(length);
robertphillips3afef1f2014-07-08 06:12:22 -0700309 // skip handles padding the read out to a multiple of 4
310 } break;
fmalitad87bd7c2016-10-06 12:09:50 -0700311 case DRAW_DRAWABLE: {
312 auto* d = fPictureData->getDrawable(reader);
313 BREAK_ON_READ_ERROR(reader);
314
315 canvas->drawDrawable(d);
316 } break;
msarett95416f42016-04-27 13:51:20 -0700317 case DRAW_DRAWABLE_MATRIX: {
318 SkMatrix matrix;
319 reader->readMatrix(&matrix);
320 SkDrawable* drawable = fPictureData->getDrawable(reader);
fmalitad87bd7c2016-10-06 12:09:50 -0700321 BREAK_ON_READ_ERROR(reader);
322
msarett95416f42016-04-27 13:51:20 -0700323 canvas->drawDrawable(drawable, &matrix);
324 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700325 case DRAW_DRRECT: {
robertphillips5354e4a2016-06-27 12:05:39 -0700326 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700327 SkRRect outer, inner;
328 reader->readRRect(&outer);
329 reader->readRRect(&inner);
fmalitad87bd7c2016-10-06 12:09:50 -0700330 BREAK_ON_READ_ERROR(reader);
331
robertphillips5354e4a2016-06-27 12:05:39 -0700332 if (paint) {
333 canvas->drawDRRect(outer, inner, *paint);
334 }
robertphillips3afef1f2014-07-08 06:12:22 -0700335 } break;
Robert Phillips19c22e92017-02-10 12:32:08 +0000336 case BEGIN_COMMENT_GROUP: {
337 SkString tmp;
338 reader->readString(&tmp);
339 // deprecated (M44)
340 break;
341 }
342 case COMMENT: {
343 SkString tmp;
344 reader->readString(&tmp);
345 reader->readString(&tmp);
346 // deprecated (M44)
347 break;
348 }
349 case END_COMMENT_GROUP:
350 // deprecated (M44)
351 break;
reed871872f2015-06-22 12:48:26 -0700352 case DRAW_IMAGE: {
353 const SkPaint* paint = fPictureData->getPaint(reader);
354 const SkImage* image = fPictureData->getImage(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700355 SkPoint loc;
356 reader->readPoint(&loc);
fmalitad87bd7c2016-10-06 12:09:50 -0700357 BREAK_ON_READ_ERROR(reader);
358
reed871872f2015-06-22 12:48:26 -0700359 canvas->drawImage(image, loc.fX, loc.fY, paint);
360 } break;
msarettc573a402016-08-02 08:05:56 -0700361 case DRAW_IMAGE_LATTICE: {
362 const SkPaint* paint = fPictureData->getPaint(reader);
363 const SkImage* image = fPictureData->getImage(reader);
364 SkCanvas::Lattice lattice;
365 lattice.fXCount = reader->readInt();
366 lattice.fXDivs = (const int*) reader->skip(lattice.fXCount * sizeof(int32_t));
367 lattice.fYCount = reader->readInt();
368 lattice.fYDivs = (const int*) reader->skip(lattice.fYCount * sizeof(int32_t));
msarett0764efe2016-09-02 11:24:30 -0700369 int flagCount = reader->readInt();
370 lattice.fFlags = (0 == flagCount) ? nullptr : (const SkCanvas::Lattice::Flags*)
371 reader->skip(SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags)));
msarett71df2d72016-09-30 12:41:42 -0700372 SkIRect src;
373 reader->readIRect(&src);
374 lattice.fBounds = &src;
msarettc573a402016-08-02 08:05:56 -0700375 SkRect dst;
376 reader->readRect(&dst);
fmalitad87bd7c2016-10-06 12:09:50 -0700377 BREAK_ON_READ_ERROR(reader);
378
msarettc573a402016-08-02 08:05:56 -0700379 canvas->drawImageLattice(image, lattice, dst, paint);
380 } break;
reed4c21dc52015-06-25 12:32:03 -0700381 case DRAW_IMAGE_NINE: {
382 const SkPaint* paint = fPictureData->getPaint(reader);
383 const SkImage* image = fPictureData->getImage(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700384 SkIRect center;
385 reader->readIRect(&center);
386 SkRect dst;
387 reader->readRect(&dst);
fmalitad87bd7c2016-10-06 12:09:50 -0700388 BREAK_ON_READ_ERROR(reader);
389
reed4c21dc52015-06-25 12:32:03 -0700390 canvas->drawImageNine(image, center, dst, paint);
391 } break;
reeda5517e22015-07-14 10:54:12 -0700392 case DRAW_IMAGE_RECT_STRICT:
reed871872f2015-06-22 12:48:26 -0700393 case DRAW_IMAGE_RECT: {
394 const SkPaint* paint = fPictureData->getPaint(reader);
395 const SkImage* image = fPictureData->getImage(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700396 SkRect storage;
397 const SkRect* src = get_rect_ptr(reader, &storage); // may be null
398 SkRect dst;
399 reader->readRect(&dst); // required
reeda5517e22015-07-14 10:54:12 -0700400 // DRAW_IMAGE_RECT_STRICT assumes this constraint, and doesn't store it
401 SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
402 if (DRAW_IMAGE_RECT == op) {
403 // newer op-code stores the constraint explicitly
404 constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
405 }
fmalitad87bd7c2016-10-06 12:09:50 -0700406 BREAK_ON_READ_ERROR(reader);
407
reede47829b2015-08-06 10:02:53 -0700408 canvas->legacy_drawImageRect(image, src, dst, paint, constraint);
reed871872f2015-06-22 12:48:26 -0700409 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700410 case DRAW_OVAL: {
robertphillips5354e4a2016-06-27 12:05:39 -0700411 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700412 SkRect rect;
413 reader->readRect(&rect);
fmalitad87bd7c2016-10-06 12:09:50 -0700414 BREAK_ON_READ_ERROR(reader);
415
robertphillips5354e4a2016-06-27 12:05:39 -0700416 if (paint) {
417 canvas->drawOval(rect, *paint);
418 }
robertphillips3afef1f2014-07-08 06:12:22 -0700419 } break;
robertphillips5354e4a2016-06-27 12:05:39 -0700420 case DRAW_PAINT: {
421 const SkPaint* paint = fPictureData->getPaint(reader);
fmalitad87bd7c2016-10-06 12:09:50 -0700422 BREAK_ON_READ_ERROR(reader);
423
robertphillips5354e4a2016-06-27 12:05:39 -0700424 if (paint) {
425 canvas->drawPaint(*paint);
426 }
427 } break;
dandov963137b2014-08-07 07:49:53 -0700428 case DRAW_PATCH: {
robertphillips5354e4a2016-06-27 12:05:39 -0700429 const SkPaint* paint = fPictureData->getPaint(reader);
mtklein533eb782014-08-27 10:39:42 -0700430
dandovb3c9d1c2014-08-12 08:34:29 -0700431 const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts *
432 sizeof(SkPoint));
433 uint32_t flag = reader->readInt();
halcanary96fcdcc2015-08-27 07:41:13 -0700434 const SkColor* colors = nullptr;
dandovb3c9d1c2014-08-12 08:34:29 -0700435 if (flag & DRAW_VERTICES_HAS_COLORS) {
436 colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners * sizeof(SkColor));
437 }
halcanary96fcdcc2015-08-27 07:41:13 -0700438 const SkPoint* texCoords = nullptr;
dandovb3c9d1c2014-08-12 08:34:29 -0700439 if (flag & DRAW_VERTICES_HAS_TEXS) {
440 texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners *
441 sizeof(SkPoint));
442 }
Mike Reed7d954ad2016-10-28 15:42:34 -0400443 SkBlendMode bmode = SkBlendMode::kModulate;
dandovb3c9d1c2014-08-12 08:34:29 -0700444 if (flag & DRAW_VERTICES_HAS_XFER) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400445 unsigned mode = reader->readInt();
446 if (mode <= (unsigned)SkBlendMode::kLastMode) {
447 bmode = (SkBlendMode)mode;
dandovb3c9d1c2014-08-12 08:34:29 -0700448 }
dandovb3c9d1c2014-08-12 08:34:29 -0700449 }
fmalitad87bd7c2016-10-06 12:09:50 -0700450 BREAK_ON_READ_ERROR(reader);
451
robertphillips5354e4a2016-06-27 12:05:39 -0700452 if (paint) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400453 canvas->drawPatch(cubics, colors, texCoords, bmode, *paint);
robertphillips5354e4a2016-06-27 12:05:39 -0700454 }
dandov963137b2014-08-07 07:49:53 -0700455 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700456 case DRAW_PATH: {
robertphillips5354e4a2016-06-27 12:05:39 -0700457 const SkPaint* paint = fPictureData->getPaint(reader);
fmalitad87bd7c2016-10-06 12:09:50 -0700458 const auto& path = fPictureData->getPath(reader);
459 BREAK_ON_READ_ERROR(reader);
460
robertphillips5354e4a2016-06-27 12:05:39 -0700461 if (paint) {
fmalitad87bd7c2016-10-06 12:09:50 -0700462 canvas->drawPath(path, *paint);
robertphillips5354e4a2016-06-27 12:05:39 -0700463 }
robertphillips3afef1f2014-07-08 06:12:22 -0700464 } break;
fmalitad87bd7c2016-10-06 12:09:50 -0700465 case DRAW_PICTURE: {
466 const auto* pic = fPictureData->getPicture(reader);
467 BREAK_ON_READ_ERROR(reader);
468
469 canvas->drawPicture(pic);
470 } break;
reedd5fa1a42014-08-09 11:08:05 -0700471 case DRAW_PICTURE_MATRIX_PAINT: {
fmalita9f49cfd2014-08-12 12:24:17 -0700472 const SkPaint* paint = fPictureData->getPaint(reader);
reedd5fa1a42014-08-09 11:08:05 -0700473 SkMatrix matrix;
474 reader->readMatrix(&matrix);
fmalita9f49cfd2014-08-12 12:24:17 -0700475 const SkPicture* pic = fPictureData->getPicture(reader);
fmalitad87bd7c2016-10-06 12:09:50 -0700476 BREAK_ON_READ_ERROR(reader);
477
reedd5fa1a42014-08-09 11:08:05 -0700478 canvas->drawPicture(pic, &matrix, paint);
479 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700480 case DRAW_POINTS: {
robertphillips5354e4a2016-06-27 12:05:39 -0700481 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700482 SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt();
483 size_t count = reader->readInt();
484 const SkPoint* pts = (const SkPoint*)reader->skip(sizeof(SkPoint)* count);
fmalitad87bd7c2016-10-06 12:09:50 -0700485 BREAK_ON_READ_ERROR(reader);
486
robertphillips5354e4a2016-06-27 12:05:39 -0700487 if (paint) {
488 canvas->drawPoints(mode, count, pts, *paint);
489 }
robertphillips3afef1f2014-07-08 06:12:22 -0700490 } break;
491 case DRAW_POS_TEXT: {
robertphillips5354e4a2016-06-27 12:05:39 -0700492 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700493 TextContainer text;
494 get_text(reader, &text);
495 size_t points = reader->readInt();
496 const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
fmalitad87bd7c2016-10-06 12:09:50 -0700497 BREAK_ON_READ_ERROR(reader);
498
Robert Phillipsb2526042016-09-26 09:00:36 -0400499 if (paint && text.text()) {
robertphillips5354e4a2016-06-27 12:05:39 -0700500 canvas->drawPosText(text.text(), text.length(), pos, *paint);
501 }
robertphillips3afef1f2014-07-08 06:12:22 -0700502 } break;
503 case DRAW_POS_TEXT_TOP_BOTTOM: {
robertphillips5354e4a2016-06-27 12:05:39 -0700504 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700505 TextContainer text;
506 get_text(reader, &text);
507 size_t points = reader->readInt();
508 const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint));
509 const SkScalar top = reader->readScalar();
510 const SkScalar bottom = reader->readScalar();
fmalitad87bd7c2016-10-06 12:09:50 -0700511 BREAK_ON_READ_ERROR(reader);
512
Mike Reed918e1442017-01-23 11:39:45 -0500513 SkRect clip = canvas->getLocalClipBounds();
Robert Phillipsb2526042016-09-26 09:00:36 -0400514 if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
robertphillips5354e4a2016-06-27 12:05:39 -0700515 canvas->drawPosText(text.text(), text.length(), pos, *paint);
robertphillips3afef1f2014-07-08 06:12:22 -0700516 }
517 } break;
518 case DRAW_POS_TEXT_H: {
robertphillips5354e4a2016-06-27 12:05:39 -0700519 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700520 TextContainer text;
521 get_text(reader, &text);
522 size_t xCount = reader->readInt();
523 const SkScalar constY = reader->readScalar();
524 const SkScalar* xpos = (const SkScalar*)reader->skip(xCount * sizeof(SkScalar));
fmalitad87bd7c2016-10-06 12:09:50 -0700525 BREAK_ON_READ_ERROR(reader);
526
Robert Phillipsb2526042016-09-26 09:00:36 -0400527 if (paint && text.text()) {
robertphillips5354e4a2016-06-27 12:05:39 -0700528 canvas->drawPosTextH(text.text(), text.length(), xpos, constY, *paint);
529 }
robertphillips3afef1f2014-07-08 06:12:22 -0700530 } break;
531 case DRAW_POS_TEXT_H_TOP_BOTTOM: {
robertphillips5354e4a2016-06-27 12:05:39 -0700532 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700533 TextContainer text;
534 get_text(reader, &text);
535 size_t xCount = reader->readInt();
536 const SkScalar* xpos = (const SkScalar*)reader->skip((3 + xCount) * sizeof(SkScalar));
fmalitad87bd7c2016-10-06 12:09:50 -0700537 BREAK_ON_READ_ERROR(reader);
538
robertphillips3afef1f2014-07-08 06:12:22 -0700539 const SkScalar top = *xpos++;
540 const SkScalar bottom = *xpos++;
541 const SkScalar constY = *xpos++;
Mike Reed918e1442017-01-23 11:39:45 -0500542 SkRect clip = canvas->getLocalClipBounds();
Robert Phillipsb2526042016-09-26 09:00:36 -0400543 if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
robertphillips5354e4a2016-06-27 12:05:39 -0700544 canvas->drawPosTextH(text.text(), text.length(), xpos, constY, *paint);
robertphillips3afef1f2014-07-08 06:12:22 -0700545 }
546 } break;
547 case DRAW_RECT: {
robertphillips5354e4a2016-06-27 12:05:39 -0700548 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips9ca06c42016-04-20 11:43:33 -0700549 SkRect rect;
550 reader->readRect(&rect);
fmalitad87bd7c2016-10-06 12:09:50 -0700551 BREAK_ON_READ_ERROR(reader);
552
robertphillips5354e4a2016-06-27 12:05:39 -0700553 if (paint) {
554 canvas->drawRect(rect, *paint);
555 }
robertphillips3afef1f2014-07-08 06:12:22 -0700556 } break;
msarett44df6512016-08-25 13:54:30 -0700557 case DRAW_REGION: {
558 const SkPaint* paint = fPictureData->getPaint(reader);
559 SkRegion region;
560 reader->readRegion(&region);
fmalitad87bd7c2016-10-06 12:09:50 -0700561 BREAK_ON_READ_ERROR(reader);
562
msarett44df6512016-08-25 13:54:30 -0700563 if (paint) {
564 canvas->drawRegion(region, *paint);
565 }
566 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700567 case DRAW_RRECT: {
robertphillips5354e4a2016-06-27 12:05:39 -0700568 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700569 SkRRect rrect;
570 reader->readRRect(&rrect);
fmalitad87bd7c2016-10-06 12:09:50 -0700571 BREAK_ON_READ_ERROR(reader);
572
robertphillips5354e4a2016-06-27 12:05:39 -0700573 if (paint) {
574 canvas->drawRRect(rrect, *paint);
575 }
robertphillips3afef1f2014-07-08 06:12:22 -0700576 } break;
Jim Van Verth4123d0f2017-05-22 12:02:21 -0400577 case DRAW_SHADOW_REC: {
578 const auto& path = fPictureData->getPath(reader);
579 SkDrawShadowRec rec;
580 reader->readPoint3(&rec.fZPlaneParams);
581 reader->readPoint3(&rec.fLightPos);
582 rec.fLightRadius = reader->readScalar();
583 rec.fAmbientAlpha = reader->readScalar();
584 rec.fSpotAlpha = reader->readScalar();
585 rec.fColor = reader->read32();
586 rec.fFlags = reader->read32();
587 BREAK_ON_READ_ERROR(reader);
588
589 canvas->private_draw_shadow_rec(path, rec);
590 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700591 case DRAW_SPRITE: {
reedda420b92015-12-16 08:38:15 -0800592 /* const SkPaint* paint = */ fPictureData->getPaint(reader);
reeda9ca05c2016-08-11 03:55:15 -0700593 /* const SkImage* image = */ fPictureData->getBitmapAsImage(reader);
reedda420b92015-12-16 08:38:15 -0800594 /* int left = */ reader->readInt();
595 /* int top = */ reader->readInt();
596 // drawSprite removed dec-2015
robertphillips3afef1f2014-07-08 06:12:22 -0700597 } break;
598 case DRAW_TEXT: {
robertphillips5354e4a2016-06-27 12:05:39 -0700599 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700600 TextContainer text;
601 get_text(reader, &text);
602 SkScalar x = reader->readScalar();
603 SkScalar y = reader->readScalar();
fmalitad87bd7c2016-10-06 12:09:50 -0700604 BREAK_ON_READ_ERROR(reader);
605
Robert Phillipsb2526042016-09-26 09:00:36 -0400606 if (paint && text.text()) {
robertphillips5354e4a2016-06-27 12:05:39 -0700607 canvas->drawText(text.text(), text.length(), x, y, *paint);
608 }
robertphillips3afef1f2014-07-08 06:12:22 -0700609 } break;
fmalitab7425172014-08-26 07:56:44 -0700610 case DRAW_TEXT_BLOB: {
robertphillips5354e4a2016-06-27 12:05:39 -0700611 const SkPaint* paint = fPictureData->getPaint(reader);
fmalitab7425172014-08-26 07:56:44 -0700612 const SkTextBlob* blob = fPictureData->getTextBlob(reader);
613 SkScalar x = reader->readScalar();
614 SkScalar y = reader->readScalar();
fmalitad87bd7c2016-10-06 12:09:50 -0700615 BREAK_ON_READ_ERROR(reader);
616
robertphillips5354e4a2016-06-27 12:05:39 -0700617 if (paint) {
618 canvas->drawTextBlob(blob, x, y, *paint);
619 }
fmalitab7425172014-08-26 07:56:44 -0700620 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700621 case DRAW_TEXT_TOP_BOTTOM: {
robertphillips5354e4a2016-06-27 12:05:39 -0700622 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700623 TextContainer text;
624 get_text(reader, &text);
625 const SkScalar* ptr = (const SkScalar*)reader->skip(4 * sizeof(SkScalar));
fmalitad87bd7c2016-10-06 12:09:50 -0700626 BREAK_ON_READ_ERROR(reader);
627
robertphillips3afef1f2014-07-08 06:12:22 -0700628 // ptr[0] == x
629 // ptr[1] == y
630 // ptr[2] == top
631 // ptr[3] == bottom
Mike Reed918e1442017-01-23 11:39:45 -0500632 SkRect clip = canvas->getLocalClipBounds();
msarett6372e652016-08-11 10:31:49 -0700633 float top = ptr[2];
634 float bottom = ptr[3];
Robert Phillipsb2526042016-09-26 09:00:36 -0400635 if (top < clip.fBottom && bottom > clip.fTop && paint && text.text()) {
robertphillips5354e4a2016-06-27 12:05:39 -0700636 canvas->drawText(text.text(), text.length(), ptr[0], ptr[1], *paint);
robertphillips3afef1f2014-07-08 06:12:22 -0700637 }
638 } break;
639 case DRAW_TEXT_ON_PATH: {
robertphillips5354e4a2016-06-27 12:05:39 -0700640 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700641 TextContainer text;
642 get_text(reader, &text);
643 const SkPath& path = fPictureData->getPath(reader);
644 SkMatrix matrix;
645 reader->readMatrix(&matrix);
fmalitad87bd7c2016-10-06 12:09:50 -0700646 BREAK_ON_READ_ERROR(reader);
647
Robert Phillipsb2526042016-09-26 09:00:36 -0400648 if (paint && text.text()) {
robertphillips5354e4a2016-06-27 12:05:39 -0700649 canvas->drawTextOnPath(text.text(), text.length(), path, &matrix, *paint);
650 }
robertphillips3afef1f2014-07-08 06:12:22 -0700651 } break;
reed45561a02016-07-07 12:47:17 -0700652 case DRAW_TEXT_RSXFORM: {
653 const SkPaint* paint = fPictureData->getPaint(reader);
654 int count = reader->readInt();
655 uint32_t flags = reader->read32();
656 TextContainer text;
657 get_text(reader, &text);
658 const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform));
659 const SkRect* cull = nullptr;
660 if (flags & DRAW_TEXT_RSXFORM_HAS_CULL) {
661 cull = (const SkRect*)reader->skip(sizeof(SkRect));
662 }
fmalitad87bd7c2016-10-06 12:09:50 -0700663 BREAK_ON_READ_ERROR(reader);
664
Robert Phillipsb2526042016-09-26 09:00:36 -0400665 if (text.text()) {
666 canvas->drawTextRSXform(text.text(), text.length(), xform, cull, *paint);
667 }
reed45561a02016-07-07 12:47:17 -0700668 } break;
Mike Reedebbdec42017-03-21 09:35:45 -0400669 case DRAW_VERTICES_RETIRED_03_2017: {
robertphillips5354e4a2016-06-27 12:05:39 -0700670 const SkPaint* paint = fPictureData->getPaint(reader);
robertphillips3afef1f2014-07-08 06:12:22 -0700671 DrawVertexFlags flags = (DrawVertexFlags)reader->readInt();
Mike Reed887cdf12017-04-03 11:11:09 -0400672 SkVertices::VertexMode vmode = (SkVertices::VertexMode)reader->readInt();
robertphillips3afef1f2014-07-08 06:12:22 -0700673 int vCount = reader->readInt();
674 const SkPoint* verts = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint));
halcanary96fcdcc2015-08-27 07:41:13 -0700675 const SkPoint* texs = nullptr;
676 const SkColor* colors = nullptr;
677 const uint16_t* indices = nullptr;
robertphillips3afef1f2014-07-08 06:12:22 -0700678 int iCount = 0;
679 if (flags & DRAW_VERTICES_HAS_TEXS) {
680 texs = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint));
681 }
682 if (flags & DRAW_VERTICES_HAS_COLORS) {
683 colors = (const SkColor*)reader->skip(vCount * sizeof(SkColor));
684 }
685 if (flags & DRAW_VERTICES_HAS_INDICES) {
686 iCount = reader->readInt();
687 indices = (const uint16_t*)reader->skip(iCount * sizeof(uint16_t));
688 }
Mike Reed7d954ad2016-10-28 15:42:34 -0400689 SkBlendMode bmode = SkBlendMode::kModulate;
robertphillips3afef1f2014-07-08 06:12:22 -0700690 if (flags & DRAW_VERTICES_HAS_XFER) {
Mike Reed7d954ad2016-10-28 15:42:34 -0400691 unsigned mode = reader->readInt();
692 if (mode <= (unsigned)SkBlendMode::kLastMode) {
693 bmode = (SkBlendMode)mode;
robertphillips3afef1f2014-07-08 06:12:22 -0700694 }
robertphillips3afef1f2014-07-08 06:12:22 -0700695 }
fmalitad87bd7c2016-10-06 12:09:50 -0700696 BREAK_ON_READ_ERROR(reader);
697
robertphillips5354e4a2016-06-27 12:05:39 -0700698 if (paint) {
Mike Reede88a1cb2017-03-17 09:50:46 -0400699 canvas->drawVertices(SkVertices::MakeCopy(vmode, vCount, verts, texs, colors,
700 iCount, indices), bmode, *paint);
701 }
702 } break;
703 case DRAW_VERTICES_OBJECT: {
704 const SkPaint* paint = fPictureData->getPaint(reader);
705 const SkVertices* vertices = fPictureData->getVertices(reader);
706 SkBlendMode bmode = static_cast<SkBlendMode>(reader->readInt());
707
708 BREAK_ON_READ_ERROR(reader);
709
710 if (paint && vertices) {
711 canvas->drawVertices(vertices, bmode, *paint);
robertphillips5354e4a2016-06-27 12:05:39 -0700712 }
robertphillips3afef1f2014-07-08 06:12:22 -0700713 } break;
714 case RESTORE:
715 canvas->restore();
716 break;
fmalitad87bd7c2016-10-06 12:09:50 -0700717 case ROTATE: {
718 auto deg = reader->readScalar();
719 BREAK_ON_READ_ERROR(reader);
720
721 canvas->rotate(deg);
722 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700723 case SAVE:
robertphillips3afef1f2014-07-08 06:12:22 -0700724 canvas->save();
725 break;
reed4960eee2015-12-18 07:09:18 -0800726 case SAVE_LAYER_SAVEFLAGS_DEPRECATED: {
robertphillips9ca06c42016-04-20 11:43:33 -0700727 SkRect storage;
728 const SkRect* boundsPtr = get_rect_ptr(reader, &storage);
robertphillips3afef1f2014-07-08 06:12:22 -0700729 const SkPaint* paint = fPictureData->getPaint(reader);
reedbada1882015-12-21 13:09:44 -0800730 auto flags = SkCanvas::LegacySaveFlagsToSaveLayerFlags(reader->readInt());
fmalitad87bd7c2016-10-06 12:09:50 -0700731 BREAK_ON_READ_ERROR(reader);
732
reedbada1882015-12-21 13:09:44 -0800733 canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
reed4960eee2015-12-18 07:09:18 -0800734 } break;
reedbfd5f172016-01-07 11:28:08 -0800735 case SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016: {
robertphillips9ca06c42016-04-20 11:43:33 -0700736 SkRect storage;
737 const SkRect* boundsPtr = get_rect_ptr(reader, &storage);
reed4960eee2015-12-18 07:09:18 -0800738 const SkPaint* paint = fPictureData->getPaint(reader);
fmalitad87bd7c2016-10-06 12:09:50 -0700739 auto flags = reader->readInt();
740 BREAK_ON_READ_ERROR(reader);
741
742 canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
robertphillips3afef1f2014-07-08 06:12:22 -0700743 } break;
reedbfd5f172016-01-07 11:28:08 -0800744 case SAVE_LAYER_SAVELAYERREC: {
Florin Malita53f77bd2017-04-28 13:48:37 -0400745 SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, nullptr, nullptr, 0);
746 SkMatrix clipMatrix;
reedbfd5f172016-01-07 11:28:08 -0800747 const uint32_t flatFlags = reader->readInt();
robertphillips9ca06c42016-04-20 11:43:33 -0700748 SkRect bounds;
reedbfd5f172016-01-07 11:28:08 -0800749 if (flatFlags & SAVELAYERREC_HAS_BOUNDS) {
robertphillips9ca06c42016-04-20 11:43:33 -0700750 reader->readRect(&bounds);
751 rec.fBounds = &bounds;
reedbfd5f172016-01-07 11:28:08 -0800752 }
753 if (flatFlags & SAVELAYERREC_HAS_PAINT) {
754 rec.fPaint = fPictureData->getPaint(reader);
755 }
756 if (flatFlags & SAVELAYERREC_HAS_BACKDROP) {
fmalitad87bd7c2016-10-06 12:09:50 -0700757 if (const auto* paint = fPictureData->getPaint(reader)) {
758 rec.fBackdrop = paint->getImageFilter();
759 }
reedbfd5f172016-01-07 11:28:08 -0800760 }
761 if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
762 rec.fSaveLayerFlags = reader->readInt();
763 }
Florin Malita53f77bd2017-04-28 13:48:37 -0400764 if (flatFlags & SAVELAYERREC_HAS_CLIPMASK) {
Mike Kleinb34ab042017-05-01 21:34:14 +0000765 rec.fClipMask = fPictureData->getImage(reader);
Florin Malita53f77bd2017-04-28 13:48:37 -0400766 }
767 if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX) {
768 reader->readMatrix(&clipMatrix);
769 rec.fClipMatrix = &clipMatrix;
770 }
fmalitad87bd7c2016-10-06 12:09:50 -0700771 BREAK_ON_READ_ERROR(reader);
772
reedbfd5f172016-01-07 11:28:08 -0800773 canvas->saveLayer(rec);
774 } break;
robertphillips3afef1f2014-07-08 06:12:22 -0700775 case SCALE: {
776 SkScalar sx = reader->readScalar();
777 SkScalar sy = reader->readScalar();
fmalitad87bd7c2016-10-06 12:09:50 -0700778 BREAK_ON_READ_ERROR(reader);
779
robertphillips3afef1f2014-07-08 06:12:22 -0700780 canvas->scale(sx, sy);
781 } break;
782 case SET_MATRIX: {
783 SkMatrix matrix;
784 reader->readMatrix(&matrix);
fmalitad87bd7c2016-10-06 12:09:50 -0700785 BREAK_ON_READ_ERROR(reader);
786
robertphillips3afef1f2014-07-08 06:12:22 -0700787 matrix.postConcat(initialMatrix);
788 canvas->setMatrix(matrix);
789 } break;
790 case SKEW: {
791 SkScalar sx = reader->readScalar();
792 SkScalar sy = reader->readScalar();
fmalitad87bd7c2016-10-06 12:09:50 -0700793 BREAK_ON_READ_ERROR(reader);
794
robertphillips3afef1f2014-07-08 06:12:22 -0700795 canvas->skew(sx, sy);
796 } break;
797 case TRANSLATE: {
798 SkScalar dx = reader->readScalar();
799 SkScalar dy = reader->readScalar();
fmalitad87bd7c2016-10-06 12:09:50 -0700800 BREAK_ON_READ_ERROR(reader);
801
robertphillips3afef1f2014-07-08 06:12:22 -0700802 canvas->translate(dx, dy);
803 } break;
804 default:
mtklein46616af2014-09-30 14:47:10 -0700805 SkASSERTF(false, "Unknown draw type: %d", op);
robertphillipsce4dd3d2014-07-07 13:46:35 -0700806 }
fmalitad87bd7c2016-10-06 12:09:50 -0700807
808#undef BREAK_ON_READ_ERROR
robertphillipsce4dd3d2014-07-07 13:46:35 -0700809}