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(®ion);
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(¢er);
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(®ion);
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