1 /*
2 * Copyright 2016 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 "SkDeduper.h"
10 #include "SkImageDeserializer.h"
11 #include "SkPicture.h"
12 #include "SkPictureRecorder.h"
13 #include "SkPipe.h"
14 #include "SkPipeFormat.h"
15 #include "SkReadBuffer.h"
16 #include "SkRefSet.h"
17 #include "SkRSXform.h"
18 #include "SkTextBlob.h"
19 #include "SkTypeface.h"
20
21 class SkPipeReader;
22
23 static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex = nullptr);
24
25 ///////////////////////////////////////////////////////////////////////////////////////////////////
26
27 class SkPipeInflator : public SkInflator {
28 public:
SkPipeInflator(SkRefSet<SkImage> * images,SkRefSet<SkPicture> * pictures,SkRefSet<SkTypeface> * typefaces,SkTDArray<SkFlattenable::Factory> * factories,SkTypefaceDeserializer * tfd,SkImageDeserializer * imd)29 SkPipeInflator(SkRefSet<SkImage>* images, SkRefSet<SkPicture>* pictures,
30 SkRefSet<SkTypeface>* typefaces, SkTDArray<SkFlattenable::Factory>* factories,
31 SkTypefaceDeserializer* tfd, SkImageDeserializer* imd)
32 : fImages(images)
33 , fPictures(pictures)
34 , fTypefaces(typefaces)
35 , fFactories(factories)
36 , fTFDeserializer(tfd)
37 , fIMDeserializer(imd)
38 {}
39
getImage(int index)40 SkImage* getImage(int index) override {
41 return index ? fImages->get(index - 1) : nullptr;
42 }
getPicture(int index)43 SkPicture* getPicture(int index) override {
44 return index ? fPictures->get(index - 1) : nullptr;
45 }
getTypeface(int index)46 SkTypeface* getTypeface(int index) override {
47 return fTypefaces->get(index - 1);
48 }
getFactory(int index)49 SkFlattenable::Factory getFactory(int index) override {
50 return index ? fFactories->getAt(index - 1) : nullptr;
51 }
52
setImage(int index,SkImage * img)53 bool setImage(int index, SkImage* img) {
54 return fImages->set(index - 1, img);
55 }
setPicture(int index,SkPicture * pic)56 bool setPicture(int index, SkPicture* pic) {
57 return fPictures->set(index - 1, pic);
58 }
setTypeface(int index,SkTypeface * face)59 bool setTypeface(int index, SkTypeface* face) {
60 return fTypefaces->set(index - 1, face);
61 }
setFactory(int index,SkFlattenable::Factory factory)62 bool setFactory(int index, SkFlattenable::Factory factory) {
63 SkASSERT(index > 0);
64 SkASSERT(factory);
65 index -= 1;
66 if ((unsigned)index < (unsigned)fFactories->count()) {
67 (*fFactories)[index] = factory;
68 return true;
69 }
70 if (fFactories->count() == index) {
71 *fFactories->append() = factory;
72 return true;
73 }
74 SkDebugf("setFactory: index [%d] out of range %d\n", index, fFactories->count());
75 return false;
76 }
77
setTypefaceDeserializer(SkTypefaceDeserializer * tfd)78 void setTypefaceDeserializer(SkTypefaceDeserializer* tfd) {
79 fTFDeserializer = tfd;
80 }
81
setImageDeserializer(SkImageDeserializer * imd)82 void setImageDeserializer(SkImageDeserializer* imd) {
83 fIMDeserializer = imd;
84 }
85
86 sk_sp<SkTypeface> makeTypeface(const void* data, size_t size);
87 sk_sp<SkImage> makeImage(const sk_sp<SkData>&);
88
89 private:
90 SkRefSet<SkImage>* fImages;
91 SkRefSet<SkPicture>* fPictures;
92 SkRefSet<SkTypeface>* fTypefaces;
93 SkTDArray<SkFlattenable::Factory>* fFactories;
94
95 SkTypefaceDeserializer* fTFDeserializer;
96 SkImageDeserializer* fIMDeserializer;
97 };
98
99 ///////////////////////////////////////////////////////////////////////////////////////////////////
100
skip(SkReadBuffer & reader,int count=1)101 template <typename T> const T* skip(SkReadBuffer& reader, int count = 1) {
102 return (const T*)reader.skip(count * sizeof(T));
103 }
104
read_rrect(SkReadBuffer & reader)105 static SkRRect read_rrect(SkReadBuffer& reader) {
106 SkRRect rrect;
107 rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMemory);
108 return rrect;
109 }
110
read_sparse_matrix(SkReadBuffer & reader,SkMatrix::TypeMask tm)111 static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) {
112 SkMatrix matrix;
113 matrix.reset();
114
115 if (tm & SkMatrix::kPerspective_Mask) {
116 matrix.set9(skip<SkScalar>(reader, 9));
117 } else if (tm & SkMatrix::kAffine_Mask) {
118 const SkScalar* tmp = skip<SkScalar>(reader, 6);
119 matrix[SkMatrix::kMScaleX] = tmp[0];
120 matrix[SkMatrix::kMSkewX] = tmp[1];
121 matrix[SkMatrix::kMTransX] = tmp[2];
122 matrix[SkMatrix::kMScaleY] = tmp[3];
123 matrix[SkMatrix::kMSkewY] = tmp[4];
124 matrix[SkMatrix::kMTransY] = tmp[5];
125 } else if (tm & SkMatrix::kScale_Mask) {
126 const SkScalar* tmp = skip<SkScalar>(reader, 4);
127 matrix[SkMatrix::kMScaleX] = tmp[0];
128 matrix[SkMatrix::kMTransX] = tmp[1];
129 matrix[SkMatrix::kMScaleY] = tmp[2];
130 matrix[SkMatrix::kMTransY] = tmp[3];
131 } else if (tm & SkMatrix::kTranslate_Mask) {
132 const SkScalar* tmp = skip<SkScalar>(reader, 2);
133 matrix[SkMatrix::kMTransX] = tmp[0];
134 matrix[SkMatrix::kMTransY] = tmp[1];
135 }
136 // else read nothing for Identity
137 return matrix;
138 }
139
140 ///////////////////////////////////////////////////////////////////////////////////////////////////
141
142 #define CHECK_SET_SCALAR(Field) \
143 do { if (nondef & k##Field##_NonDef) { \
144 paint.set##Field(reader.readScalar()); \
145 }} while (0)
146
147 #define CHECK_SET_FLATTENABLE(Field) \
148 do { if (nondef & k##Field##_NonDef) { \
149 paint.set##Field(reader.read##Field()); \
150 }} while (0)
151
152 /*
153 * Header:
154 * paint flags : 32
155 * non_def bits : 16
156 * xfermode enum : 8
157 * pad zeros : 8
158 */
read_paint(SkReadBuffer & reader)159 static SkPaint read_paint(SkReadBuffer& reader) {
160 SkPaint paint;
161
162 uint32_t packedFlags = reader.read32();
163 uint32_t extra = reader.read32();
164 unsigned nondef = extra >> 16;
165 paint.setBlendMode(SkBlendMode((extra >> 8) & 0xFF));
166 SkASSERT((extra & 0xFF) == 0); // zero pad byte
167
168 packedFlags >>= 2; // currently unused
169 paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3)); packedFlags >>= 2;
170 paint.setTextAlign((SkPaint::Align)(packedFlags & 3)); packedFlags >>= 2;
171 paint.setHinting((SkPaint::Hinting)(packedFlags & 3)); packedFlags >>= 2;
172 paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3)); packedFlags >>= 2;
173 paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3)); packedFlags >>= 2;
174 paint.setStyle((SkPaint::Style)(packedFlags & 3)); packedFlags >>= 2;
175 paint.setFilterQuality((SkFilterQuality)(packedFlags & 3)); packedFlags >>= 2;
176 paint.setFlags(packedFlags);
177
178 CHECK_SET_SCALAR(TextSize);
179 CHECK_SET_SCALAR(TextScaleX);
180 CHECK_SET_SCALAR(TextSkewX);
181 CHECK_SET_SCALAR(StrokeWidth);
182 CHECK_SET_SCALAR(StrokeMiter);
183
184 if (nondef & kColor_NonDef) {
185 paint.setColor(reader.read32());
186 }
187
188 CHECK_SET_FLATTENABLE(Typeface);
189 CHECK_SET_FLATTENABLE(PathEffect);
190 CHECK_SET_FLATTENABLE(Shader);
191 CHECK_SET_FLATTENABLE(MaskFilter);
192 CHECK_SET_FLATTENABLE(ColorFilter);
193 CHECK_SET_FLATTENABLE(Rasterizer);
194 CHECK_SET_FLATTENABLE(ImageFilter);
195 CHECK_SET_FLATTENABLE(DrawLooper);
196
197 return paint;
198 }
199
200 class SkPipeReader : public SkReadBuffer {
201 public:
SkPipeReader(SkPipeDeserializer * sink,const void * data,size_t size)202 SkPipeReader(SkPipeDeserializer* sink, const void* data, size_t size)
203 : SkReadBuffer(data, size)
204 , fSink(sink)
205 {}
206
207 SkPipeDeserializer* fSink;
208
findFactory(const char name[])209 SkFlattenable::Factory findFactory(const char name[]) {
210 SkFlattenable::Factory factory;
211 // Check if a custom Factory has been specified for this flattenable.
212 if (!(factory = this->getCustomFactory(SkString(name)))) {
213 // If there is no custom Factory, check for a default.
214 factory = SkFlattenable::NameToFactory(name);
215 }
216 return factory;
217 }
218
readPaint(SkPaint * paint)219 void readPaint(SkPaint* paint) override {
220 *paint = read_paint(*this);
221 }
222 };
223
224 ///////////////////////////////////////////////////////////////////////////////////////////////////
225
226 typedef void (*SkPipeHandler)(SkPipeReader&, uint32_t packedVerb, SkCanvas*);
227
save_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)228 static void save_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
229 SkASSERT(SkPipeVerb::kSave == unpack_verb(packedVerb));
230 canvas->save();
231 }
232
saveLayer_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)233 static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
234 SkASSERT(SkPipeVerb::kSaveLayer == unpack_verb(packedVerb));
235 unsigned extra = unpack_verb_extra(packedVerb);
236 const SkRect* bounds = (extra & kHasBounds_SaveLayerMask) ? skip<SkRect>(reader) : nullptr;
237 SkPaint paintStorage, *paint = nullptr;
238 if (extra & kHasPaint_SaveLayerMask) {
239 paintStorage = read_paint(reader);
240 paint = &paintStorage;
241 }
242 sk_sp<SkImageFilter> backdrop;
243 if (extra & kHasBackdrop_SaveLayerMask) {
244 backdrop = reader.readImageFilter();
245 }
246 SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_SaveLayerMask);
247
248 // unremap this wacky flag
249 if (extra & kDontClipToLayer_SaveLayerMask) {
250 flags |= (1 << 31);//SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag;
251 }
252
253 canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), flags));
254 }
255
restore_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)256 static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
257 SkASSERT(SkPipeVerb::kRestore == unpack_verb(packedVerb));
258 canvas->restore();
259 }
260
concat_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)261 static void concat_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
262 SkASSERT(SkPipeVerb::kConcat == unpack_verb(packedVerb));
263 SkMatrix::TypeMask tm = (SkMatrix::TypeMask)(packedVerb & kTypeMask_ConcatMask);
264 const SkMatrix matrix = read_sparse_matrix(reader, tm);
265 if (packedVerb & kSetMatrix_ConcatMask) {
266 canvas->setMatrix(matrix);
267 } else {
268 canvas->concat(matrix);
269 }
270 }
271
clipRect_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)272 static void clipRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
273 SkASSERT(SkPipeVerb::kClipRect == unpack_verb(packedVerb));
274 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
275 bool isAA = unpack_verb_extra(packedVerb) & 1;
276 canvas->clipRect(*skip<SkRect>(reader), op, isAA);
277 }
278
clipRRect_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)279 static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
280 SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb));
281 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
282 bool isAA = unpack_verb_extra(packedVerb) & 1;
283 canvas->clipRRect(read_rrect(reader), op, isAA);
284 }
285
clipPath_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)286 static void clipPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
287 SkASSERT(SkPipeVerb::kClipPath == unpack_verb(packedVerb));
288 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
289 bool isAA = unpack_verb_extra(packedVerb) & 1;
290 SkPath path;
291 reader.readPath(&path);
292 canvas->clipPath(path, op, isAA);
293 }
294
clipRegion_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)295 static void clipRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
296 SkASSERT(SkPipeVerb::kClipRegion == unpack_verb(packedVerb));
297 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
298 SkRegion region;
299 reader.readRegion(®ion);
300 canvas->clipRegion(region, op);
301 }
302
drawArc_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)303 static void drawArc_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
304 SkASSERT(SkPipeVerb::kDrawArc == unpack_verb(packedVerb));
305 const bool useCenter = (bool)(unpack_verb_extra(packedVerb) & 1);
306 const SkScalar* scalars = skip<SkScalar>(reader, 6); // bounds[0..3], start[4], sweep[5]
307 const SkRect* bounds = (const SkRect*)scalars;
308 canvas->drawArc(*bounds, scalars[4], scalars[5], useCenter, read_paint(reader));
309 }
310
drawAtlas_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)311 static void drawAtlas_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
312 SkASSERT(SkPipeVerb::kDrawAtlas == unpack_verb(packedVerb));
313 SkBlendMode mode = (SkBlendMode)(packedVerb & kMode_DrawAtlasMask);
314 sk_sp<SkImage> image(reader.readImage());
315 int count = reader.read32();
316 const SkRSXform* xform = skip<SkRSXform>(reader, count);
317 const SkRect* rect = skip<SkRect>(reader, count);
318 const SkColor* color = nullptr;
319 if (packedVerb & kHasColors_DrawAtlasMask) {
320 color = skip<SkColor>(reader, count);
321 }
322 const SkRect* cull = nullptr;
323 if (packedVerb & kHasCull_DrawAtlasMask) {
324 cull = skip<SkRect>(reader);
325 }
326 SkPaint paintStorage, *paint = nullptr;
327 if (packedVerb & kHasPaint_DrawAtlasMask) {
328 paintStorage = read_paint(reader);
329 paint = &paintStorage;
330 }
331 canvas->drawAtlas(image, xform, rect, color, count, mode, cull, paint);
332 }
333
drawDRRect_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)334 static void drawDRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
335 SkASSERT(SkPipeVerb::kDrawDRRect == unpack_verb(packedVerb));
336 const SkRRect outer = read_rrect(reader);
337 const SkRRect inner = read_rrect(reader);
338 canvas->drawDRRect(outer, inner, read_paint(reader));
339 }
340
drawText_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)341 static void drawText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
342 SkASSERT(SkPipeVerb::kDrawText == unpack_verb(packedVerb));
343 uint32_t len = unpack_verb_extra(packedVerb);
344 if (0 == len) {
345 len = reader.read32();
346 }
347 const void* text = reader.skip(SkAlign4(len));
348 SkScalar x = reader.readScalar();
349 SkScalar y = reader.readScalar();
350 canvas->drawText(text, len, x, y, read_paint(reader));
351 }
352
drawPosText_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)353 static void drawPosText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
354 SkASSERT(SkPipeVerb::kDrawPosText == unpack_verb(packedVerb));
355 uint32_t len = unpack_verb_extra(packedVerb);
356 if (0 == len) {
357 len = reader.read32();
358 }
359 const void* text = reader.skip(SkAlign4(len));
360 int count = reader.read32();
361 const SkPoint* pos = skip<SkPoint>(reader, count);
362 SkPaint paint = read_paint(reader);
363 SkASSERT(paint.countText(text, len) == count);
364 canvas->drawPosText(text, len, pos, paint);
365 }
366
drawPosTextH_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)367 static void drawPosTextH_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
368 SkASSERT(SkPipeVerb::kDrawPosTextH == unpack_verb(packedVerb));
369 uint32_t len = unpack_verb_extra(packedVerb);
370 if (0 == len) {
371 len = reader.read32();
372 }
373 const void* text = reader.skip(SkAlign4(len));
374 int count = reader.read32();
375 const SkScalar* xpos = skip<SkScalar>(reader, count);
376 SkScalar constY = reader.readScalar();
377 SkPaint paint = read_paint(reader);
378 SkASSERT(paint.countText(text, len) == count);
379 canvas->drawPosTextH(text, len, xpos, constY, paint);
380 }
381
drawTextOnPath_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)382 static void drawTextOnPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
383 SkASSERT(SkPipeVerb::kDrawTextOnPath == unpack_verb(packedVerb));
384 uint32_t byteLength = packedVerb & kTextLength_DrawTextOnPathMask;
385 SkMatrix::TypeMask tm = (SkMatrix::TypeMask)
386 ((packedVerb & kMatrixType_DrawTextOnPathMask) >> kMatrixType_DrawTextOnPathShift);
387
388 if (0 == byteLength) {
389 byteLength = reader.read32();
390 }
391 const void* text = reader.skip(SkAlign4(byteLength));
392 SkPath path;
393 reader.readPath(&path);
394 const SkMatrix* matrix = nullptr;
395 SkMatrix matrixStorage;
396 if (tm != SkMatrix::kIdentity_Mask) {
397 matrixStorage = read_sparse_matrix(reader, tm);
398 matrix = &matrixStorage;
399 }
400 canvas->drawTextOnPath(text, byteLength, path, matrix, read_paint(reader));
401 }
402
drawTextBlob_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)403 static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
404 sk_sp<SkTextBlob> tb = SkTextBlob::MakeFromBuffer(reader);
405 SkScalar x = reader.readScalar();
406 SkScalar y = reader.readScalar();
407 canvas->drawTextBlob(tb, x, y, read_paint(reader));
408 }
409
drawTextRSXform_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)410 static void drawTextRSXform_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
411 SkASSERT(SkPipeVerb::kDrawTextRSXform == unpack_verb(packedVerb));
412 uint32_t len = unpack_verb_extra(packedVerb) >> 1;
413 if (0 == len) {
414 len = reader.read32();
415 }
416 const void* text = reader.skip(SkAlign4(len));
417 int count = reader.read32();
418 const SkRSXform* xform = skip<SkRSXform>(reader, count);
419 const SkRect* cull = (packedVerb & 1) ? skip<SkRect>(reader) : nullptr;
420 SkPaint paint = read_paint(reader);
421 SkASSERT(paint.countText(text, len) == count);
422 canvas->drawTextRSXform(text, len, xform, cull, paint);
423 }
424
drawPatch_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)425 static void drawPatch_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
426 SkASSERT(SkPipeVerb::kDrawPatch == unpack_verb(packedVerb));
427 const SkColor* colors = nullptr;
428 const SkPoint* tex = nullptr;
429 const SkPoint* cubics = skip<SkPoint>(reader, 12);
430 if (packedVerb & kHasColors_DrawPatchExtraMask) {
431 colors = skip<SkColor>(reader, 4);
432 }
433 if (packedVerb & kHasTexture_DrawPatchExtraMask) {
434 tex = skip<SkPoint>(reader, 4);
435 }
436 SkBlendMode mode = (SkBlendMode)(packedVerb & kModeEnum_DrawPatchExtraMask);
437 canvas->drawPatch(cubics, colors, tex, mode, read_paint(reader));
438 }
439
drawPaint_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)440 static void drawPaint_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
441 SkASSERT(SkPipeVerb::kDrawPaint == unpack_verb(packedVerb));
442 canvas->drawPaint(read_paint(reader));
443 }
444
drawRect_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)445 static void drawRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
446 SkASSERT(SkPipeVerb::kDrawRect == unpack_verb(packedVerb));
447 const SkRect* rect = skip<SkRect>(reader);
448 canvas->drawRect(*rect, read_paint(reader));
449 }
450
drawRegion_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)451 static void drawRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
452 SkASSERT(SkPipeVerb::kDrawRegion == unpack_verb(packedVerb));
453 size_t size = unpack_verb_extra(packedVerb);
454 if (0 == size) {
455 size = reader.read32();
456 }
457 SkRegion region;
458 region.readFromMemory(skip<char>(reader, SkAlign4(size)), size);
459 canvas->drawRegion(region, read_paint(reader));
460 }
461
drawOval_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)462 static void drawOval_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
463 SkASSERT(SkPipeVerb::kDrawOval == unpack_verb(packedVerb));
464 const SkRect* rect = skip<SkRect>(reader);
465 canvas->drawOval(*rect, read_paint(reader));
466 }
467
drawRRect_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)468 static void drawRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
469 SkASSERT(SkPipeVerb::kDrawRRect == unpack_verb(packedVerb));
470 SkRRect rrect = read_rrect(reader);
471 canvas->drawRRect(rrect, read_paint(reader));
472 }
473
drawPath_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)474 static void drawPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
475 SkASSERT(SkPipeVerb::kDrawPath == unpack_verb(packedVerb));
476 SkPath path;
477 reader.readPath(&path);
478 canvas->drawPath(path, read_paint(reader));
479 }
480
drawPoints_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)481 static void drawPoints_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
482 SkASSERT(SkPipeVerb::kDrawPoints == unpack_verb(packedVerb));
483 SkCanvas::PointMode mode = (SkCanvas::PointMode)unpack_verb_extra(packedVerb);
484 int count = reader.read32();
485 const SkPoint* points = skip<SkPoint>(reader, count);
486 canvas->drawPoints(mode, count, points, read_paint(reader));
487 }
488
drawImage_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)489 static void drawImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
490 SkASSERT(SkPipeVerb::kDrawImage == unpack_verb(packedVerb));
491 sk_sp<SkImage> image(reader.readImage());
492 SkScalar x = reader.readScalar();
493 SkScalar y = reader.readScalar();
494 SkPaint paintStorage, *paint = nullptr;
495 if (packedVerb & kHasPaint_DrawImageMask) {
496 paintStorage = read_paint(reader);
497 paint = &paintStorage;
498 }
499 canvas->drawImage(image, x, y, paint);
500 }
501
drawImageRect_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)502 static void drawImageRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
503 SkASSERT(SkPipeVerb::kDrawImageRect == unpack_verb(packedVerb));
504 sk_sp<SkImage> image(reader.readImage());
505 SkCanvas::SrcRectConstraint constraint =
506 (SkCanvas::SrcRectConstraint)(packedVerb & kConstraint_DrawImageRectMask);
507 const SkRect* src = (packedVerb & kHasSrcRect_DrawImageRectMask) ?
508 skip<SkRect>(reader) : nullptr;
509 const SkRect* dst = skip<SkRect>(reader);
510 SkPaint paintStorage, *paint = nullptr;
511 if (packedVerb & kHasPaint_DrawImageRectMask) {
512 paintStorage = read_paint(reader);
513 paint = &paintStorage;
514 }
515 if (src) {
516 canvas->drawImageRect(image, *src, *dst, paint, constraint);
517 } else {
518 canvas->drawImageRect(image, *dst, paint);
519 }
520 }
521
drawImageNine_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)522 static void drawImageNine_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
523 SkASSERT(SkPipeVerb::kDrawImageNine == unpack_verb(packedVerb));
524 sk_sp<SkImage> image(reader.readImage());
525 const SkIRect* center = skip<SkIRect>(reader);
526 const SkRect* dst = skip<SkRect>(reader);
527 SkPaint paintStorage, *paint = nullptr;
528 if (packedVerb & kHasPaint_DrawImageNineMask) {
529 paintStorage = read_paint(reader);
530 paint = &paintStorage;
531 }
532 canvas->drawImageNine(image, *center, *dst, paint);
533 }
534
drawImageLattice_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)535 static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
536 SkASSERT(SkPipeVerb::kDrawImageLattice == unpack_verb(packedVerb));
537 sk_sp<SkImage> image(reader.readImage());
538
539 SkCanvas::Lattice lattice;
540 lattice.fXCount = (packedVerb >> kXCount_DrawImageLatticeShift) & kCount_DrawImageLatticeMask;
541 if (lattice.fXCount == kCount_DrawImageLatticeMask) {
542 lattice.fXCount = reader.read32();
543 }
544 lattice.fYCount = (packedVerb >> kXCount_DrawImageLatticeShift) & kCount_DrawImageLatticeMask;
545 if (lattice.fYCount == kCount_DrawImageLatticeMask) {
546 lattice.fYCount = reader.read32();
547 }
548 lattice.fXDivs = skip<int32_t>(reader, lattice.fXCount);
549 lattice.fYDivs = skip<int32_t>(reader, lattice.fYCount);
550 if (packedVerb & kHasFlags_DrawImageLatticeMask) {
551 int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1);
552 SkASSERT(count > 0);
553 lattice.fFlags = skip<SkCanvas::Lattice::Flags>(reader, SkAlign4(count));
554 } else {
555 lattice.fFlags = nullptr;
556 }
557 lattice.fBounds = skip<SkIRect>(reader);
558 const SkRect* dst = skip<SkRect>(reader);
559
560 SkPaint paintStorage, *paint = nullptr;
561 if (packedVerb & kHasPaint_DrawImageLatticeMask) {
562 paintStorage = read_paint(reader);
563 paint = &paintStorage;
564 }
565 canvas->drawImageLattice(image.get(), lattice, *dst, paint);
566 }
567
drawVertices_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)568 static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
569 SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb));
570 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)
571 ((packedVerb & kVMode_DrawVerticesMask) >> kVMode_DrawVerticesShift);
572 int vertexCount = packedVerb & kVCount_DrawVerticesMask;
573 if (0 == vertexCount) {
574 vertexCount = reader.read32();
575 }
576 SkBlendMode bmode = (SkBlendMode)
577 ((packedVerb & kXMode_DrawVerticesMask) >> kXMode_DrawVerticesShift);
578 const SkPoint* vertices = skip<SkPoint>(reader, vertexCount);
579 const SkPoint* texs = nullptr;
580 if (packedVerb & kHasTex_DrawVerticesMask) {
581 texs = skip<SkPoint>(reader, vertexCount);
582 }
583 const SkColor* colors = nullptr;
584 if (packedVerb & kHasColors_DrawVerticesMask) {
585 colors = skip<SkColor>(reader, vertexCount);
586 }
587 int indexCount = 0;
588 const uint16_t* indices = nullptr;
589 if (packedVerb & kHasIndices_DrawVerticesMask) {
590 indexCount = reader.read32();
591 indices = skip<uint16_t>(reader, indexCount);
592 }
593
594 canvas->drawVertices(vmode, vertexCount, vertices, texs, colors, bmode,
595 indices, indexCount, read_paint(reader));
596 }
597
drawPicture_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)598 static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
599 SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb));
600 unsigned extra = unpack_verb_extra(packedVerb);
601 int index = extra & kIndex_ObjectDefinitionMask;
602 SkPicture* pic = reader.getInflator()->getPicture(index);
603 SkMatrix matrixStorage, *matrix = nullptr;
604 SkPaint paintStorage, *paint = nullptr;
605 if (extra & kHasMatrix_DrawPictureExtra) {
606 reader.readMatrix(&matrixStorage);
607 matrix = &matrixStorage;
608 }
609 if (extra & kHasPaint_DrawPictureExtra) {
610 paintStorage = read_paint(reader);
611 paint = &paintStorage;
612 }
613 canvas->drawPicture(pic, matrix, paint);
614 }
615
drawAnnotation_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)616 static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
617 SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb));
618 const SkRect* rect = skip<SkRect>(reader);
619
620 // len includes the key's trailing 0
621 uint32_t len = unpack_verb_extra(packedVerb) >> 1;
622 if (0 == len) {
623 len = reader.read32();
624 }
625 const char* key = skip<char>(reader, len);
626 sk_sp<SkData> data;
627 if (packedVerb & 1) {
628 uint32_t size = reader.read32();
629 data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size);
630 }
631 canvas->drawAnnotation(*rect, key, data);
632 }
633
634 #if 0
635 stream.write("skiacodc", 8);
636 stream.write32(pmap.width());
637 stream.write32(pmap.height());
638 stream.write16(pmap.colorType());
639 stream.write16(pmap.alphaType());
640 stream.write32(0); // no colorspace for now
641 for (int y = 0; y < pmap.height(); ++y) {
642 stream.write(pmap.addr8(0, y), pmap.width());
643 }
644 #endif
645
make_from_skiaimageformat(const void * encoded,size_t encodedSize)646 static sk_sp<SkImage> make_from_skiaimageformat(const void* encoded, size_t encodedSize) {
647 if (encodedSize < 24) {
648 return nullptr;
649 }
650
651 SkMemoryStream stream(encoded, encodedSize);
652 char signature[8];
653 stream.read(signature, 8);
654 if (memcmp(signature, "skiaimgf", 8)) {
655 return nullptr;
656 }
657
658 int width = stream.readU32();
659 int height = stream.readU32();
660 SkColorType ct = (SkColorType)stream.readU16();
661 SkAlphaType at = (SkAlphaType)stream.readU16();
662 SkASSERT(kAlpha_8_SkColorType == ct);
663
664 SkDEBUGCODE(size_t colorSpaceSize =) stream.readU32();
665 SkASSERT(0 == colorSpaceSize);
666
667 SkImageInfo info = SkImageInfo::Make(width, height, ct, at);
668 size_t size = width * height;
669 sk_sp<SkData> pixels = SkData::MakeUninitialized(size);
670 stream.read(pixels->writable_data(), size);
671 SkASSERT(encodedSize == SkAlign4(stream.getPosition()));
672 return SkImage::MakeRasterData(info, pixels, width);
673 }
674
makeImage(const sk_sp<SkData> & data)675 sk_sp<SkImage> SkPipeInflator::makeImage(const sk_sp<SkData>& data) {
676 if (fIMDeserializer) {
677 return fIMDeserializer->makeFromData(data.get(), nullptr);
678 }
679 sk_sp<SkImage> image = make_from_skiaimageformat(data->data(), data->size());
680 if (!image) {
681 image = SkImage::MakeFromEncoded(data);
682 }
683 return image;
684 }
685
686
defineImage_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas *)687 static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) {
688 SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb));
689 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
690 uint32_t extra = unpack_verb_extra(packedVerb);
691 int index = extra & kIndex_ObjectDefinitionMask;
692
693 if (extra & kUndef_ObjectDefinitionMask) {
694 // zero-index means we are "forgetting" that cache entry
695 inflator->setImage(index, nullptr);
696 } else {
697 // we are defining a new image
698 sk_sp<SkData> data = reader.readByteArrayAsData();
699 sk_sp<SkImage> image = inflator->makeImage(data);
700 if (!image) {
701 SkDebugf("-- failed to decode\n");
702 }
703 inflator->setImage(index, image.get());
704 }
705 }
706
makeTypeface(const void * data,size_t size)707 sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) {
708 if (fTFDeserializer) {
709 return fTFDeserializer->deserialize(data, size);
710 }
711 SkMemoryStream stream(data, size, false);
712 return SkTypeface::MakeDeserialize(&stream);
713 }
714
defineTypeface_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)715 static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
716 SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb));
717 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
718 uint32_t extra = unpack_verb_extra(packedVerb);
719 int index = extra & kIndex_ObjectDefinitionMask;
720
721 if (extra & kUndef_ObjectDefinitionMask) {
722 // zero-index means we are "forgetting" that cache entry
723 inflator->setTypeface(index, nullptr);
724 } else {
725 // we are defining a new image
726 sk_sp<SkData> data = reader.readByteArrayAsData();
727 // TODO: seems like we could "peek" to see the array, and not need to copy it.
728 sk_sp<SkTypeface> tf = inflator->makeTypeface(data->data(), data->size());
729 inflator->setTypeface(index, tf.get());
730 }
731 }
732
defineFactory_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)733 static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
734 SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb));
735 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
736 uint32_t extra = unpack_verb_extra(packedVerb);
737 int index = extra >> kNameLength_DefineFactoryExtraBits;
738 size_t len = extra & kNameLength_DefineFactoryExtraMask;
739 // +1 for the trailing null char
740 const char* name = (const char*)reader.skip(SkAlign4(len + 1));
741 SkFlattenable::Factory factory = reader.findFactory(name);
742 if (factory) {
743 inflator->setFactory(index, factory);
744 }
745 }
746
definePicture_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)747 static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
748 SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb));
749 int deleteIndex = unpack_verb_extra(packedVerb);
750
751 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
752
753 if (deleteIndex) {
754 inflator->setPicture(deleteIndex - 1, nullptr);
755 } else {
756 SkPictureRecorder recorder;
757 int pictureIndex = -1; // invalid
758 const SkRect* cull = skip<SkRect>(reader);
759 do_playback(reader, recorder.beginRecording(*cull), &pictureIndex);
760 SkASSERT(pictureIndex > 0);
761 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
762 inflator->setPicture(pictureIndex, picture.get());
763 }
764 }
765
endPicture_handler(SkPipeReader & reader,uint32_t packedVerb,SkCanvas * canvas)766 static void endPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
767 sk_throw(); // never call me
768 }
769
770 ///////////////////////////////////////////////////////////////////////////////////////////////////
771
772 struct HandlerRec {
773 SkPipeHandler fProc;
774 const char* fName;
775 };
776
777 #define HANDLER(name) { name##_handler, #name }
778 const HandlerRec gPipeHandlers[] = {
779 HANDLER(save),
780 HANDLER(saveLayer),
781 HANDLER(restore),
782 HANDLER(concat),
783
784 HANDLER(clipRect),
785 HANDLER(clipRRect),
786 HANDLER(clipPath),
787 HANDLER(clipRegion),
788
789 HANDLER(drawArc),
790 HANDLER(drawAtlas),
791 HANDLER(drawDRRect),
792 HANDLER(drawText),
793 HANDLER(drawPosText),
794 HANDLER(drawPosTextH),
795 HANDLER(drawRegion),
796 HANDLER(drawTextOnPath),
797 HANDLER(drawTextBlob),
798 HANDLER(drawTextRSXform),
799 HANDLER(drawPatch),
800 HANDLER(drawPaint),
801 HANDLER(drawPoints),
802 HANDLER(drawRect),
803 HANDLER(drawPath),
804 HANDLER(drawOval),
805 HANDLER(drawRRect),
806
807 HANDLER(drawImage),
808 HANDLER(drawImageRect),
809 HANDLER(drawImageNine),
810 HANDLER(drawImageLattice),
811
812 HANDLER(drawVertices),
813
814 HANDLER(drawPicture),
815 HANDLER(drawAnnotation),
816
817 HANDLER(defineImage),
818 HANDLER(defineTypeface),
819 HANDLER(defineFactory),
820 HANDLER(definePicture),
821 HANDLER(endPicture), // handled special -- should never be called
822 };
823 #undef HANDLER
824
825 ///////////////////////////////////////////////////////////////////////////////////////////////////
826
827 class SkPipeDeserializer::Impl {
828 public:
829 SkRefSet<SkImage> fImages;
830 SkRefSet<SkPicture> fPictures;
831 SkRefSet<SkTypeface> fTypefaces;
832 SkTDArray<SkFlattenable::Factory> fFactories;
833
834 SkTypefaceDeserializer* fTFDeserializer = nullptr;
835 SkImageDeserializer* fIMDeserializer = nullptr;
836 };
837
SkPipeDeserializer()838 SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {}
~SkPipeDeserializer()839 SkPipeDeserializer::~SkPipeDeserializer() {}
840
setTypefaceDeserializer(SkTypefaceDeserializer * tfd)841 void SkPipeDeserializer::setTypefaceDeserializer(SkTypefaceDeserializer* tfd) {
842 fImpl->fTFDeserializer = tfd;
843 }
844
setImageDeserializer(SkImageDeserializer * imd)845 void SkPipeDeserializer::setImageDeserializer(SkImageDeserializer* imd) {
846 fImpl->fIMDeserializer = imd;
847 }
848
readImage(const void * data,size_t size)849 sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) {
850 if (size < sizeof(uint32_t)) {
851 SkDebugf("-------- data length too short for readImage %d\n", size);
852 return nullptr;
853 }
854
855 const uint32_t* ptr = (const uint32_t*)data;
856 uint32_t packedVerb = *ptr++;
857 size -= 4;
858
859 if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) {
860 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
861 &fImpl->fTypefaces, &fImpl->fFactories,
862 fImpl->fTFDeserializer, fImpl->fIMDeserializer);
863 SkPipeReader reader(this, ptr, size);
864 reader.setInflator(&inflator);
865 defineImage_handler(reader, packedVerb, nullptr);
866 packedVerb = reader.read32(); // read the next verb
867 }
868 if (SkPipeVerb::kWriteImage != unpack_verb(packedVerb)) {
869 SkDebugf("-------- unexpected verb for readImage %d\n", unpack_verb(packedVerb));
870 return nullptr;
871 }
872 int index = unpack_verb_extra(packedVerb);
873 if (0 == index) {
874 return nullptr; // writer failed
875 }
876 return sk_ref_sp(fImpl->fImages.get(index - 1));
877 }
878
readPicture(const void * data,size_t size)879 sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) {
880 if (size < sizeof(uint32_t)) {
881 SkDebugf("-------- data length too short for readPicture %d\n", size);
882 return nullptr;
883 }
884
885 const uint32_t* ptr = (const uint32_t*)data;
886 uint32_t packedVerb = *ptr++;
887 size -= 4;
888
889 if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) {
890 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
891 &fImpl->fTypefaces, &fImpl->fFactories,
892 fImpl->fTFDeserializer, fImpl->fIMDeserializer);
893 SkPipeReader reader(this, ptr, size);
894 reader.setInflator(&inflator);
895 definePicture_handler(reader, packedVerb, nullptr);
896 packedVerb = reader.read32(); // read the next verb
897 }
898 if (SkPipeVerb::kWritePicture != unpack_verb(packedVerb)) {
899 SkDebugf("-------- unexpected verb for readPicture %d\n", unpack_verb(packedVerb));
900 return nullptr;
901 }
902 int index = unpack_verb_extra(packedVerb);
903 if (0 == index) {
904 return nullptr; // writer failed
905 }
906 return sk_ref_sp(fImpl->fPictures.get(index - 1));
907 }
908
do_playback(SkPipeReader & reader,SkCanvas * canvas,int * endPictureIndex)909 static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex) {
910 int indent = 0;
911
912 const bool showEachVerb = false;
913 int counter = 0;
914 while (!reader.eof()) {
915 uint32_t prevOffset = reader.offset();
916 uint32_t packedVerb = reader.read32();
917 SkPipeVerb verb = unpack_verb(packedVerb);
918 if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) {
919 SkDebugf("------- bad verb %d\n", verb);
920 return false;
921 }
922 if (SkPipeVerb::kRestore == verb) {
923 indent -= 1;
924 SkASSERT(indent >= 0);
925 }
926
927 if (SkPipeVerb::kEndPicture == verb) {
928 if (endPictureIndex) {
929 *endPictureIndex = unpack_verb_extra(packedVerb);
930 }
931 return true;
932 }
933 HandlerRec rec = gPipeHandlers[(unsigned)verb];
934 rec.fProc(reader, packedVerb, canvas);
935 if (showEachVerb) {
936 for (int i = 0; i < indent; ++i) {
937 SkDebugf(" ");
938 }
939 SkDebugf("%d [%d] %s %d\n", prevOffset, counter++, rec.fName, reader.offset() - prevOffset);
940 }
941 if (!reader.isValid()) {
942 SkDebugf("-------- bad reader\n");
943 return false;
944 }
945
946 switch (verb) {
947 case SkPipeVerb::kSave:
948 case SkPipeVerb::kSaveLayer:
949 indent += 1;
950 break;
951 default:
952 break;
953 }
954 }
955 return true;
956 }
957
playback(const void * data,size_t size,SkCanvas * canvas)958 bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) {
959 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
960 &fImpl->fTypefaces, &fImpl->fFactories,
961 fImpl->fTFDeserializer, fImpl->fIMDeserializer);
962 SkPipeReader reader(this, data, size);
963 reader.setInflator(&inflator);
964 return do_playback(reader, canvas);
965 }
966
967