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