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; // currently unused |
| 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 & 3)); packedFl
ags >>= 2; |
| 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 & kHasPaint_DrawImageMask) { |
| 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 & kHasPaint_DrawImageNineMask) { |
| 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_ObjectDefinitionMask; |
| 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_skiaimageformat(const void* encoded, size_t enco
dedSize) { |
| 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, "skiaimgf", 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_skiaimageformat(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_ObjectDefinitionMask; |
| 697 |
| 698 if (extra & kUndef_ObjectDefinitionMask) { |
| 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_ObjectDefinitionMask; |
| 725 |
| 726 if (extra & kUndef_ObjectDefinitionMask) { |
| 727 // zero-index means we are "forgetting" that cache entry |
| 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), // handled special -- should never be called |
| 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() {} |
| 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; |
| 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 |