SkPicturePlayback.cpp 25 KB

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