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