diff options
author | 2016-08-23 09:15:04 -0700 | |
---|---|---|
committer | 2016-08-23 09:15:04 -0700 | |
commit | c966ef9f07eed89bd571e3f89f8eb86f73b9328f (patch) | |
tree | 718c283931e211d1d8ae6cb7175be6057f2bf3c6 /src/utils/SkMultiPictureDocumentReader.cpp | |
parent | afdc177e77a4d083a23f709113ca97e4905df9ff (diff) |
SkMultiSKP: version 2
Measurable size improvement.
BUG=skia:5370
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2255333003
Review-Url: https://codereview.chromium.org/2255333003
Diffstat (limited to 'src/utils/SkMultiPictureDocumentReader.cpp')
-rw-r--r-- | src/utils/SkMultiPictureDocumentReader.cpp | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/src/utils/SkMultiPictureDocumentReader.cpp b/src/utils/SkMultiPictureDocumentReader.cpp index 6bc77bfc76..3924f3eb42 100644 --- a/src/utils/SkMultiPictureDocumentReader.cpp +++ b/src/utils/SkMultiPictureDocumentReader.cpp @@ -9,6 +9,8 @@ #include "SkMultiPictureDocumentReader.h" #include "SkPicture.h" #include "SkStream.h" +#include "SkPictureRecorder.h" +#include "SkNWayCanvas.h" bool SkMultiPictureDocumentReader::init(SkStreamSeekable* stream) { if (!stream) { @@ -24,26 +26,68 @@ bool SkMultiPictureDocumentReader::init(SkStreamSeekable* stream) { } bool good = true; uint32_t versionNumber = stream->readU32(); - if (versionNumber != 1) { + if (versionNumber != SkMultiPictureDocumentProtocol::kVersion) { return false; } uint32_t pageCount = stream->readU32(); fSizes.reset(pageCount); - fOffsets.reset(pageCount); for (uint32_t i = 0; i < pageCount; ++i) { - SkMultiPictureDocumentProtocol::Entry entry; - good &= sizeof(entry) == stream->read(&entry, sizeof(entry)); - fSizes[i] = SkSize::Make(entry.sizeX, entry.sizeY); - good &= SkTFitsIn<size_t>(entry.offset); - fOffsets[i] = static_cast<size_t>(entry.offset); + SkSize size; + good &= sizeof(size) == stream->read(&size, sizeof(size)); + fSizes[i] = size; } + fOffset = stream->getPosition(); return good; } +namespace { +struct PagerCanvas : public SkNWayCanvas { + SkPictureRecorder fRecorder; + const SkTArray<SkSize>* fSizes; + SkTArray<sk_sp<SkPicture>>* fDest; + PagerCanvas(SkISize wh, + const SkTArray<SkSize>* s, + SkTArray<sk_sp<SkPicture>>* d) + : SkNWayCanvas(wh.width(), wh.height()), fSizes(s), fDest(d) { + this->nextCanvas(); + } + void nextCanvas() { + int i = fDest->count(); + if (i < fSizes->count()) { + SkRect bounds = SkRect::MakeSize((*fSizes)[i]); + this->addCanvas(fRecorder.beginRecording(bounds)); + } + } + void onDrawAnnotation(const SkRect& r, const char* key, SkData* d) override { + if (0 == strcmp(key, SkMultiPictureDocumentProtocol::kEndPage)) { + this->removeAll(); + if (fRecorder.getRecordingCanvas()) { + fDest->emplace_back(fRecorder.finishRecordingAsPicture()); + } + this->nextCanvas(); + } else { + this->SkNWayCanvas::onDrawAnnotation(r, key, d); + } + } +}; +} // namespace + sk_sp<SkPicture> SkMultiPictureDocumentReader::readPage(SkStreamSeekable* stream, int pageNumber) const { SkASSERT(pageNumber >= 0); - SkASSERT(pageNumber < fOffsets.count()); - SkAssertResult(stream->seek(fOffsets[pageNumber])); - return SkPicture::MakeFromStream(stream); + SkASSERT(pageNumber < fSizes.count()); + if (0 == fPages.count()) { + stream->seek(fOffset); // jump to beginning of skp + auto picture = SkPicture::MakeFromStream(stream); + SkISize size = SkMultiPictureDocumentProtocol::Join(fSizes).toCeil(); + PagerCanvas canvas(size, &fSizes, &this->fPages); + // Must call playback(), not drawPicture() to reach + // PagerCanvas::onDrawAnnotation(). + picture->playback(&canvas); + if (fPages.count() != fSizes.count()) { + SkDEBUGF(("Malformed SkMultiPictureDocument\n")); + } + } + // Allow for malformed document. + return pageNumber < fPages.count() ? fPages[pageNumber] : nullptr; } |