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 "SkCanvasPriv.h"
10 #include "SkDrawShadowInfo.h"
11 #include "SkFontPriv.h"
12 #include "SkPaintPriv.h"
13 #include "SkPatchUtils.h"
14 #include "SkPictureData.h"
15 #include "SkPicturePlayback.h"
16 #include "SkPictureRecord.h"
17 #include "SkReadBuffer.h"
18 #include "SkRSXform.h"
19 #include "SkSafeMath.h"
20 #include "SkTextBlob.h"
21 #include "SkTDArray.h"
22 #include "SkTypes.h"
23 
24 // matches old SkCanvas::SaveFlags
25 enum LegacySaveFlags {
26     kClipToLayer_LegacySaveFlags      = 0x10,
27 };
28 
LegacySaveFlagsToSaveLayerFlags(uint32_t flags)29 SkCanvas::SaveLayerFlags SkCanvasPriv::LegacySaveFlagsToSaveLayerFlags(uint32_t flags) {
30     uint32_t layerFlags = 0;
31 
32     if (0 == (flags & kClipToLayer_LegacySaveFlags)) {
33         layerFlags |= kDontClipToLayer_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 
draw(SkCanvas * canvas,SkPicture::AbortCallback * callback,SkReadBuffer * buffer)71 void SkPicturePlayback::draw(SkCanvas* canvas,
72                              SkPicture::AbortCallback* callback,
73                              SkReadBuffer* buffer) {
74     AutoResetOpID aroi(this);
75     SkASSERT(0 == fCurOffset);
76 
77     SkReadBuffer reader(fPictureData->opData()->bytes(),
78                         fPictureData->opData()->size());
79 
80     // Record this, so we can concat w/ it if we encounter a setMatrix()
81     SkMatrix initialMatrix = canvas->getTotalMatrix();
82 
83     SkAutoCanvasRestore acr(canvas, false);
84 
85     while (!reader.eof()) {
86         if (callback && callback->abort()) {
87             return;
88         }
89 
90         fCurOffset = reader.offset();
91         uint32_t size;
92         DrawType op = ReadOpAndSize(&reader, &size);
93         if (!reader.validate(op > UNUSED && op <= LAST_DRAWTYPE_ENUM)) {
94             return;
95         }
96 
97         this->handleOp(&reader, op, size, canvas, initialMatrix);
98     }
99 
100     // need to propagate invalid state to the parent reader
101     if (buffer) {
102         buffer->validate(reader.isValid());
103     }
104 }
105 
validate_offsetToRestore(SkReadBuffer * reader,size_t offsetToRestore)106 static void validate_offsetToRestore(SkReadBuffer* reader, size_t offsetToRestore) {
107     if (offsetToRestore) {
108         reader->validate(SkIsAlign4(offsetToRestore) && offsetToRestore >= reader->offset());
109     }
110 }
111 
handleOp(SkReadBuffer * reader,DrawType op,uint32_t size,SkCanvas * canvas,const SkMatrix & initialMatrix)112 void SkPicturePlayback::handleOp(SkReadBuffer* reader,
113                                  DrawType op,
114                                  uint32_t size,
115                                  SkCanvas* canvas,
116                                  const SkMatrix& initialMatrix) {
117 #define BREAK_ON_READ_ERROR(r) if (!r->isValid()) break
118 
119     switch (op) {
120         case NOOP: {
121             SkASSERT(size >= 4);
122             reader->skip(size - 4);
123         } break;
124         case FLUSH:
125             canvas->flush();
126             break;
127         case CLIP_PATH: {
128             const SkPath& path = fPictureData->getPath(reader);
129             uint32_t packed = reader->readInt();
130             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
131             bool doAA = ClipParams_unpackDoAA(packed);
132             size_t offsetToRestore = reader->readInt();
133             validate_offsetToRestore(reader, offsetToRestore);
134             BREAK_ON_READ_ERROR(reader);
135 
136             canvas->clipPath(path, clipOp, doAA);
137             if (canvas->isClipEmpty() && offsetToRestore) {
138                 reader->skip(offsetToRestore - reader->offset());
139             }
140         } break;
141         case CLIP_REGION: {
142             SkRegion region;
143             reader->readRegion(&region);
144             uint32_t packed = reader->readInt();
145             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
146             size_t offsetToRestore = reader->readInt();
147             validate_offsetToRestore(reader, offsetToRestore);
148             BREAK_ON_READ_ERROR(reader);
149 
150             canvas->clipRegion(region, clipOp);
151             if (canvas->isClipEmpty() && offsetToRestore) {
152                 reader->skip(offsetToRestore - reader->offset());
153             }
154         } break;
155         case CLIP_RECT: {
156             SkRect rect;
157             reader->readRect(&rect);
158             uint32_t packed = reader->readInt();
159             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
160             bool doAA = ClipParams_unpackDoAA(packed);
161             size_t offsetToRestore = reader->readInt();
162             validate_offsetToRestore(reader, offsetToRestore);
163             BREAK_ON_READ_ERROR(reader);
164 
165             canvas->clipRect(rect, clipOp, doAA);
166             if (canvas->isClipEmpty() && offsetToRestore) {
167                 reader->skip(offsetToRestore - reader->offset());
168             }
169         } break;
170         case CLIP_RRECT: {
171             SkRRect rrect;
172             reader->readRRect(&rrect);
173             uint32_t packed = reader->readInt();
174             SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
175             bool doAA = ClipParams_unpackDoAA(packed);
176             size_t offsetToRestore = reader->readInt();
177             validate_offsetToRestore(reader, offsetToRestore);
178             BREAK_ON_READ_ERROR(reader);
179 
180             canvas->clipRRect(rrect, clipOp, doAA);
181             if (canvas->isClipEmpty() && offsetToRestore) {
182                 reader->skip(offsetToRestore - reader->offset());
183             }
184         } break;
185         case PUSH_CULL: break;  // Deprecated, safe to ignore both push and pop.
186         case POP_CULL:  break;
187         case CONCAT: {
188             SkMatrix matrix;
189             reader->readMatrix(&matrix);
190             BREAK_ON_READ_ERROR(reader);
191 
192             canvas->concat(matrix);
193             break;
194         }
195         case DRAW_ANNOTATION: {
196             SkRect rect;
197             reader->readRect(&rect);
198             SkString key;
199             reader->readString(&key);
200             sk_sp<SkData> data = reader->readByteArrayAsData();
201             BREAK_ON_READ_ERROR(reader);
202             SkASSERT(data);
203 
204             canvas->drawAnnotation(rect, key.c_str(), data.get());
205         } break;
206         case DRAW_ARC: {
207             const SkPaint* paint = fPictureData->getPaint(reader);
208             SkRect rect;
209             reader->readRect(&rect);
210             SkScalar startAngle = reader->readScalar();
211             SkScalar sweepAngle = reader->readScalar();
212             int useCenter = reader->readInt();
213             BREAK_ON_READ_ERROR(reader);
214 
215             if (paint) {
216                 canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), *paint);
217             }
218         } break;
219         case DRAW_ATLAS: {
220             const SkPaint* paint = fPictureData->getPaint(reader);
221             const SkImage* atlas = fPictureData->getImage(reader);
222             const uint32_t flags = reader->readUInt();
223             const int count = reader->readUInt();
224             const SkRSXform* xform = (const SkRSXform*)reader->skip(count, sizeof(SkRSXform));
225             const SkRect* tex = (const SkRect*)reader->skip(count, sizeof(SkRect));
226             const SkColor* colors = nullptr;
227             SkBlendMode mode = SkBlendMode::kDst;
228             if (flags & DRAW_ATLAS_HAS_COLORS) {
229                 colors = (const SkColor*)reader->skip(count, sizeof(SkColor));
230                 mode = (SkBlendMode)reader->readUInt();
231             }
232             const SkRect* cull = nullptr;
233             if (flags & DRAW_ATLAS_HAS_CULL) {
234                 cull = (const SkRect*)reader->skip(sizeof(SkRect));
235             }
236             BREAK_ON_READ_ERROR(reader);
237 
238             canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
239         } break;
240         case DRAW_CLEAR: {
241             auto c = reader->readInt();
242             BREAK_ON_READ_ERROR(reader);
243 
244             canvas->clear(c);
245         } break;
246         case DRAW_DATA: {
247             // This opcode is now dead, just need to skip it for backwards compatibility
248             size_t length = reader->readInt();
249             (void)reader->skip(length);
250             // skip handles padding the read out to a multiple of 4
251         } break;
252         case DRAW_DRAWABLE: {
253             auto* d = fPictureData->getDrawable(reader);
254             BREAK_ON_READ_ERROR(reader);
255 
256             canvas->drawDrawable(d);
257         } break;
258         case DRAW_DRAWABLE_MATRIX: {
259             SkMatrix matrix;
260             reader->readMatrix(&matrix);
261             SkDrawable* drawable = fPictureData->getDrawable(reader);
262             BREAK_ON_READ_ERROR(reader);
263 
264             canvas->drawDrawable(drawable, &matrix);
265         } break;
266         case DRAW_DRRECT: {
267             const SkPaint* paint = fPictureData->getPaint(reader);
268             SkRRect outer, inner;
269             reader->readRRect(&outer);
270             reader->readRRect(&inner);
271             BREAK_ON_READ_ERROR(reader);
272 
273             if (paint) {
274                 canvas->drawDRRect(outer, inner, *paint);
275             }
276         } break;
277         case DRAW_EDGEAA_RECT: {
278             SkRect rect;
279             reader->readRect(&rect);
280             SkCanvas::QuadAAFlags aaFlags = static_cast<SkCanvas::QuadAAFlags>(reader->read32());
281             SkColor color = reader->read32();
282             SkBlendMode blend = static_cast<SkBlendMode>(reader->read32());
283             BREAK_ON_READ_ERROR(reader);
284 
285             canvas->experimental_DrawEdgeAARectV1(rect, aaFlags, color, blend);
286         } break;
287         case DRAW_IMAGE: {
288             const SkPaint* paint = fPictureData->getPaint(reader);
289             const SkImage* image = fPictureData->getImage(reader);
290             SkPoint loc;
291             reader->readPoint(&loc);
292             BREAK_ON_READ_ERROR(reader);
293 
294             canvas->drawImage(image, loc.fX, loc.fY, paint);
295         } break;
296         case DRAW_IMAGE_LATTICE: {
297             const SkPaint* paint = fPictureData->getPaint(reader);
298             const SkImage* image = fPictureData->getImage(reader);
299             SkCanvas::Lattice lattice;
300             (void)SkCanvasPriv::ReadLattice(*reader, &lattice);
301             const SkRect* dst = reader->skipT<SkRect>();
302             BREAK_ON_READ_ERROR(reader);
303 
304             canvas->drawImageLattice(image, lattice, *dst, paint);
305         } break;
306         case DRAW_IMAGE_NINE: {
307             const SkPaint* paint = fPictureData->getPaint(reader);
308             const SkImage* image = fPictureData->getImage(reader);
309             SkIRect center;
310             reader->readIRect(&center);
311             SkRect dst;
312             reader->readRect(&dst);
313             BREAK_ON_READ_ERROR(reader);
314 
315             canvas->drawImageNine(image, center, dst, paint);
316         } break;
317         case DRAW_IMAGE_RECT: {
318             const SkPaint* paint = fPictureData->getPaint(reader);
319             const SkImage* image = fPictureData->getImage(reader);
320             SkRect storage;
321             const SkRect* src = get_rect_ptr(reader, &storage);   // may be null
322             SkRect dst;
323             reader->readRect(&dst);     // required
324             // DRAW_IMAGE_RECT_STRICT assumes this constraint, and doesn't store it
325             SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint;
326             if (DRAW_IMAGE_RECT == op) {
327                 // newer op-code stores the constraint explicitly
328                 constraint = (SkCanvas::SrcRectConstraint)reader->readInt();
329             }
330             BREAK_ON_READ_ERROR(reader);
331 
332             canvas->legacy_drawImageRect(image, src, dst, paint, constraint);
333         } break;
334         case DRAW_IMAGE_SET: {
335             int cnt = reader->readInt();
336             if (!reader->validate(cnt >= 0)) {
337                 break;
338             }
339             SkFilterQuality filterQuality = (SkFilterQuality)reader->readUInt();
340             SkBlendMode mode = (SkBlendMode)reader->readUInt();
341             SkAutoTArray<SkCanvas::ImageSetEntry> set(cnt);
342             for (int i = 0; i < cnt; ++i) {
343                 set[i].fImage = sk_ref_sp(fPictureData->getImage(reader));
344                 reader->readRect(&set[i].fSrcRect);
345                 reader->readRect(&set[i].fDstRect);
346                 set[i].fAlpha = reader->readScalar();
347                 set[i].fAAFlags = reader->readUInt();
348             }
349             BREAK_ON_READ_ERROR(reader);
350 
351             canvas->experimental_DrawImageSetV1(set.get(), cnt, filterQuality, mode);
352         } break;
353         case DRAW_OVAL: {
354             const SkPaint* paint = fPictureData->getPaint(reader);
355             SkRect rect;
356             reader->readRect(&rect);
357             BREAK_ON_READ_ERROR(reader);
358 
359             if (paint) {
360                 canvas->drawOval(rect, *paint);
361             }
362         } break;
363         case DRAW_PAINT: {
364             const SkPaint* paint = fPictureData->getPaint(reader);
365             BREAK_ON_READ_ERROR(reader);
366 
367             if (paint) {
368                 canvas->drawPaint(*paint);
369             }
370         } break;
371         case DRAW_PATCH: {
372             const SkPaint* paint = fPictureData->getPaint(reader);
373 
374             const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts,
375                                                                  sizeof(SkPoint));
376             uint32_t flag = reader->readInt();
377             const SkColor* colors = nullptr;
378             if (flag & DRAW_VERTICES_HAS_COLORS) {
379                 colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners, sizeof(SkColor));
380             }
381             const SkPoint* texCoords = nullptr;
382             if (flag & DRAW_VERTICES_HAS_TEXS) {
383                 texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners,
384                                                          sizeof(SkPoint));
385             }
386             SkBlendMode bmode = SkBlendMode::kModulate;
387             if (flag & DRAW_VERTICES_HAS_XFER) {
388                 unsigned mode = reader->readInt();
389                 if (mode <= (unsigned)SkBlendMode::kLastMode) {
390                     bmode = (SkBlendMode)mode;
391                 }
392             }
393             BREAK_ON_READ_ERROR(reader);
394 
395             if (paint) {
396                 canvas->drawPatch(cubics, colors, texCoords, bmode, *paint);
397             }
398         } break;
399         case DRAW_PATH: {
400             const SkPaint* paint = fPictureData->getPaint(reader);
401             const auto& path = fPictureData->getPath(reader);
402             BREAK_ON_READ_ERROR(reader);
403 
404             if (paint) {
405                 canvas->drawPath(path, *paint);
406             }
407         } break;
408         case DRAW_PICTURE: {
409             const auto* pic = fPictureData->getPicture(reader);
410             BREAK_ON_READ_ERROR(reader);
411 
412             canvas->drawPicture(pic);
413         } break;
414         case DRAW_PICTURE_MATRIX_PAINT: {
415             const SkPaint* paint = fPictureData->getPaint(reader);
416             SkMatrix matrix;
417             reader->readMatrix(&matrix);
418             const SkPicture* pic = fPictureData->getPicture(reader);
419             BREAK_ON_READ_ERROR(reader);
420 
421             canvas->drawPicture(pic, &matrix, paint);
422         } break;
423         case DRAW_POINTS: {
424             const SkPaint* paint = fPictureData->getPaint(reader);
425             SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt();
426             size_t count = reader->readInt();
427             const SkPoint* pts = (const SkPoint*)reader->skip(count, sizeof(SkPoint));
428             BREAK_ON_READ_ERROR(reader);
429 
430             if (paint) {
431                 canvas->drawPoints(mode, count, pts, *paint);
432             }
433         } break;
434         case DRAW_RECT: {
435             const SkPaint* paint = fPictureData->getPaint(reader);
436             SkRect rect;
437             reader->readRect(&rect);
438             BREAK_ON_READ_ERROR(reader);
439 
440             if (paint) {
441                 canvas->drawRect(rect, *paint);
442             }
443         } break;
444         case DRAW_REGION: {
445             const SkPaint* paint = fPictureData->getPaint(reader);
446             SkRegion region;
447             reader->readRegion(&region);
448             BREAK_ON_READ_ERROR(reader);
449 
450             if (paint) {
451                 canvas->drawRegion(region, *paint);
452             }
453         } break;
454         case DRAW_RRECT: {
455             const SkPaint* paint = fPictureData->getPaint(reader);
456             SkRRect rrect;
457             reader->readRRect(&rrect);
458             BREAK_ON_READ_ERROR(reader);
459 
460             if (paint) {
461                 canvas->drawRRect(rrect, *paint);
462             }
463         } break;
464         case DRAW_SHADOW_REC: {
465             const auto& path = fPictureData->getPath(reader);
466             SkDrawShadowRec rec;
467             reader->readPoint3(&rec.fZPlaneParams);
468             reader->readPoint3(&rec.fLightPos);
469             rec.fLightRadius = reader->readScalar();
470             if (reader->isVersionLT(SkReadBuffer::kTwoColorDrawShadow_Version)) {
471                 SkScalar ambientAlpha = reader->readScalar();
472                 SkScalar spotAlpha = reader->readScalar();
473                 SkColor color = reader->read32();
474                 rec.fAmbientColor = SkColorSetA(color, SkColorGetA(color)*ambientAlpha);
475                 rec.fSpotColor = SkColorSetA(color, SkColorGetA(color)*spotAlpha);
476             } else {
477                 rec.fAmbientColor = reader->read32();
478                 rec.fSpotColor = reader->read32();
479             }
480             rec.fFlags = reader->read32();
481             BREAK_ON_READ_ERROR(reader);
482 
483             canvas->private_draw_shadow_rec(path, rec);
484         } break;
485         case DRAW_TEXT_BLOB: {
486             const SkPaint* paint = fPictureData->getPaint(reader);
487             const SkTextBlob* blob = fPictureData->getTextBlob(reader);
488             SkScalar x = reader->readScalar();
489             SkScalar y = reader->readScalar();
490             BREAK_ON_READ_ERROR(reader);
491 
492             if (paint) {
493                 canvas->drawTextBlob(blob, x, y, *paint);
494             }
495         } break;
496         case DRAW_VERTICES_OBJECT: {
497             const SkPaint* paint = fPictureData->getPaint(reader);
498             const SkVertices* vertices = fPictureData->getVertices(reader);
499             const int boneCount = reader->readInt();
500             const SkVertices::Bone* bones = boneCount ?
501                     (const SkVertices::Bone*) reader->skip(boneCount, sizeof(SkVertices::Bone)) :
502                     nullptr;
503             SkBlendMode bmode = reader->read32LE(SkBlendMode::kLastMode);
504             BREAK_ON_READ_ERROR(reader);
505 
506             if (paint && vertices) {
507                 canvas->drawVertices(vertices, bones, boneCount, bmode, *paint);
508             }
509         } break;
510         case RESTORE:
511             canvas->restore();
512             break;
513         case ROTATE: {
514             auto deg = reader->readScalar();
515             canvas->rotate(deg);
516         } break;
517         case SAVE:
518             canvas->save();
519             break;
520         case SAVE_BEHIND: {
521             uint32_t flags = reader->readInt();
522             const SkRect* subset = nullptr;
523             SkRect storage;
524             if (flags & SAVEBEHIND_HAS_SUBSET) {
525                 reader->readRect(&storage);
526                 subset = &storage;
527             }
528             SkCanvasPriv::SaveBehind(canvas, subset);
529         } break;
530         case SAVE_LAYER_SAVEFLAGS_DEPRECATED: {
531             SkRect storage;
532             const SkRect* boundsPtr = get_rect_ptr(reader, &storage);
533             const SkPaint* paint = fPictureData->getPaint(reader);
534             auto flags = SkCanvasPriv::LegacySaveFlagsToSaveLayerFlags(reader->readInt());
535             BREAK_ON_READ_ERROR(reader);
536 
537             canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags));
538         } break;
539         case SAVE_LAYER_SAVELAYERREC: {
540             SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, nullptr, nullptr, 0);
541             SkMatrix clipMatrix;
542             const uint32_t flatFlags = reader->readInt();
543             SkRect bounds;
544             if (flatFlags & SAVELAYERREC_HAS_BOUNDS) {
545                 reader->readRect(&bounds);
546                 rec.fBounds = &bounds;
547             }
548             if (flatFlags & SAVELAYERREC_HAS_PAINT) {
549                 rec.fPaint = fPictureData->getPaint(reader);
550             }
551             if (flatFlags & SAVELAYERREC_HAS_BACKDROP) {
552                 if (const auto* paint = fPictureData->getPaint(reader)) {
553                     rec.fBackdrop = paint->getImageFilter();
554                 }
555             }
556             if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
557                 rec.fSaveLayerFlags = reader->readInt();
558             }
559             if (flatFlags & SAVELAYERREC_HAS_CLIPMASK) {
560                 rec.fClipMask = fPictureData->getImage(reader);
561             }
562             if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX) {
563                 reader->readMatrix(&clipMatrix);
564                 rec.fClipMatrix = &clipMatrix;
565             }
566             BREAK_ON_READ_ERROR(reader);
567 
568             canvas->saveLayer(rec);
569         } break;
570         case SCALE: {
571             SkScalar sx = reader->readScalar();
572             SkScalar sy = reader->readScalar();
573             canvas->scale(sx, sy);
574         } break;
575         case SET_MATRIX: {
576             SkMatrix matrix;
577             reader->readMatrix(&matrix);
578             matrix.postConcat(initialMatrix);
579             canvas->setMatrix(matrix);
580         } break;
581         case SKEW: {
582             SkScalar sx = reader->readScalar();
583             SkScalar sy = reader->readScalar();
584             canvas->skew(sx, sy);
585         } break;
586         case TRANSLATE: {
587             SkScalar dx = reader->readScalar();
588             SkScalar dy = reader->readScalar();
589             canvas->translate(dx, dy);
590         } break;
591         default:
592             reader->validate(false);    // unknown op
593             break;
594     }
595 
596 #undef BREAK_ON_READ_ERROR
597 }
598