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 "include/core/SkCanvas.h" 9#include "include/core/SkRSXform.h" 10#include "include/core/SkTextBlob.h" 11#include "include/core/SkTypes.h" 12#include "include/private/SkTDArray.h" 13#include "src/core/SkCanvasPriv.h" 14#include "src/core/SkDrawShadowInfo.h" 15#include "src/core/SkFontPriv.h" 16#include "src/core/SkPaintPriv.h" 17#include "src/core/SkPictureData.h" 18#include "src/core/SkPicturePlayback.h" 19#include "src/core/SkPictureRecord.h" 20#include "src/core/SkReadBuffer.h" 21#include "src/core/SkSafeMath.h" 22#include "src/core/SkSamplingPriv.h" 23#include "src/core/SkVerticesPriv.h" 24#include "src/utils/SkPatchUtils.h" 25 26static const SkRect* get_rect_ptr(SkReadBuffer* reader, SkRect* storage) { 27 if (reader->readBool()) { 28 reader->readRect(storage); 29 return storage; 30 } else { 31 return nullptr; 32 } 33} 34 35void SkPicturePlayback::draw(SkCanvas* canvas, 36 SkPicture::AbortCallback* callback, 37 SkReadBuffer* buffer) { 38 AutoResetOpID aroi(this); 39 SkASSERT(0 == fCurOffset); 40 41 SkReadBuffer reader(fPictureData->opData()->bytes(), 42 fPictureData->opData()->size()); 43 44 // Record this, so we can concat w/ it if we encounter a setMatrix() 45 SkM44 initialMatrix = canvas->getLocalToDevice(); 46 47 SkAutoCanvasRestore acr(canvas, false); 48 49 while (!reader.eof() && reader.isValid()) { 50 if (callback && callback->abort()) { 51 return; 52 } 53 54 fCurOffset = reader.offset(); 55 56 uint32_t bits = reader.readInt(); 57 uint32_t op = bits >> 24, 58 size = bits & 0xffffff; 59 if (size == 0xffffff) { 60 size = reader.readInt(); 61 } 62 63 if (!reader.validate(size > 0 && op > UNUSED && op <= LAST_DRAWTYPE_ENUM)) { 64 return; 65 } 66 67 this->handleOp(&reader, (DrawType)op, size, canvas, initialMatrix); 68 } 69 70 // need to propagate invalid state to the parent reader 71 if (buffer) { 72 buffer->validate(reader.isValid()); 73 } 74} 75 76static void validate_offsetToRestore(SkReadBuffer* reader, size_t offsetToRestore) { 77 if (offsetToRestore) { 78 reader->validate(SkIsAlign4(offsetToRestore) && offsetToRestore >= reader->offset()); 79 } 80} 81 82static bool do_clip_op(SkReadBuffer* reader, SkCanvas* canvas, SkRegion::Op op, 83 SkClipOp* clipOpToUse) { 84 switch(op) { 85 case SkRegion::kDifference_Op: 86 case SkRegion::kIntersect_Op: 87 // Fully supported, identity mapping between SkClipOp and Region::Op 88 *clipOpToUse = static_cast<SkClipOp>(op); 89 return true; 90 case SkRegion::kReplace_Op: 91 // Emulate the replace by resetting first and following it up with an intersect 92 SkASSERT(reader->isVersionLT(SkPicturePriv::kNoExpandingClipOps)); 93 SkCanvasPriv::ResetClip(canvas); 94 *clipOpToUse = SkClipOp::kIntersect; 95 return true; 96 default: 97 // An expanding clip op, which if encountered on an old SKP, we just silently ignore 98 SkASSERT(reader->isVersionLT(SkPicturePriv::kNoExpandingClipOps)); 99 return false; 100 } 101} 102 103void SkPicturePlayback::handleOp(SkReadBuffer* reader, 104 DrawType op, 105 uint32_t size, 106 SkCanvas* canvas, 107 const SkM44& initialMatrix) { 108#define BREAK_ON_READ_ERROR(r) if (!r->isValid()) break 109 110 switch (op) { 111 case NOOP: { 112 SkASSERT(size >= 4); 113 reader->skip(size - 4); 114 } break; 115 case FLUSH: 116 canvas->flush(); 117 break; 118 case CLIP_PATH: { 119 const SkPath& path = fPictureData->getPath(reader); 120 uint32_t packed = reader->readInt(); 121 SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed); 122 bool doAA = ClipParams_unpackDoAA(packed); 123 size_t offsetToRestore = reader->readInt(); 124 validate_offsetToRestore(reader, offsetToRestore); 125 BREAK_ON_READ_ERROR(reader); 126 127 SkClipOp clipOp; 128 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 129 canvas->clipPath(path, clipOp, doAA); 130 } 131 if (canvas->isClipEmpty() && offsetToRestore) { 132 reader->skip(offsetToRestore - reader->offset()); 133 } 134 } break; 135 case CLIP_REGION: { 136 SkRegion region; 137 reader->readRegion(®ion); 138 uint32_t packed = reader->readInt(); 139 SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed); 140 size_t offsetToRestore = reader->readInt(); 141 validate_offsetToRestore(reader, offsetToRestore); 142 BREAK_ON_READ_ERROR(reader); 143 144 SkClipOp clipOp; 145 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 146 canvas->clipRegion(region, clipOp); 147 } 148 if (canvas->isClipEmpty() && offsetToRestore) { 149 reader->skip(offsetToRestore - reader->offset()); 150 } 151 } break; 152 case CLIP_RECT: { 153 SkRect rect; 154 reader->readRect(&rect); 155 uint32_t packed = reader->readInt(); 156 SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed); 157 bool doAA = ClipParams_unpackDoAA(packed); 158 size_t offsetToRestore = reader->readInt(); 159 validate_offsetToRestore(reader, offsetToRestore); 160 BREAK_ON_READ_ERROR(reader); 161 162 SkClipOp clipOp; 163 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 164 canvas->clipRect(rect, clipOp, doAA); 165 } 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 SkRegion::Op rgnOp = 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 SkClipOp clipOp; 181 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 182 canvas->clipRRect(rrect, clipOp, doAA); 183 } 184 if (canvas->isClipEmpty() && offsetToRestore) { 185 reader->skip(offsetToRestore - reader->offset()); 186 } 187 } break; 188 case CLIP_SHADER_IN_PAINT: { 189 const SkPaint& paint = fPictureData->requiredPaint(reader); 190 // clipShader() was never used in conjunction with deprecated, expanding clip ops, so 191 // it requires the op to just be intersect or difference. 192 SkClipOp clipOp = reader->checkRange(SkClipOp::kDifference, SkClipOp::kIntersect); 193 BREAK_ON_READ_ERROR(reader); 194 195 canvas->clipShader(paint.refShader(), clipOp); 196 } break; 197 case RESET_CLIP: 198 // For Android, an emulated "replace" clip op appears as a manual reset followed by 199 // an intersect operation (equivalent to the above handling of replace ops encountered 200 // in old serialized pictures). 201 SkCanvasPriv::ResetClip(canvas); 202 break; 203 case PUSH_CULL: break; // Deprecated, safe to ignore both push and pop. 204 case POP_CULL: break; 205 case CONCAT: { 206 SkMatrix matrix; 207 reader->readMatrix(&matrix); 208 BREAK_ON_READ_ERROR(reader); 209 210 canvas->concat(matrix); 211 break; 212 } 213 case CONCAT44: { 214 const SkScalar* colMaj = reader->skipT<SkScalar>(16); 215 BREAK_ON_READ_ERROR(reader); 216 canvas->concat(SkM44::ColMajor(colMaj)); 217 break; 218 } 219 case DRAW_ANNOTATION: { 220 SkRect rect; 221 reader->readRect(&rect); 222 SkString key; 223 reader->readString(&key); 224 sk_sp<SkData> data = reader->readByteArrayAsData(); 225 BREAK_ON_READ_ERROR(reader); 226 SkASSERT(data); 227 228 canvas->drawAnnotation(rect, key.c_str(), data.get()); 229 } break; 230 case DRAW_ARC: { 231 const SkPaint& paint = fPictureData->requiredPaint(reader); 232 SkRect rect; 233 reader->readRect(&rect); 234 SkScalar startAngle = reader->readScalar(); 235 SkScalar sweepAngle = reader->readScalar(); 236 int useCenter = reader->readInt(); 237 BREAK_ON_READ_ERROR(reader); 238 239 canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), paint); 240 } break; 241 case DRAW_ATLAS: { 242 const SkPaint* paint = fPictureData->optionalPaint(reader); 243 const SkImage* atlas = fPictureData->getImage(reader); 244 const uint32_t flags = reader->readUInt(); 245 const int count = reader->readUInt(); 246 const SkRSXform* xform = (const SkRSXform*)reader->skip(count, sizeof(SkRSXform)); 247 const SkRect* tex = (const SkRect*)reader->skip(count, sizeof(SkRect)); 248 const SkColor* colors = nullptr; 249 SkBlendMode mode = SkBlendMode::kDst; 250 if (flags & DRAW_ATLAS_HAS_COLORS) { 251 colors = (const SkColor*)reader->skip(count, sizeof(SkColor)); 252 mode = (SkBlendMode)reader->readUInt(); 253 } 254 const SkRect* cull = nullptr; 255 if (flags & DRAW_ATLAS_HAS_CULL) { 256 cull = (const SkRect*)reader->skip(sizeof(SkRect)); 257 } 258 BREAK_ON_READ_ERROR(reader); 259 260 SkSamplingOptions sampling; 261 if (flags & DRAW_ATLAS_HAS_SAMPLING) { 262 sampling = reader->readSampling(); 263 BREAK_ON_READ_ERROR(reader); 264 } 265 canvas->drawAtlas(atlas, xform, tex, colors, count, mode, sampling, cull, paint); 266 } break; 267 case DRAW_CLEAR: { 268 auto c = reader->readInt(); 269 BREAK_ON_READ_ERROR(reader); 270 271 canvas->clear(c); 272 } break; 273 case DRAW_DATA: { 274 // This opcode is now dead, just need to skip it for backwards compatibility 275 size_t length = reader->readInt(); 276 (void)reader->skip(length); 277 // skip handles padding the read out to a multiple of 4 278 } break; 279 case DRAW_DRAWABLE: { 280 auto* d = fPictureData->getDrawable(reader); 281 BREAK_ON_READ_ERROR(reader); 282 283 canvas->drawDrawable(d); 284 } break; 285 case DRAW_DRAWABLE_MATRIX: { 286 SkMatrix matrix; 287 reader->readMatrix(&matrix); 288 SkDrawable* drawable = fPictureData->getDrawable(reader); 289 BREAK_ON_READ_ERROR(reader); 290 291 canvas->drawDrawable(drawable, &matrix); 292 } break; 293 case DRAW_DRRECT: { 294 const SkPaint& paint = fPictureData->requiredPaint(reader); 295 SkRRect outer, inner; 296 reader->readRRect(&outer); 297 reader->readRRect(&inner); 298 BREAK_ON_READ_ERROR(reader); 299 300 canvas->drawDRRect(outer, inner, paint); 301 } break; 302 case DRAW_EDGEAA_QUAD: { 303 SkRect rect; 304 reader->readRect(&rect); 305 SkCanvas::QuadAAFlags aaFlags = static_cast<SkCanvas::QuadAAFlags>(reader->read32()); 306 SkColor4f color; 307 reader->readColor4f(&color); 308 SkBlendMode blend = static_cast<SkBlendMode>(reader->read32()); 309 bool hasClip = reader->readInt(); 310 SkPoint* clip = nullptr; 311 if (hasClip) { 312 clip = (SkPoint*) reader->skip(4, sizeof(SkPoint)); 313 } 314 BREAK_ON_READ_ERROR(reader); 315 canvas->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, color, blend); 316 } break; 317 case DRAW_EDGEAA_IMAGE_SET: 318 case DRAW_EDGEAA_IMAGE_SET2: { 319 static const size_t kEntryReadSize = 320 4 * sizeof(uint32_t) + 2 * sizeof(SkRect) + sizeof(SkScalar); 321 static const size_t kMatrixSize = 9 * sizeof(SkScalar); // != sizeof(SkMatrix) 322 323 int cnt = reader->readInt(); 324 if (!reader->validate(cnt >= 0)) { 325 break; 326 } 327 const SkPaint* paint = fPictureData->optionalPaint(reader); 328 329 SkSamplingOptions sampling; 330 if (op == DRAW_EDGEAA_IMAGE_SET2) { 331 sampling = reader->readSampling(); 332 } else { 333 sampling = SkSamplingOptions(SkFilterMode::kNearest); 334 } 335 336 SkCanvas::SrcRectConstraint constraint = 337 reader->checkRange(SkCanvas::kStrict_SrcRectConstraint, 338 SkCanvas::kFast_SrcRectConstraint); 339 340 if (!reader->validate(SkSafeMath::Mul(cnt, kEntryReadSize) <= reader->available())) { 341 break; 342 } 343 344 // Track minimum necessary clip points and matrices that must be provided to satisfy 345 // the entries. 346 int expectedClips = 0; 347 int maxMatrixIndex = -1; 348 SkAutoTArray<SkCanvas::ImageSetEntry> set(cnt); 349 for (int i = 0; i < cnt && reader->isValid(); ++i) { 350 set[i].fImage = sk_ref_sp(fPictureData->getImage(reader)); 351 reader->readRect(&set[i].fSrcRect); 352 reader->readRect(&set[i].fDstRect); 353 set[i].fMatrixIndex = reader->readInt(); 354 set[i].fAlpha = reader->readScalar(); 355 set[i].fAAFlags = reader->readUInt(); 356 set[i].fHasClip = reader->readInt(); 357 358 expectedClips += set[i].fHasClip ? 1 : 0; 359 if (set[i].fMatrixIndex > maxMatrixIndex) { 360 maxMatrixIndex = set[i].fMatrixIndex; 361 } 362 } 363 364 int dstClipCount = reader->readInt(); 365 SkPoint* dstClips = nullptr; 366 if (!reader->validate(expectedClips <= dstClipCount)) { 367 // Entries request more dstClip points than are provided in the buffer 368 break; 369 } else if (dstClipCount > 0) { 370 dstClips = (SkPoint*) reader->skip(dstClipCount, sizeof(SkPoint)); 371 if (dstClips == nullptr) { 372 // Not enough bytes remaining so the reader has been invalidated 373 break; 374 } 375 } 376 int matrixCount = reader->readInt(); 377 if (!reader->validate((maxMatrixIndex + 1) <= matrixCount) || 378 !reader->validate( 379 SkSafeMath::Mul(matrixCount, kMatrixSize) <= reader->available())) { 380 // Entries access out-of-bound matrix indices, given provided matrices or 381 // there aren't enough bytes to provide that many matrices 382 break; 383 } 384 SkTArray<SkMatrix> matrices(matrixCount); 385 for (int i = 0; i < matrixCount && reader->isValid(); ++i) { 386 reader->readMatrix(&matrices.push_back()); 387 } 388 BREAK_ON_READ_ERROR(reader); 389 390 canvas->experimental_DrawEdgeAAImageSet(set.get(), cnt, dstClips, matrices.begin(), 391 sampling, paint, constraint); 392 } break; 393 case DRAW_IMAGE: { 394 const SkPaint* paint = fPictureData->optionalPaint(reader); 395 const SkImage* image = fPictureData->getImage(reader); 396 SkPoint loc; 397 reader->readPoint(&loc); 398 BREAK_ON_READ_ERROR(reader); 399 400 canvas->drawImage(image, loc.fX, loc.fY, 401 SkSamplingOptions(SkFilterMode::kNearest), 402 paint); 403 } break; 404 case DRAW_IMAGE2: { 405 const SkPaint* paint = fPictureData->optionalPaint(reader); 406 const SkImage* image = fPictureData->getImage(reader); 407 SkPoint loc; 408 reader->readPoint(&loc); 409 SkSamplingOptions sampling = reader->readSampling(); 410 BREAK_ON_READ_ERROR(reader); 411 412 canvas->drawImage(image, loc.fX, loc.fY, sampling, paint); 413 } break; 414 case DRAW_IMAGE_LATTICE: { 415 const SkPaint* paint = fPictureData->optionalPaint(reader); 416 const SkImage* image = fPictureData->getImage(reader); 417 SkCanvas::Lattice lattice; 418 (void)SkCanvasPriv::ReadLattice(*reader, &lattice); 419 const SkRect* dst = reader->skipT<SkRect>(); 420 BREAK_ON_READ_ERROR(reader); 421 422 canvas->drawImageLattice(image, lattice, *dst, SkFilterMode::kNearest, paint); 423 } break; 424 case DRAW_IMAGE_LATTICE2: { 425 const SkPaint* paint = fPictureData->optionalPaint(reader); 426 const SkImage* image = fPictureData->getImage(reader); 427 SkCanvas::Lattice lattice; 428 (void)SkCanvasPriv::ReadLattice(*reader, &lattice); 429 const SkRect* dst = reader->skipT<SkRect>(); 430 SkFilterMode filter = reader->read32LE(SkFilterMode::kLinear); 431 BREAK_ON_READ_ERROR(reader); 432 433 canvas->drawImageLattice(image, lattice, *dst, filter, paint); 434 } break; 435 case DRAW_IMAGE_NINE: { 436 const SkPaint* paint = fPictureData->optionalPaint(reader); 437 const SkImage* image = fPictureData->getImage(reader); 438 SkIRect center; 439 reader->readIRect(¢er); 440 SkRect dst; 441 reader->readRect(&dst); 442 BREAK_ON_READ_ERROR(reader); 443 444 canvas->drawImageNine(image, center, dst, SkFilterMode::kNearest, paint); 445 } break; 446 case DRAW_IMAGE_RECT: { 447 const SkPaint* paint = fPictureData->optionalPaint(reader); 448 const SkImage* image = fPictureData->getImage(reader); 449 SkRect storage; 450 const SkRect* src = get_rect_ptr(reader, &storage); // may be null 451 SkRect dst; 452 reader->readRect(&dst); // required 453 // DRAW_IMAGE_RECT_STRICT assumes this constraint, and doesn't store it 454 SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint; 455 if (DRAW_IMAGE_RECT == op) { 456 // newer op-code stores the constraint explicitly 457 constraint = reader->checkRange(SkCanvas::kStrict_SrcRectConstraint, 458 SkCanvas::kFast_SrcRectConstraint); 459 } 460 BREAK_ON_READ_ERROR(reader); 461 462 auto sampling = SkSamplingOptions(SkFilterMode::kNearest); 463 if (src) { 464 canvas->drawImageRect(image, *src, dst, sampling, paint, constraint); 465 } else { 466 canvas->drawImageRect(image, dst, sampling, paint); 467 } 468 } break; 469 case DRAW_IMAGE_RECT2: { 470 const SkPaint* paint = fPictureData->optionalPaint(reader); 471 const SkImage* image = fPictureData->getImage(reader); 472 SkRect src = reader->readRect(); 473 SkRect dst = reader->readRect(); 474 SkSamplingOptions sampling = reader->readSampling(); 475 auto constraint = reader->read32LE(SkCanvas::kFast_SrcRectConstraint); 476 BREAK_ON_READ_ERROR(reader); 477 478 canvas->drawImageRect(image, src, dst, sampling, paint, constraint); 479 } break; 480 case DRAW_OVAL: { 481 const SkPaint& paint = fPictureData->requiredPaint(reader); 482 SkRect rect; 483 reader->readRect(&rect); 484 BREAK_ON_READ_ERROR(reader); 485 486 canvas->drawOval(rect, paint); 487 } break; 488 case DRAW_PAINT: { 489 const SkPaint& paint = fPictureData->requiredPaint(reader); 490 BREAK_ON_READ_ERROR(reader); 491 492 canvas->drawPaint(paint); 493 } break; 494 case DRAW_BEHIND_PAINT: { 495 const SkPaint& paint = fPictureData->requiredPaint(reader); 496 BREAK_ON_READ_ERROR(reader); 497 498 SkCanvasPriv::DrawBehind(canvas, paint); 499 } break; 500 case DRAW_PATCH: { 501 const SkPaint& paint = fPictureData->requiredPaint(reader); 502 503 const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts, 504 sizeof(SkPoint)); 505 uint32_t flag = reader->readInt(); 506 const SkColor* colors = nullptr; 507 if (flag & DRAW_VERTICES_HAS_COLORS) { 508 colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners, sizeof(SkColor)); 509 } 510 const SkPoint* texCoords = nullptr; 511 if (flag & DRAW_VERTICES_HAS_TEXS) { 512 texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners, 513 sizeof(SkPoint)); 514 } 515 SkBlendMode bmode = SkBlendMode::kModulate; 516 if (flag & DRAW_VERTICES_HAS_XFER) { 517 unsigned mode = reader->readInt(); 518 if (mode <= (unsigned)SkBlendMode::kLastMode) { 519 bmode = (SkBlendMode)mode; 520 } 521 } 522 BREAK_ON_READ_ERROR(reader); 523 524 canvas->drawPatch(cubics, colors, texCoords, bmode, paint); 525 } break; 526 case DRAW_PATH: { 527 const SkPaint& paint = fPictureData->requiredPaint(reader); 528 const auto& path = fPictureData->getPath(reader); 529 BREAK_ON_READ_ERROR(reader); 530 531 canvas->drawPath(path, paint); 532 } break; 533 case DRAW_PICTURE: { 534 const auto* pic = fPictureData->getPicture(reader); 535 BREAK_ON_READ_ERROR(reader); 536 537 canvas->drawPicture(pic); 538 } break; 539 case DRAW_PICTURE_MATRIX_PAINT: { 540 const SkPaint* paint = fPictureData->optionalPaint(reader); 541 SkMatrix matrix; 542 reader->readMatrix(&matrix); 543 const SkPicture* pic = fPictureData->getPicture(reader); 544 BREAK_ON_READ_ERROR(reader); 545 546 canvas->drawPicture(pic, &matrix, paint); 547 } break; 548 case DRAW_POINTS: { 549 const SkPaint& paint = fPictureData->requiredPaint(reader); 550 SkCanvas::PointMode mode = reader->checkRange(SkCanvas::kPoints_PointMode, 551 SkCanvas::kPolygon_PointMode); 552 size_t count = reader->readInt(); 553 const SkPoint* pts = (const SkPoint*)reader->skip(count, sizeof(SkPoint)); 554 BREAK_ON_READ_ERROR(reader); 555 556 canvas->drawPoints(mode, count, pts, paint); 557 } break; 558 case DRAW_RECT: { 559 const SkPaint& paint = fPictureData->requiredPaint(reader); 560 SkRect rect; 561 reader->readRect(&rect); 562 BREAK_ON_READ_ERROR(reader); 563 564 canvas->drawRect(rect, paint); 565 } break; 566 case DRAW_REGION: { 567 const SkPaint& paint = fPictureData->requiredPaint(reader); 568 SkRegion region; 569 reader->readRegion(®ion); 570 BREAK_ON_READ_ERROR(reader); 571 572 canvas->drawRegion(region, paint); 573 } break; 574 case DRAW_RRECT: { 575 const SkPaint& paint = fPictureData->requiredPaint(reader); 576 SkRRect rrect; 577 reader->readRRect(&rrect); 578 BREAK_ON_READ_ERROR(reader); 579 580 canvas->drawRRect(rrect, paint); 581 } break; 582 case DRAW_SHADOW_REC: { 583 const auto& path = fPictureData->getPath(reader); 584 SkDrawShadowRec rec; 585 reader->readPoint3(&rec.fZPlaneParams); 586 reader->readPoint3(&rec.fLightPos); 587 rec.fLightRadius = reader->readScalar(); 588 rec.fAmbientColor = reader->read32(); 589 rec.fSpotColor = reader->read32(); 590 rec.fFlags = reader->read32(); 591 BREAK_ON_READ_ERROR(reader); 592 593 canvas->private_draw_shadow_rec(path, rec); 594 } break; 595 case DRAW_TEXT_BLOB: { 596 const SkPaint& paint = fPictureData->requiredPaint(reader); 597 const SkTextBlob* blob = fPictureData->getTextBlob(reader); 598 SkScalar x = reader->readScalar(); 599 SkScalar y = reader->readScalar(); 600 BREAK_ON_READ_ERROR(reader); 601 602 canvas->drawTextBlob(blob, x, y, paint); 603 } break; 604 case DRAW_VERTICES_OBJECT: { 605 const SkPaint& paint = fPictureData->requiredPaint(reader); 606 const SkVertices* vertices = fPictureData->getVertices(reader); 607 const int boneCount = reader->readInt(); 608 (void)reader->skip(boneCount, sizeof(SkVertices_DeprecatedBone)); 609 SkBlendMode bmode = reader->read32LE(SkBlendMode::kLastMode); 610 BREAK_ON_READ_ERROR(reader); 611 612 if (vertices) { // TODO: read error if vertices == null? 613 canvas->drawVertices(vertices, bmode, paint); 614 } 615 } break; 616 case MARK_CTM: { 617 SkString name; 618 reader->readString(&name); 619 BREAK_ON_READ_ERROR(reader); 620 canvas->markCTM(name.c_str()); 621 } break; 622 case RESTORE: 623 canvas->restore(); 624 break; 625 case ROTATE: { 626 auto deg = reader->readScalar(); 627 canvas->rotate(deg); 628 } break; 629 case SAVE: 630 canvas->save(); 631 break; 632 case SAVE_BEHIND: { 633 uint32_t flags = reader->readInt(); 634 const SkRect* subset = nullptr; 635 SkRect storage; 636 if (flags & SAVEBEHIND_HAS_SUBSET) { 637 reader->readRect(&storage); 638 subset = &storage; 639 } 640 SkCanvasPriv::SaveBehind(canvas, subset); 641 } break; 642 case SAVE_LAYER_SAVELAYERREC: { 643 SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0); 644 const uint32_t flatFlags = reader->readInt(); 645 SkRect bounds; 646 if (flatFlags & SAVELAYERREC_HAS_BOUNDS) { 647 reader->readRect(&bounds); 648 rec.fBounds = &bounds; 649 } 650 if (flatFlags & SAVELAYERREC_HAS_PAINT) { 651 rec.fPaint = &fPictureData->requiredPaint(reader); 652 } 653 if (flatFlags & SAVELAYERREC_HAS_BACKDROP) { 654 const SkPaint& paint = fPictureData->requiredPaint(reader); 655 rec.fBackdrop = paint.getImageFilter(); 656 } 657 if (flatFlags & SAVELAYERREC_HAS_FLAGS) { 658 rec.fSaveLayerFlags = reader->readInt(); 659 } 660 if (flatFlags & SAVELAYERREC_HAS_CLIPMASK_OBSOLETE) { 661 (void)fPictureData->getImage(reader); 662 } 663 if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX_OBSOLETE) { 664 SkMatrix clipMatrix_ignored; 665 reader->readMatrix(&clipMatrix_ignored); 666 } 667 if (!reader->isVersionLT(SkPicturePriv::Version::kBackdropScaleFactor) && 668 (flatFlags & SAVELAYERREC_HAS_BACKDROP_SCALE)) { 669 SkCanvasPriv::SetBackdropScaleFactor(&rec, reader->readScalar()); 670 } 671 BREAK_ON_READ_ERROR(reader); 672 673 canvas->saveLayer(rec); 674 } break; 675 case SCALE: { 676 SkScalar sx = reader->readScalar(); 677 SkScalar sy = reader->readScalar(); 678 canvas->scale(sx, sy); 679 } break; 680 case SET_M44: { 681 SkM44 m; 682 reader->read(&m); 683 canvas->setMatrix(initialMatrix * m); 684 } break; 685 case SET_MATRIX: { 686 SkMatrix matrix; 687 reader->readMatrix(&matrix); 688 canvas->setMatrix(initialMatrix * SkM44(matrix)); 689 } break; 690 case SKEW: { 691 SkScalar sx = reader->readScalar(); 692 SkScalar sy = reader->readScalar(); 693 canvas->skew(sx, sy); 694 } break; 695 case TRANSLATE: { 696 SkScalar dx = reader->readScalar(); 697 SkScalar dy = reader->readScalar(); 698 canvas->translate(dx, dy); 699 } break; 700 default: 701 reader->validate(false); // unknown op 702 break; 703 } 704 705#undef BREAK_ON_READ_ERROR 706} 707