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 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 */ 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 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: 73 size_t length() { return fByteLength; } 74 const void* text() { return (const void*)fText; } 75 size_t fByteLength; 76 const char* fText; 77 }; 78 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 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 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