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