OLD | NEW |
---|---|
(Empty) | |
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 "SkPicture.h" | |
11 #include "SkPictureRecorder.h" | |
12 #include "SkPipe.h" | |
13 #include "SkPipeFormat.h" | |
14 #include "SkReadBuffer.h" | |
15 #include "SkRefSet.h" | |
16 #include "SkRSXform.h" | |
17 #include "SkTextBlob.h" | |
18 #include "SkTypeface.h" | |
19 | |
20 class SkPipeReader; | |
21 | |
22 static bool do_playback(SkPipeReader& reader, SkCanvas* canvas); | |
23 | |
24 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
25 | |
26 class SkPipeInflator : public SkInflator { | |
27 public: | |
28 SkPipeInflator(SkRefSet<SkImage>* images, SkRefSet<SkPicture>* pictures, | |
29 SkRefSet<SkTypeface>* typefaces, SkTDArray<SkFlattenable::Fac tory>* factories) | |
30 : fImages(images) | |
31 , fPictures(pictures) | |
32 , fTypefaces(typefaces) | |
33 , fFactories(factories) | |
34 {} | |
35 | |
36 SkImage* getImage(int index) override { | |
37 return index ? fImages->get(index - 1) : nullptr; | |
38 } | |
39 SkPicture* getPicture(int index) override { | |
40 return index ? fPictures->get(index - 1) : nullptr; | |
41 } | |
42 SkTypeface* getTypeface(int index) override { return fTypefaces->get(index); } | |
43 SkFlattenable::Factory getFactory(int index) override { | |
44 return index ? fFactories->getAt(index - 1) : nullptr; | |
45 } | |
46 | |
47 bool setImage(int index, SkImage* img) { | |
48 return fImages->set(index - 1, img); | |
49 } | |
50 bool setPicture(int index, SkPicture* pic) { | |
51 return fPictures->set(index - 1, pic); | |
52 } | |
53 bool setTypeface(int index, SkTypeface* face) { | |
54 return fTypefaces->set(index - 1, face); | |
55 } | |
56 bool setFactory(int index, SkFlattenable::Factory factory) { | |
57 SkASSERT(index > 0); | |
58 SkASSERT(factory); | |
59 index -= 1; | |
60 if ((unsigned)index < (unsigned)fFactories->count()) { | |
61 (*fFactories)[index] = factory; | |
62 return true; | |
63 } | |
64 if (fFactories->count() == index) { | |
65 *fFactories->append() = factory; | |
66 return true; | |
67 } | |
68 SkDebugf("setFactory: index [%d] out of range %d\n", index, fFactories-> count()); | |
69 return false; | |
70 } | |
71 | |
72 private: | |
73 SkRefSet<SkImage>* fImages; | |
74 SkRefSet<SkPicture>* fPictures; | |
75 SkRefSet<SkTypeface>* fTypefaces; | |
76 SkTDArray<SkFlattenable::Factory>* fFactories; | |
77 }; | |
78 | |
79 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
80 | |
81 template <typename T> const T* skip(SkReadBuffer& reader, int count = 1) { | |
82 return (const T*)reader.skip(count * sizeof(T)); | |
83 } | |
84 | |
85 static SkRRect read_rrect(SkReadBuffer& reader) { | |
86 SkRRect rrect; | |
87 rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMe mory); | |
88 return rrect; | |
89 } | |
90 | |
91 static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) { | |
92 SkMatrix matrix; | |
93 matrix.reset(); | |
94 | |
95 if (tm & SkMatrix::kPerspective_Mask) { | |
96 matrix.set9(skip<SkScalar>(reader, 9)); | |
97 } else if (tm & SkMatrix::kAffine_Mask) { | |
98 const SkScalar* tmp = skip<SkScalar>(reader, 6); | |
99 matrix[SkMatrix::kMScaleX] = tmp[0]; | |
100 matrix[SkMatrix::kMSkewX] = tmp[1]; | |
101 matrix[SkMatrix::kMTransX] = tmp[2]; | |
102 matrix[SkMatrix::kMScaleY] = tmp[3]; | |
103 matrix[SkMatrix::kMSkewY] = tmp[4]; | |
104 matrix[SkMatrix::kMTransY] = tmp[5]; | |
105 } else if (tm & SkMatrix::kScale_Mask) { | |
106 const SkScalar* tmp = skip<SkScalar>(reader, 4); | |
107 matrix[SkMatrix::kMScaleX] = tmp[0]; | |
108 matrix[SkMatrix::kMTransX] = tmp[1]; | |
109 matrix[SkMatrix::kMScaleY] = tmp[2]; | |
110 matrix[SkMatrix::kMTransY] = tmp[3]; | |
111 } else if (tm & SkMatrix::kTranslate_Mask) { | |
112 const SkScalar* tmp = skip<SkScalar>(reader, 2); | |
113 matrix[SkMatrix::kMTransX] = tmp[0]; | |
114 matrix[SkMatrix::kMTransY] = tmp[1]; | |
115 } | |
116 // else read nothing for Identity | |
117 return matrix; | |
118 } | |
119 | |
120 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
121 | |
122 #define CHECK_SET_SCALAR(Field) \ | |
123 do { if (nondef & k##Field##_NonDef) { \ | |
124 paint.set##Field(reader.readScalar()); \ | |
125 }} while (0) | |
126 | |
127 #define CHECK_SET_FLATTENABLE(Field) \ | |
128 do { if (nondef & k##Field##_NonDef) { \ | |
129 paint.set##Field(reader.read##Field()); \ | |
130 }} while (0) | |
131 | |
132 /* | |
133 * Header: | |
134 * paint flags : 32 | |
135 * non_def bits : 16 | |
136 * xfermode enum : 8 | |
137 * pad zeros : 8 | |
138 */ | |
139 static SkPaint read_paint(SkReadBuffer& reader) { | |
140 uint32_t packedFlags = reader.read32(); | |
141 uint32_t extra = reader.read32(); | |
142 unsigned nondef = extra >> 16; | |
143 SkXfermode::Mode mode = (SkXfermode::Mode)((extra >> 8) & 0xFF); | |
144 SkASSERT((extra & 0xFF) == 0); | |
145 | |
146 SkPaint paint; | |
147 | |
148 packedFlags >>= 2; | |
149 paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3)); packedFl ags >>= 2; | |
150 paint.setTextAlign((SkPaint::Align)(packedFlags & 3)); packedFl ags >>= 2; | |
151 paint.setHinting((SkPaint::Hinting)(packedFlags & 2)); packedFl ags >>= 2; | |
152 paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3)); packedFl ags >>= 2; | |
153 paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3)); packedFl ags >>= 2; | |
154 paint.setStyle((SkPaint::Style)(packedFlags & 3)); packedFl ags >>= 2; | |
155 paint.setFilterQuality((SkFilterQuality)(packedFlags & 3)); packedFl ags >>= 2; | |
156 paint.setFlags(packedFlags); | |
157 | |
158 CHECK_SET_SCALAR(TextSize); | |
159 CHECK_SET_SCALAR(TextScaleX); | |
160 CHECK_SET_SCALAR(TextSkewX); | |
161 CHECK_SET_SCALAR(StrokeWidth); | |
162 CHECK_SET_SCALAR(StrokeMiter); | |
163 | |
164 if (nondef & kColor_NonDef) { | |
165 paint.setColor(reader.read32()); | |
166 } | |
167 if (nondef & kTypeface_NonDef) { | |
mtklein
2016/08/26 18:43:23
:|
| |
168 } | |
169 | |
170 CHECK_SET_FLATTENABLE(PathEffect); | |
171 CHECK_SET_FLATTENABLE(Shader); | |
172 CHECK_SET_FLATTENABLE(Xfermode); | |
173 CHECK_SET_FLATTENABLE(MaskFilter); | |
174 CHECK_SET_FLATTENABLE(ColorFilter); | |
175 CHECK_SET_FLATTENABLE(Rasterizer); | |
176 CHECK_SET_FLATTENABLE(ImageFilter); | |
177 | |
178 if (!(nondef & kXfermode_NonDef)) { | |
179 paint.setXfermodeMode(mode); | |
180 } | |
181 | |
182 return paint; | |
183 } | |
184 | |
185 class SkPipeReader : public SkReadBuffer { | |
186 public: | |
187 SkPipeReader(SkPipeDeserializer* sink, const void* data, size_t size) | |
188 : SkReadBuffer(data, size) | |
189 , fSink(sink) | |
190 {} | |
191 | |
192 SkPipeDeserializer* fSink; | |
193 | |
194 SkFlattenable::Factory findFactory(const char name[]) { | |
195 SkFlattenable::Factory factory; | |
196 // Check if a custom Factory has been specified for this flattenable. | |
197 if (!(factory = this->getCustomFactory(SkString(name)))) { | |
198 // If there is no custom Factory, check for a default. | |
199 factory = SkFlattenable::NameToFactory(name); | |
200 } | |
201 return factory; | |
202 } | |
203 | |
204 void readPaint(SkPaint* paint) override { | |
205 *paint = read_paint(*this); | |
206 } | |
207 }; | |
208 | |
209 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
210 | |
211 typedef void (*SkPipeHandler)(SkPipeReader&, uint32_t packedVerb, SkCanvas*); | |
212 | |
213 static void save_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* ca nvas) { | |
214 SkASSERT(SkPipeVerb::kSave == unpack_verb(packedVerb)); | |
215 canvas->save(); | |
216 } | |
217 | |
218 static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
219 SkASSERT(SkPipeVerb::kSaveLayer == unpack_verb(packedVerb)); | |
220 unsigned extra = unpack_verb_extra(packedVerb); | |
221 const SkRect* bounds = (extra & kHasBounds_SaveLayerMask) ? skip<SkRect>(rea der) : nullptr; | |
222 SkPaint paintStorage, *paint = nullptr; | |
223 if (extra & kHasPaint_SaveLayerMask) { | |
224 paintStorage = read_paint(reader); | |
225 paint = &paintStorage; | |
226 } | |
227 sk_sp<SkImageFilter> backdrop; | |
228 if (extra & kHasBackdrop_SaveLayerMask) { | |
229 backdrop = reader.readImageFilter(); | |
230 } | |
231 SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_S aveLayerMask); | |
232 canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), flag s)); | |
233 } | |
234 | |
235 static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { | |
236 SkASSERT(SkPipeVerb::kRestore == unpack_verb(packedVerb)); | |
237 canvas->restore(); | |
238 } | |
239 | |
240 static void concat_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { | |
241 SkASSERT(SkPipeVerb::kConcat == unpack_verb(packedVerb)); | |
242 SkMatrix::TypeMask tm = (SkMatrix::TypeMask)unpack_verb_extra(packedVerb); | |
243 canvas->concat(read_sparse_matrix(reader, tm)); | |
244 } | |
245 | |
246 static void clipRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
247 SkASSERT(SkPipeVerb::kClipRect == unpack_verb(packedVerb)); | |
248 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
249 bool isAA = unpack_verb_extra(packedVerb) & 1; | |
250 canvas->clipRect(*skip<SkRect>(reader), op, isAA); | |
251 } | |
252 | |
253 static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
254 SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb)); | |
255 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
256 bool isAA = unpack_verb_extra(packedVerb) & 1; | |
257 canvas->clipRRect(read_rrect(reader), op, isAA); | |
258 } | |
259 | |
260 static void clipPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
261 SkASSERT(SkPipeVerb::kClipPath == unpack_verb(packedVerb)); | |
262 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
263 bool isAA = unpack_verb_extra(packedVerb) & 1; | |
264 SkPath path; | |
265 reader.readPath(&path); | |
266 canvas->clipPath(path, op, isAA); | |
267 } | |
268 | |
269 static void clipRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanv as* canvas) { | |
270 SkASSERT(SkPipeVerb::kClipRegion == unpack_verb(packedVerb)); | |
271 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
272 SkRegion region; | |
273 reader.readRegion(®ion); | |
274 canvas->clipRegion(region, op); | |
275 } | |
276 | |
277 static void drawDRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanv as* canvas) { | |
278 SkASSERT(SkPipeVerb::kDrawDRRect == unpack_verb(packedVerb)); | |
279 const SkRRect outer = read_rrect(reader); | |
280 const SkRRect inner = read_rrect(reader); | |
281 canvas->drawDRRect(outer, inner, read_paint(reader)); | |
282 } | |
283 | |
284 static void drawText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
285 SkASSERT(SkPipeVerb::kDrawText == unpack_verb(packedVerb)); | |
286 uint32_t len = unpack_verb_extra(packedVerb); | |
287 if (0 == len) { | |
288 len = reader.read32(); | |
289 } | |
290 const void* text = reader.skip(SkAlign4(len)); | |
291 SkScalar x = reader.readScalar(); | |
292 SkScalar y = reader.readScalar(); | |
293 canvas->drawText(text, len, x, y, read_paint(reader)); | |
294 } | |
295 | |
296 static void drawPosText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCan vas* canvas) { | |
297 SkASSERT(SkPipeVerb::kDrawPosText == unpack_verb(packedVerb)); | |
298 uint32_t len = unpack_verb_extra(packedVerb); | |
299 if (0 == len) { | |
300 len = reader.read32(); | |
301 } | |
302 const void* text = reader.skip(SkAlign4(len)); | |
303 int count = reader.read32(); | |
304 const SkPoint* pos = skip<SkPoint>(reader, count); | |
305 SkPaint paint = read_paint(reader); | |
306 SkASSERT(paint.countText(text, len) == count); | |
307 canvas->drawPosText(text, len, pos, paint); | |
308 } | |
309 | |
310 static void drawPosTextH_handler(SkPipeReader& reader, uint32_t packedVerb, SkCa nvas* canvas) { | |
311 SkASSERT(SkPipeVerb::kDrawPosTextH == unpack_verb(packedVerb)); | |
312 uint32_t len = unpack_verb_extra(packedVerb); | |
313 if (0 == len) { | |
314 len = reader.read32(); | |
315 } | |
316 const void* text = reader.skip(SkAlign4(len)); | |
317 int count = reader.read32(); | |
318 const SkScalar* xpos = skip<SkScalar>(reader, count); | |
319 SkScalar constY = reader.readScalar(); | |
320 SkPaint paint = read_paint(reader); | |
321 SkASSERT(paint.countText(text, len) == count); | |
322 canvas->drawPosTextH(text, len, xpos, constY, paint); | |
323 } | |
324 | |
325 static void drawTextOnPath_handler(SkPipeReader& reader, uint32_t packedVerb, Sk Canvas* canvas) { | |
326 SkASSERT(SkPipeVerb::kDrawTextOnPath == unpack_verb(packedVerb)); | |
327 uint32_t byteLength = packedVerb & kTextLength_DrawTextOnPathMask; | |
328 SkMatrix::TypeMask tm = (SkMatrix::TypeMask) | |
329 ((packedVerb & kMatrixType_DrawTextOnPathMask) >> kMatrixType_DrawTe xtOnPathShift); | |
330 | |
331 if (0 == byteLength) { | |
332 byteLength = reader.read32(); | |
333 } | |
334 const void* text = reader.skip(SkAlign4(byteLength)); | |
335 SkPath path; | |
336 reader.readPath(&path); | |
337 const SkMatrix* matrix = nullptr; | |
338 SkMatrix matrixStorage; | |
339 if (tm != SkMatrix::kIdentity_Mask) { | |
340 matrixStorage = read_sparse_matrix(reader, tm); | |
341 matrix = &matrixStorage; | |
342 } | |
343 canvas->drawTextOnPath(text, byteLength, path, matrix, read_paint(reader)); | |
344 } | |
345 | |
346 static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCa nvas* canvas) { | |
347 sk_sp<SkTextBlob> tb = SkTextBlob::MakeFromBuffer(reader); | |
348 SkScalar x = reader.readScalar(); | |
349 SkScalar y = reader.readScalar(); | |
350 canvas->drawTextBlob(tb, x, y, read_paint(reader)); | |
351 } | |
352 | |
353 static void drawTextRSXform_handler(SkPipeReader& reader, uint32_t packedVerb, S kCanvas* canvas) { | |
354 SkASSERT(SkPipeVerb::kDrawTextRSXform == unpack_verb(packedVerb)); | |
355 uint32_t len = unpack_verb_extra(packedVerb) >> 1; | |
356 if (0 == len) { | |
357 len = reader.read32(); | |
358 } | |
359 const void* text = reader.skip(SkAlign4(len)); | |
360 int count = reader.read32(); | |
361 const SkRSXform* xform = skip<SkRSXform>(reader, count); | |
362 const SkRect* cull = (packedVerb & 1) ? skip<SkRect>(reader) : nullptr; | |
363 SkPaint paint = read_paint(reader); | |
364 SkASSERT(paint.countText(text, len) == count); | |
365 canvas->drawTextRSXform(text, len, xform, cull, paint); | |
366 } | |
367 | |
368 static void drawPatch_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
369 SkASSERT(SkPipeVerb::kDrawPatch == unpack_verb(packedVerb)); | |
370 const SkColor* colors = nullptr; | |
371 const SkPoint* tex = nullptr; | |
372 const SkPoint* cubics = skip<SkPoint>(reader, 12); | |
373 if (packedVerb & kHasColors_DrawPatchExtraMask) { | |
374 colors = skip<SkColor>(reader, 4); | |
375 } | |
376 if (packedVerb & kHasTexture_DrawPatchExtraMask) { | |
377 tex = skip<SkPoint>(reader, 4); | |
378 } | |
379 sk_sp<SkXfermode> xfer; | |
380 unsigned mode = packedVerb & kModeEnum_DrawPatchExtraMask; | |
381 if (kExplicitXfer_DrawPatchExtraValue == mode) { | |
382 xfer = reader.readXfermode(); | |
383 } else { | |
384 if (mode != SkXfermode::kSrcOver_Mode) { | |
385 xfer = SkXfermode::Make((SkXfermode::Mode)mode); | |
386 } | |
387 } | |
388 canvas->drawPatch(cubics, colors, tex, xfer.get(), read_paint(reader)); | |
389 } | |
390 | |
391 static void drawPaint_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
392 SkASSERT(SkPipeVerb::kDrawPaint == unpack_verb(packedVerb)); | |
393 canvas->drawPaint(read_paint(reader)); | |
394 } | |
395 | |
396 static void drawRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
397 SkASSERT(SkPipeVerb::kDrawRect == unpack_verb(packedVerb)); | |
398 const SkRect* rect = skip<SkRect>(reader); | |
399 canvas->drawRect(*rect, read_paint(reader)); | |
400 } | |
401 | |
402 static void drawOval_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
403 SkASSERT(SkPipeVerb::kDrawOval == unpack_verb(packedVerb)); | |
404 const SkRect* rect = skip<SkRect>(reader); | |
405 canvas->drawOval(*rect, read_paint(reader)); | |
406 } | |
407 | |
408 static void drawRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
409 SkASSERT(SkPipeVerb::kDrawRRect == unpack_verb(packedVerb)); | |
410 SkRRect rrect = read_rrect(reader); | |
411 canvas->drawRRect(rrect, read_paint(reader)); | |
412 } | |
413 | |
414 static void drawPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
415 SkASSERT(SkPipeVerb::kDrawPath == unpack_verb(packedVerb)); | |
416 SkPath path; | |
417 reader.readPath(&path); | |
418 canvas->drawPath(path, read_paint(reader)); | |
419 } | |
420 | |
421 static void drawPoints_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanv as* canvas) { | |
422 SkASSERT(SkPipeVerb::kDrawPoints == unpack_verb(packedVerb)); | |
423 SkCanvas::PointMode mode = (SkCanvas::PointMode)unpack_verb_extra(packedVerb ); | |
424 int count = reader.read32(); | |
425 const SkPoint* points = skip<SkPoint>(reader, count); | |
426 canvas->drawPoints(mode, count, points, read_paint(reader)); | |
427 } | |
428 | |
429 static void drawImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
430 SkASSERT(SkPipeVerb::kDrawImage == unpack_verb(packedVerb)); | |
431 sk_sp<SkImage> image(reader.readImage()); | |
432 SkScalar x = reader.readScalar(); | |
433 SkScalar y = reader.readScalar(); | |
434 SkPaint paintStorage, *paint = nullptr; | |
435 if (packedVerb & 1) { | |
436 paintStorage = read_paint(reader); | |
437 paint = &paintStorage; | |
438 } | |
439 canvas->drawImage(image, x, y, paint); | |
440 } | |
441 | |
442 static void drawImageRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
443 SkASSERT(SkPipeVerb::kDrawImageRect == unpack_verb(packedVerb)); | |
444 sk_sp<SkImage> image(reader.readImage()); | |
445 const SkRect* src = (packedVerb & 2) ? skip<SkRect>(reader) : nullptr; | |
446 const SkRect* dst = skip<SkRect>(reader); | |
447 SkPaint paintStorage, *paint = nullptr; | |
448 if (packedVerb & 1) { | |
449 paintStorage = read_paint(reader); | |
450 paint = &paintStorage; | |
451 } | |
452 if (src) { | |
453 canvas->drawImageRect(image, *src, *dst, paint); | |
454 } else { | |
455 canvas->drawImageRect(image, *dst, paint); | |
456 } | |
457 } | |
458 | |
459 static void drawImageNine_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
460 SkASSERT(SkPipeVerb::kDrawImageNine == unpack_verb(packedVerb)); | |
461 sk_sp<SkImage> image(reader.readImage()); | |
462 const SkIRect* center = skip<SkIRect>(reader); | |
463 const SkRect* dst = skip<SkRect>(reader); | |
464 SkPaint paintStorage, *paint = nullptr; | |
465 if (packedVerb & 1) { | |
466 paintStorage = read_paint(reader); | |
467 paint = &paintStorage; | |
468 } | |
469 canvas->drawImageNine(image, *center, *dst, paint); | |
470 } | |
471 | |
472 static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCa nvas* canvas) { | |
473 SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb)); | |
474 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode) | |
475 ((packedVerb & kVMode_DrawVerticesMask) >> kVMode_DrawVerticesShift) ; | |
476 int vertexCount = packedVerb & kVCount_DrawVerticesMask; | |
477 if (0 == vertexCount) { | |
478 vertexCount = reader.read32(); | |
479 } | |
480 sk_sp<SkXfermode> xfer; | |
481 unsigned xmode = (packedVerb & kVMode_DrawVerticesMask) >> kVMode_DrawVertic esShift; | |
482 if (0xFF == xmode) { | |
483 xfer = reader.readXfermode(); | |
484 } else { | |
485 xfer = SkXfermode::Make((SkXfermode::Mode)xmode); | |
486 } | |
487 const SkPoint* vertices = skip<SkPoint>(reader, vertexCount); | |
488 const SkPoint* texs = nullptr; | |
489 if (packedVerb & kHasTex_DrawVerticesMask) { | |
490 texs = skip<SkPoint>(reader, vertexCount); | |
491 } | |
492 const SkColor* colors = nullptr; | |
493 if (packedVerb & kHasColors_DrawVerticesMask) { | |
494 colors = skip<SkColor>(reader, vertexCount); | |
495 } | |
496 int indexCount = 0; | |
497 const uint16_t* indices = nullptr; | |
498 if (packedVerb & kHasIndices_DrawVerticesMask) { | |
499 indexCount = reader.read32(); | |
500 indices = skip<uint16_t>(reader, indexCount); | |
501 } | |
502 | |
503 canvas->drawVertices(vmode, vertexCount, vertices, texs, colors, xfer.get(), | |
504 indices, indexCount, read_paint(reader)); | |
505 } | |
506 | |
507 static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCan vas* canvas) { | |
508 SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb)); | |
509 unsigned extra = unpack_verb_extra(packedVerb); | |
510 int index = extra & kIndex_DefineObjectMask; | |
511 SkPicture* pic = reader.getInflator()->getPicture(index); | |
512 SkMatrix matrixStorage, *matrix = nullptr; | |
513 SkPaint paintStorage, *paint = nullptr; | |
514 if (extra & kHasMatrix_DrawPictureExtra) { | |
515 reader.readMatrix(&matrixStorage); | |
516 matrix = &matrixStorage; | |
517 } | |
518 if (extra & kHasPaint_DrawPictureExtra) { | |
519 paintStorage = read_paint(reader); | |
520 paint = &paintStorage; | |
521 } | |
522 canvas->drawPicture(pic, matrix, paint); | |
523 } | |
524 | |
525 static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, Sk Canvas* canvas) { | |
526 SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb)); | |
527 const SkRect* rect = skip<SkRect>(reader); | |
528 | |
529 // len includes the key's trailing 0 | |
530 uint32_t len = unpack_verb_extra(packedVerb) >> 1; | |
531 if (0 == len) { | |
532 len = reader.read32(); | |
533 } | |
534 const char* key = skip<char>(reader, len); | |
535 sk_sp<SkData> data; | |
536 if (packedVerb & 1) { | |
537 uint32_t size = reader.read32(); | |
538 data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size); | |
539 } | |
540 canvas->drawAnnotation(*rect, key, data); | |
541 } | |
542 | |
543 static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCan vas* canvas) { | |
544 SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb)); | |
545 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); | |
546 uint32_t extra = unpack_verb_extra(packedVerb); | |
547 int index = extra & kIndex_DefineObjectMask; | |
548 | |
549 if (extra & kForget_DefineObjectMask) { | |
550 // zero-index means we are "forgetting" that cache entry | |
551 inflator->setImage(index, nullptr); | |
552 } else { | |
553 // we are defining a new image | |
554 sk_sp<SkData> data = reader.readByteArrayAsData(); | |
555 sk_sp<SkImage> image = SkImage::MakeFromEncoded(data); | |
556 inflator->setImage(index, image.get()); | |
557 } | |
558 } | |
559 | |
560 static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
561 SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)); | |
562 uint32_t extra = unpack_verb_extra(packedVerb); | |
563 // we expect our caller to notice the "kEnd" and not call us | |
564 SkASSERT(0 == (extra & kEnd_DefinePictureMask)); | |
565 | |
566 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); | |
567 int index = extra & kIndex_DefineObjectMask; | |
568 | |
569 if (extra & kForget_DefineObjectMask) { | |
570 // zero-index means we are "forgetting" that cache entry | |
571 inflator->setPicture(index, nullptr); | |
572 } else { | |
573 SkPictureRecorder recorder; | |
574 do_playback(reader, recorder.beginRecording(9999, 9999)); | |
575 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); | |
576 inflator->setPicture(index, picture.get()); | |
577 } | |
578 } | |
579 | |
580 static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, Sk Canvas* canvas) { | |
581 SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb)); | |
582 } | |
583 | |
584 static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
585 SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb)); | |
586 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); | |
587 uint32_t extra = unpack_verb_extra(packedVerb); | |
588 int index = extra >> kNameLength_DefineFactoryExtraBits; | |
589 size_t len = extra & kNameLength_DefineFactoryExtraMask; | |
590 | |
591 const char* name = (const char*)reader.skip(SkAlign4(len)); | |
592 SkFlattenable::Factory factory = reader.findFactory(name); | |
593 if (factory) { | |
594 inflator->setFactory(index, factory); | |
595 } | |
596 } | |
597 | |
598 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
599 | |
600 struct HandlerRec { | |
601 SkPipeHandler fProc; | |
602 const char* fName; | |
603 }; | |
604 | |
605 #define HANDLER(name) { name##_handler, #name } | |
606 const HandlerRec gPipeHandlers[] = { | |
607 HANDLER(save), | |
608 HANDLER(saveLayer), | |
609 HANDLER(restore), | |
610 HANDLER(concat), | |
611 | |
612 HANDLER(clipRect), | |
613 HANDLER(clipRRect), | |
614 HANDLER(clipPath), | |
615 HANDLER(clipRegion), | |
616 | |
617 HANDLER(drawDRRect), | |
618 HANDLER(drawText), | |
619 HANDLER(drawPosText), | |
620 HANDLER(drawPosTextH), | |
621 HANDLER(drawTextOnPath), | |
622 HANDLER(drawTextBlob), | |
623 HANDLER(drawTextRSXform), | |
624 HANDLER(drawPatch), | |
625 HANDLER(drawPaint), | |
626 HANDLER(drawPoints), | |
627 HANDLER(drawRect), | |
628 HANDLER(drawPath), | |
629 HANDLER(drawOval), | |
630 HANDLER(drawRRect), | |
631 | |
632 HANDLER(drawImage), | |
633 HANDLER(drawImageRect), | |
634 HANDLER(drawImageNine), | |
635 | |
636 HANDLER(drawVertices), | |
637 | |
638 HANDLER(drawPicture), | |
639 HANDLER(drawAnnotation), | |
640 | |
641 HANDLER(defineImage), | |
642 HANDLER(definePicture), | |
643 HANDLER(defineTypeface), | |
644 HANDLER(defineFactory), | |
645 }; | |
646 #undef HANDLER | |
647 | |
648 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
649 | |
650 class SkPipeDeserializer::Impl { | |
651 public: | |
652 SkRefSet<SkImage> fImages; | |
653 SkRefSet<SkPicture> fPictures; | |
654 SkRefSet<SkTypeface> fTypefaces; | |
655 SkTDArray<SkFlattenable::Factory> fFactories; | |
656 }; | |
657 | |
658 SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {} | |
659 SkPipeDeserializer::~SkPipeDeserializer() { delete fImpl; } | |
660 | |
661 sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) { | |
662 if (size < sizeof(uint32_t) + sizeof(SkRect)) { | |
663 return nullptr; | |
664 } | |
665 | |
666 uint32_t header; | |
667 memcpy(&header, data, 4); size -= 4; data = (const char*)data + 4; | |
668 if (kDefinePicture_ExtPipeVerb != header) { | |
669 return nullptr; | |
670 } | |
671 SkRect cull; | |
672 memcpy(&cull, data, sizeof(SkRect)); | |
673 size -= sizeof(SkRect); data = (const char*)data + sizeof(SkRect); | |
674 | |
675 SkPictureRecorder recorder; | |
676 this->playback(data, size, recorder.beginRecording(cull)); | |
677 return recorder.finishRecordingAsPicture(); | |
678 } | |
679 | |
680 sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) { | |
681 if (size < sizeof(uint32_t)) { | |
682 return nullptr; | |
683 } | |
684 | |
685 uint32_t header; | |
686 memcpy(&header, data, 4); size -= 4; data = (const char*)data + 4; | |
687 if (kDefineImage_ExtPipeVerb != header) { | |
688 return nullptr; | |
689 } | |
690 | |
691 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, | |
692 &fImpl->fTypefaces, &fImpl->fFactories); | |
693 SkPipeReader reader(this, data, size); | |
694 reader.setInflator(&inflator); | |
695 return sk_sp<SkImage>(reader.readImage()); | |
696 } | |
697 | |
698 static bool do_playback(SkPipeReader& reader, SkCanvas* canvas) { | |
699 const bool showEachVerb = true; | |
700 int counter = 0; | |
701 while (!reader.eof()) { | |
702 uint32_t prevOffset = reader.offset(); | |
703 uint32_t packedVerb = reader.read32(); | |
704 SkPipeVerb verb = unpack_verb(packedVerb); | |
705 if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) { | |
706 SkDebugf("------- bad verb %d\n", verb); | |
707 return false; | |
708 } | |
709 | |
710 if (SkPipeVerb::kDefinePicture == verb && (packedVerb & kEnd_DefinePictu reMask)) { | |
711 return true; | |
712 } | |
713 HandlerRec rec = gPipeHandlers[(unsigned)verb]; | |
714 rec.fProc(reader, packedVerb, canvas); | |
715 if (showEachVerb) { | |
716 SkDebugf("[%d] %s %d\n", counter++, rec.fName, reader.offset() - pre vOffset); | |
717 } | |
718 if (!reader.isValid()) { | |
719 SkDebugf("-------- bad reader\n"); | |
720 return false; | |
721 } | |
722 } | |
723 return true; | |
724 } | |
725 | |
726 bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canva s) { | |
727 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, | |
728 &fImpl->fTypefaces, &fImpl->fFactories); | |
729 SkPipeReader reader(this, data, size); | |
730 reader.setInflator(&inflator); | |
731 return do_playback(reader, canvas); | |
732 } | |
733 | |
OLD | NEW |