OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include <new> | 7 #include <new> |
8 #include "SkPictureData.h" | 8 #include "SkPictureData.h" |
9 #include "SkPictureRecord.h" | 9 #include "SkPictureRecord.h" |
10 #include "SkReadBuffer.h" | 10 #include "SkReadBuffer.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 | 61 |
62 // templatize to consolidate with similar picture logic? | 62 // templatize to consolidate with similar picture logic? |
63 const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs(); | 63 const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs(); |
64 fTextBlobCount = blobs.count(); | 64 fTextBlobCount = blobs.count(); |
65 if (fTextBlobCount > 0) { | 65 if (fTextBlobCount > 0) { |
66 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount); | 66 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount); |
67 for (int i = 0; i < fTextBlobCount; ++i) { | 67 for (int i = 0; i < fTextBlobCount; ++i) { |
68 fTextBlobRefs[i] = SkRef(blobs[i]); | 68 fTextBlobRefs[i] = SkRef(blobs[i]); |
69 } | 69 } |
70 } | 70 } |
71 | |
72 const SkTDArray<const SkImage*>& imgs = record.getImageRefs(); | |
73 fImageCount = imgs.count(); | |
74 if (fImageCount > 0) { | |
75 fImageRefs = SkNEW_ARRAY(const SkImage*, fImageCount); | |
76 for (int i = 0; i < fImageCount; ++i) { | |
77 fImageRefs[i] = SkRef(imgs[i]); | |
78 } | |
79 } | |
71 } | 80 } |
72 | 81 |
73 void SkPictureData::init() { | 82 void SkPictureData::init() { |
74 fPictureRefs = NULL; | 83 fPictureRefs = NULL; |
75 fPictureCount = 0; | 84 fPictureCount = 0; |
76 fTextBlobRefs = NULL; | 85 fTextBlobRefs = NULL; |
77 fTextBlobCount = 0; | 86 fTextBlobCount = 0; |
87 fImageRefs = NULL; | |
88 fImageCount = 0; | |
78 fOpData = NULL; | 89 fOpData = NULL; |
79 fFactoryPlayback = NULL; | 90 fFactoryPlayback = NULL; |
80 } | 91 } |
81 | 92 |
82 SkPictureData::~SkPictureData() { | 93 SkPictureData::~SkPictureData() { |
83 SkSafeUnref(fOpData); | 94 SkSafeUnref(fOpData); |
84 | 95 |
85 for (int i = 0; i < fPictureCount; i++) { | 96 for (int i = 0; i < fPictureCount; i++) { |
86 fPictureRefs[i]->unref(); | 97 fPictureRefs[i]->unref(); |
87 } | 98 } |
88 SkDELETE_ARRAY(fPictureRefs); | 99 SkDELETE_ARRAY(fPictureRefs); |
89 | 100 |
90 for (int i = 0; i < fTextBlobCount; i++) { | 101 for (int i = 0; i < fTextBlobCount; i++) { |
91 fTextBlobRefs[i]->unref(); | 102 fTextBlobRefs[i]->unref(); |
92 } | 103 } |
93 SkDELETE_ARRAY(fTextBlobRefs); | 104 SkDELETE_ARRAY(fTextBlobRefs); |
94 | 105 |
106 for (int i = 0; i < fImageCount; i++) { | |
107 fImageRefs[i]->unref(); | |
108 } | |
109 SkDELETE_ARRAY(fImageRefs); | |
110 | |
95 SkDELETE(fFactoryPlayback); | 111 SkDELETE(fFactoryPlayback); |
96 } | 112 } |
97 | 113 |
98 bool SkPictureData::containsBitmaps() const { | 114 bool SkPictureData::containsBitmaps() const { |
99 if (fBitmaps.count() > 0) { | 115 if (fBitmaps.count() > 0 || fImageCount > 0) { |
100 return true; | 116 return true; |
101 } | 117 } |
102 for (int i = 0; i < fPictureCount; ++i) { | 118 for (int i = 0; i < fPictureCount; ++i) { |
103 if (fPictureRefs[i]->willPlayBackBitmaps()) { | 119 if (fPictureRefs[i]->willPlayBackBitmaps()) { |
104 return true; | 120 return true; |
105 } | 121 } |
106 } | 122 } |
107 return false; | 123 return false; |
108 } | 124 } |
109 | 125 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 buffer.writePath(fPaths[i]); | 226 buffer.writePath(fPaths[i]); |
211 } | 227 } |
212 } | 228 } |
213 | 229 |
214 if (fTextBlobCount > 0) { | 230 if (fTextBlobCount > 0) { |
215 write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount); | 231 write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount); |
216 for (i = 0; i < fTextBlobCount; ++i) { | 232 for (i = 0; i < fTextBlobCount; ++i) { |
217 fTextBlobRefs[i]->flatten(buffer); | 233 fTextBlobRefs[i]->flatten(buffer); |
218 } | 234 } |
219 } | 235 } |
236 | |
237 if (fImageCount > 0) { | |
238 write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount); | |
239 for (i = 0; i < fImageCount; ++i) { | |
240 buffer.writeImage(fImageRefs[i]); | |
241 } | |
242 } | |
220 } | 243 } |
221 | 244 |
222 void SkPictureData::serialize(SkWStream* stream, | 245 void SkPictureData::serialize(SkWStream* stream, |
223 SkPixelSerializer* pixelSerializer) const { | 246 SkPixelSerializer* pixelSerializer) const { |
224 write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); | 247 write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); |
225 stream->write(fOpData->bytes(), fOpData->size()); | 248 stream->write(fOpData->bytes(), fOpData->size()); |
226 | 249 |
227 if (fPictureCount > 0) { | 250 if (fPictureCount > 0) { |
228 write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); | 251 write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); |
229 for (int i = 0; i < fPictureCount; i++) { | 252 for (int i = 0; i < fPictureCount; i++) { |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
396 } | 419 } |
397 if (!buffer.isValid()) { | 420 if (!buffer.isValid()) { |
398 return false; | 421 return false; |
399 } | 422 } |
400 SkDEBUGCODE(haveBuffer = true;) | 423 SkDEBUGCODE(haveBuffer = true;) |
401 } break; | 424 } break; |
402 } | 425 } |
403 return true; // success | 426 return true; // success |
404 } | 427 } |
405 | 428 |
406 bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, | 429 static const SkImage* create_image_from_buffer(SkReadBuffer& buffer) { |
407 uint32_t tag, uint32_t size) { | 430 int width = buffer.read32(); |
431 int height = buffer.read32(); | |
432 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension | |
433 buffer.validate(false); | |
434 return NULL; | |
435 } | |
436 | |
437 SkAutoTUnref<SkData> encoded(buffer.readByteArrayAsData()); | |
438 int originX = buffer.read32(); | |
439 int originY = buffer.read32(); | |
440 if (0 == encoded->size() || originX < 0 || originY < 0) { | |
441 buffer.validate(false); | |
442 return NULL; | |
443 } | |
444 | |
445 const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height); | |
446 return SkImage::NewFromEncoded(encoded, &subset); | |
447 } | |
448 | |
449 // Need a shallow wrapper to return const SkPicture* to match the other factorie s, | |
450 // as SkPicture::CreateFromBuffer() returns SkPicture* | |
451 static const SkPicture* create_picture_from_buffer(SkReadBuffer& buffer) { | |
452 return SkPicture::CreateFromBuffer(buffer); | |
453 } | |
454 | |
455 template <typename T> | |
456 bool new_array_from_buffer(SkReadBuffer& buffer, uint32_t inCount, | |
457 const T*** array, int* outCount, const T* (*factory)( SkReadBuffer&)) { | |
458 if (!buffer.validate((0 == inCount) && (NULL == array))) { | |
scroggo
2015/06/22 18:48:05
This part I found confusing - you actually do want
reed1
2015/06/22 19:19:35
Yea, that's odd. I'll change it to do that.
| |
459 return false; | |
460 } | |
461 *outCount = inCount; | |
462 if (0 == inCount) { | |
463 *array = NULL; | |
464 return true; | |
465 } | |
466 | |
467 *array = SkNEW_ARRAY(const T*, *outCount); | |
468 bool success = true; | |
469 int i = 0; | |
470 for (; i < *outCount; i++) { | |
471 (*array)[i] = factory(buffer); | |
472 if (NULL == (*array)[i]) { | |
473 success = false; | |
474 break; | |
475 } | |
476 } | |
477 if (!success) { | |
478 // Delete all of the blobs that were already created (up to but excludin g i): | |
479 for (int j = 0; j < i; j++) { | |
480 (*array)[j]->unref(); | |
481 } | |
482 // Delete the array | |
483 SkDELETE_ARRAY(*array); | |
484 *array = NULL; | |
485 *outCount = 0; | |
486 return false; | |
487 } | |
488 return true; | |
489 } | |
490 | |
491 bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size) { | |
408 switch (tag) { | 492 switch (tag) { |
409 case SK_PICT_BITMAP_BUFFER_TAG: { | 493 case SK_PICT_BITMAP_BUFFER_TAG: { |
410 const int count = SkToInt(size); | 494 const int count = SkToInt(size); |
411 fBitmaps.reset(count); | 495 fBitmaps.reset(count); |
412 for (int i = 0; i < count; ++i) { | 496 for (int i = 0; i < count; ++i) { |
413 SkBitmap* bm = &fBitmaps[i]; | 497 SkBitmap* bm = &fBitmaps[i]; |
414 if (buffer.readBitmap(bm)) { | 498 if (buffer.readBitmap(bm)) { |
415 bm->setImmutable(); | 499 bm->setImmutable(); |
416 } else { | 500 } else { |
417 return false; | 501 return false; |
418 } | 502 } |
419 } | 503 } |
420 } break; | 504 } break; |
421 case SK_PICT_PAINT_BUFFER_TAG: { | 505 case SK_PICT_PAINT_BUFFER_TAG: { |
422 const int count = SkToInt(size); | 506 const int count = SkToInt(size); |
423 fPaints.reset(count); | 507 fPaints.reset(count); |
424 for (int i = 0; i < count; ++i) { | 508 for (int i = 0; i < count; ++i) { |
425 buffer.readPaint(&fPaints[i]); | 509 buffer.readPaint(&fPaints[i]); |
426 } | 510 } |
427 } break; | 511 } break; |
428 case SK_PICT_PATH_BUFFER_TAG: | 512 case SK_PICT_PATH_BUFFER_TAG: |
429 if (size > 0) { | 513 if (size > 0) { |
430 const int count = buffer.readInt(); | 514 const int count = buffer.readInt(); |
431 fPaths.reset(count); | 515 fPaths.reset(count); |
432 for (int i = 0; i < count; i++) { | 516 for (int i = 0; i < count; i++) { |
433 buffer.readPath(&fPaths[i]); | 517 buffer.readPath(&fPaths[i]); |
434 } | 518 } |
435 } break; | 519 } break; |
436 case SK_PICT_TEXTBLOB_BUFFER_TAG: { | 520 case SK_PICT_TEXTBLOB_BUFFER_TAG: |
437 if (!buffer.validate((0 == fTextBlobCount) && (NULL == fTextBlobRefs ))) { | 521 if (!new_array_from_buffer(buffer, size, &fTextBlobRefs, &fTextBlobC ount, |
522 SkTextBlob::CreateFromBuffer)) { | |
438 return false; | 523 return false; |
439 } | 524 } |
440 fTextBlobCount = size; | 525 break; |
441 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount); | 526 case SK_PICT_IMAGE_BUFFER_TAG: |
442 bool success = true; | 527 if (!new_array_from_buffer(buffer, size, &fImageRefs, &fImageCount, |
443 int i = 0; | 528 create_image_from_buffer)) { |
444 for ( ; i < fTextBlobCount; i++) { | |
445 fTextBlobRefs[i] = SkTextBlob::CreateFromBuffer(buffer); | |
446 if (NULL == fTextBlobRefs[i]) { | |
447 success = false; | |
448 break; | |
449 } | |
450 } | |
451 if (!success) { | |
452 // Delete all of the blobs that were already created (up to but excluding i): | |
453 for (int j = 0; j < i; j++) { | |
454 fTextBlobRefs[j]->unref(); | |
455 } | |
456 // Delete the array | |
457 SkDELETE_ARRAY(fTextBlobRefs); | |
458 fTextBlobRefs = NULL; | |
459 fTextBlobCount = 0; | |
460 return false; | 529 return false; |
461 } | 530 } |
462 } break; | 531 break; |
463 case SK_PICT_READER_TAG: { | 532 case SK_PICT_READER_TAG: { |
464 SkAutoDataUnref data(SkData::NewUninitialized(size)); | 533 SkAutoDataUnref data(SkData::NewUninitialized(size)); |
465 if (!buffer.readByteArray(data->writable_data(), size) || | 534 if (!buffer.readByteArray(data->writable_data(), size) || |
466 !buffer.validate(NULL == fOpData)) { | 535 !buffer.validate(NULL == fOpData)) { |
467 return false; | 536 return false; |
468 } | 537 } |
469 SkASSERT(NULL == fOpData); | 538 SkASSERT(NULL == fOpData); |
470 fOpData = data.detach(); | 539 fOpData = data.detach(); |
471 } break; | 540 } break; |
472 case SK_PICT_PICTURE_TAG: { | 541 case SK_PICT_PICTURE_TAG: |
473 if (!buffer.validate((0 == fPictureCount) && (NULL == fPictureRefs)) ) { | 542 if (!new_array_from_buffer(buffer, size, &fPictureRefs, &fPictureCou nt, |
543 create_picture_from_buffer)) { | |
474 return false; | 544 return false; |
475 } | 545 } |
476 fPictureCount = size; | |
477 fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount); | |
478 bool success = true; | |
479 int i = 0; | |
480 for ( ; i < fPictureCount; i++) { | |
481 fPictureRefs[i] = SkPicture::CreateFromBuffer(buffer); | |
482 if (NULL == fPictureRefs[i]) { | |
483 success = false; | |
484 break; | |
485 } | |
486 } | |
487 if (!success) { | |
488 // Delete all of the pictures that were already created (up to b ut excluding i): | |
489 for (int j = 0; j < i; j++) { | |
490 fPictureRefs[j]->unref(); | |
491 } | |
492 // Delete the array | |
493 SkDELETE_ARRAY(fPictureRefs); | |
494 fPictureCount = 0; | |
495 return false; | |
496 } | |
497 } break; | |
498 default: | 546 default: |
499 // The tag was invalid. | 547 // The tag was invalid. |
500 return false; | 548 return false; |
501 } | 549 } |
502 return true; // success | 550 return true; // success |
503 } | 551 } |
504 | 552 |
505 SkPictureData* SkPictureData::CreateFromStream(SkStream* stream, | 553 SkPictureData* SkPictureData::CreateFromStream(SkStream* stream, |
506 const SkPictInfo& info, | 554 const SkPictInfo& info, |
507 SkPicture::InstallPixelRefProc pr oc) { | 555 SkPicture::InstallPixelRefProc pr oc) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
575 } | 623 } |
576 } | 624 } |
577 | 625 |
578 bool SkPictureData::suitableForLayerOptimization() const { | 626 bool SkPictureData::suitableForLayerOptimization() const { |
579 return fContentInfo.numLayers() > 0; | 627 return fContentInfo.numLayers() > 0; |
580 } | 628 } |
581 #endif | 629 #endif |
582 /////////////////////////////////////////////////////////////////////////////// | 630 /////////////////////////////////////////////////////////////////////////////// |
583 | 631 |
584 | 632 |
OLD | NEW |