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