| Index: src/core/SkPicture.cpp
|
| diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
|
| index ca1b6fa22a94cf0f84d7bd6ac0c61a7338f7c12e..0d31ab403ebf4fd2bbae50f27ac4cdab4ddc1d29 100644
|
| --- a/src/core/SkPicture.cpp
|
| +++ b/src/core/SkPicture.cpp
|
| @@ -265,6 +265,7 @@ void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
|
| #include "SkStream.h"
|
|
|
| static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' };
|
| +static const size_t kHeaderSize = sizeof(kMagic) + sizeof(SkPictInfo);
|
|
|
| bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
|
| if (NULL == stream) {
|
| @@ -273,8 +274,8 @@ bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
|
|
|
| // Check magic bytes.
|
| char magic[sizeof(kMagic)];
|
| - stream->read(magic, sizeof(kMagic));
|
| - if (0 != memcmp(magic, kMagic, sizeof(kMagic))) {
|
| + if (!stream->read(magic, sizeof(kMagic)) ||
|
| + (0 != memcmp(magic, kMagic, sizeof(kMagic)))) {
|
| return false;
|
| }
|
|
|
| @@ -293,6 +294,30 @@ bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
|
| return true;
|
| }
|
|
|
| +bool SkPicture::BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo) {
|
| + // Check magic bytes.
|
| + char magic[sizeof(kMagic)];
|
| +
|
| + if (!buffer.readByteArray(magic, sizeof(kMagic)) ||
|
| + (0 != memcmp(magic, kMagic, sizeof(kMagic)))) {
|
| + return false;
|
| + }
|
| +
|
| + SkPictInfo info;
|
| + if (!buffer.readByteArray(&info, sizeof(SkPictInfo))) {
|
| + return false;
|
| + }
|
| +
|
| + if (PICTURE_VERSION != info.fVersion) {
|
| + return false;
|
| + }
|
| +
|
| + if (pInfo != NULL) {
|
| + *pInfo = info;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height)
|
| : fPlayback(playback)
|
| , fRecord(NULL)
|
| @@ -320,31 +345,56 @@ SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
|
| return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
|
| }
|
|
|
| -void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
|
| - SkPicturePlayback* playback = fPlayback;
|
| +SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
|
| + SkPictInfo info;
|
|
|
| - if (NULL == playback && fRecord) {
|
| - playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord));
|
| + if (!BufferIsSKP(buffer, &info)) {
|
| + return NULL;
|
| }
|
|
|
| - SkPictInfo info;
|
| + SkPicturePlayback* playback;
|
| + // Check to see if there is a playback to recreate.
|
| + if (buffer.readBool()) {
|
| + playback = SkPicturePlayback::CreateFromBuffer(buffer);
|
| + if (NULL == playback) {
|
| + return NULL;
|
| + }
|
| + } else {
|
| + playback = NULL;
|
| + }
|
| +
|
| + return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
|
| +}
|
|
|
| - info.fVersion = PICTURE_VERSION;
|
| - info.fWidth = fWidth;
|
| - info.fHeight = fHeight;
|
| - info.fFlags = SkPictInfo::kCrossProcess_Flag;
|
| +void SkPicture::createHeader(void* header) const {
|
| + // Copy magic bytes at the beginning of the header
|
| + SkASSERT(sizeof(kMagic) == 8);
|
| + memcpy(header, kMagic, sizeof(kMagic));
|
| +
|
| + // Set piture info after magic bytes in the header
|
| + SkPictInfo* info = (SkPictInfo*)(((char*)header) + sizeof(kMagic));
|
| + info->fVersion = PICTURE_VERSION;
|
| + info->fWidth = fWidth;
|
| + info->fHeight = fHeight;
|
| + info->fFlags = SkPictInfo::kCrossProcess_Flag;
|
| // TODO: remove this flag, since we're always float (now)
|
| - info.fFlags |= SkPictInfo::kScalarIsFloat_Flag;
|
| + info->fFlags |= SkPictInfo::kScalarIsFloat_Flag;
|
|
|
| if (8 == sizeof(void*)) {
|
| - info.fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
|
| + info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
|
| }
|
| +}
|
|
|
| - // Write 8 magic bytes to ID this file format.
|
| - SkASSERT(sizeof(kMagic) == 8);
|
| - stream->write(kMagic, sizeof(kMagic));
|
| +void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
|
| + SkPicturePlayback* playback = fPlayback;
|
| +
|
| + if (NULL == playback && fRecord) {
|
| + playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord));
|
| + }
|
|
|
| - stream->write(&info, sizeof(info));
|
| + char header[kHeaderSize];
|
| + createHeader(&header);
|
| + stream->write(header, kHeaderSize);
|
| if (playback) {
|
| stream->writeBool(true);
|
| playback->serialize(stream, encoder);
|
| @@ -357,6 +407,28 @@ void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
|
| }
|
| }
|
|
|
| +void SkPicture::flatten(SkWriteBuffer& buffer) const {
|
| + SkPicturePlayback* playback = fPlayback;
|
| +
|
| + if (NULL == playback && fRecord) {
|
| + playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord));
|
| + }
|
| +
|
| + char header[kHeaderSize];
|
| + createHeader(&header);
|
| + buffer.writeByteArray(header, kHeaderSize);
|
| + if (playback) {
|
| + buffer.writeBool(true);
|
| + playback->flatten(buffer);
|
| + // delete playback if it is a local version (i.e. cons'd up just now)
|
| + if (playback != fPlayback) {
|
| + SkDELETE(playback);
|
| + }
|
| + } else {
|
| + buffer.writeBool(false);
|
| + }
|
| +}
|
| +
|
| bool SkPicture::willPlayBackBitmaps() const {
|
| if (!fPlayback) return false;
|
| return fPlayback->containsBitmaps();
|
|
|