/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkMultiPictureDocument.h" #include "SkMultiPictureDocumentPriv.h" #include "SkPicture.h" #include "SkPictureRecorder.h" #include "SkStream.h" #include "SkTArray.h" /* File format: BEGINNING_OF_FILE: kMagic uint32_t version_number (==2) uint32_t page_count { float sizeX float sizeY } * page_count skp file */ namespace { static SkCanvas* trim(SkCanvas* canvas, SkScalar w, SkScalar h, const SkRect& trimBox) { // Only trim if necessary. if (trimBox != SkRect::MakeWH(w, h)) { // All SkDocument implementations implement trimBox using a // clip+translate. canvas->clipRect(trimBox); canvas->translate(trimBox.x(), trimBox.y()); } return canvas; } struct MultiPictureDocument final : public SkDocument { SkPictureRecorder fPictureRecorder; SkSize fCurrentPageSize; SkTArray> fPages; SkTArray fSizes; MultiPictureDocument(SkWStream* s, void (*d)(SkWStream*, bool)) : SkDocument(s, d) {} ~MultiPictureDocument() { this->close(); } SkCanvas* onBeginPage(SkScalar w, SkScalar h, const SkRect& c) override { fCurrentPageSize.set(w, h); return trim(fPictureRecorder.beginRecording(w, h), w, h, c); } void onEndPage() override { fSizes.push_back(fCurrentPageSize); fPages.push_back(fPictureRecorder.finishRecordingAsPicture()); } void onClose(SkWStream* wStream) override { SkASSERT(wStream); SkASSERT(wStream->bytesWritten() == 0); wStream->writeText(SkMultiPictureDocumentProtocol::kMagic); wStream->write32(SkMultiPictureDocumentProtocol::kVersion); wStream->write32(SkToU32(fPages.count())); for (SkSize s : fSizes) { wStream->write(&s, sizeof(s)); } SkSize bigsize = SkMultiPictureDocumentProtocol::Join(fSizes); SkCanvas* c = fPictureRecorder.beginRecording(SkRect::MakeSize(bigsize)); for (const sk_sp& page : fPages) { c->drawPicture(page); c->drawAnnotation(SkRect::MakeEmpty(), SkMultiPictureDocumentProtocol::kEndPage, nullptr); } sk_sp p = fPictureRecorder.finishRecordingAsPicture(); p->serialize(wStream); fPages.reset(); fSizes.reset(); return; } void onAbort() override { fPages.reset(); fSizes.reset(); } }; } sk_sp SkMakeMultiPictureDocument(SkWStream* wStream) { return sk_make_sp(wStream, nullptr); }