2016-06-02 19:41:14 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
2016-08-23 16:15:04 +00:00
|
|
|
#include "SkTArray.h"
|
2016-06-02 19:41:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
File format:
|
|
|
|
BEGINNING_OF_FILE:
|
|
|
|
kMagic
|
2016-08-23 16:15:04 +00:00
|
|
|
uint32_t version_number (==2)
|
2016-06-02 19:41:14 +00:00
|
|
|
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;
|
2016-06-14 18:06:37 +00:00
|
|
|
SkSize fCurrentPageSize;
|
2016-08-23 16:15:04 +00:00
|
|
|
SkTArray<sk_sp<SkPicture>> fPages;
|
|
|
|
SkTArray<SkSize> fSizes;
|
2016-06-02 19:41:14 +00:00
|
|
|
MultiPictureDocument(SkWStream* s, void (*d)(SkWStream*, bool))
|
|
|
|
: SkDocument(s, d) {}
|
|
|
|
~MultiPictureDocument() { this->close(); }
|
|
|
|
|
|
|
|
SkCanvas* onBeginPage(SkScalar w, SkScalar h, const SkRect& c) override {
|
2016-06-14 18:06:37 +00:00
|
|
|
fCurrentPageSize.set(w, h);
|
2016-06-02 19:41:14 +00:00
|
|
|
return trim(fPictureRecorder.beginRecording(w, h), w, h, c);
|
|
|
|
}
|
|
|
|
void onEndPage() override {
|
2016-08-23 16:15:04 +00:00
|
|
|
fSizes.push_back(fCurrentPageSize);
|
|
|
|
fPages.push_back(fPictureRecorder.finishRecordingAsPicture());
|
2016-06-02 19:41:14 +00:00
|
|
|
}
|
2016-09-22 21:12:46 +00:00
|
|
|
void onClose(SkWStream* wStream) override {
|
2016-06-02 19:41:14 +00:00
|
|
|
SkASSERT(wStream);
|
|
|
|
SkASSERT(wStream->bytesWritten() == 0);
|
2016-09-22 21:12:46 +00:00
|
|
|
wStream->writeText(SkMultiPictureDocumentProtocol::kMagic);
|
|
|
|
wStream->write32(SkMultiPictureDocumentProtocol::kVersion);
|
|
|
|
wStream->write32(SkToU32(fPages.count()));
|
2016-08-23 16:15:04 +00:00
|
|
|
for (SkSize s : fSizes) {
|
2016-09-22 21:12:46 +00:00
|
|
|
wStream->write(&s, sizeof(s));
|
2016-06-02 19:41:14 +00:00
|
|
|
}
|
2016-08-23 16:15:04 +00:00
|
|
|
SkSize bigsize = SkMultiPictureDocumentProtocol::Join(fSizes);
|
|
|
|
SkCanvas* c = fPictureRecorder.beginRecording(SkRect::MakeSize(bigsize));
|
|
|
|
for (const sk_sp<SkPicture>& page : fPages) {
|
|
|
|
c->drawPicture(page);
|
|
|
|
c->drawAnnotation(SkRect::MakeEmpty(),
|
|
|
|
SkMultiPictureDocumentProtocol::kEndPage,
|
|
|
|
nullptr);
|
2016-06-02 19:41:14 +00:00
|
|
|
}
|
2016-08-23 16:15:04 +00:00
|
|
|
sk_sp<SkPicture> p = fPictureRecorder.finishRecordingAsPicture();
|
|
|
|
p->serialize(wStream);
|
|
|
|
fPages.reset();
|
|
|
|
fSizes.reset();
|
2016-09-22 21:12:46 +00:00
|
|
|
return;
|
2016-06-02 19:41:14 +00:00
|
|
|
}
|
2016-08-23 16:15:04 +00:00
|
|
|
void onAbort() override {
|
|
|
|
fPages.reset();
|
|
|
|
fSizes.reset();
|
|
|
|
}
|
2016-06-02 19:41:14 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
sk_sp<SkDocument> SkMakeMultiPictureDocument(SkWStream* wStream) {
|
|
|
|
return sk_make_sp<MultiPictureDocument>(wStream, nullptr);
|
|
|
|
}
|