blob: 9baf45c72169e89b7ebada9ad00f65915ecfe5e7 [file] [log] [blame]
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "PageCachingDocument.h"
#include "SkCanvas.h"
#include "SkDocument.h"
#include "SkPictureRecorder.h"
#include "SkRect.h"
#include "SkTDArray.h"
namespace {
typedef void (*DoneProc)(SkWStream*, bool);
typedef SkData* (*Encoder)(size_t*, const SkBitmap&);
// This class allows us to compare the relative memory consumption of
// the PDF and SkPicture backends.
class PageCachingDocument : public SkDocument {
public:
PageCachingDocument(SkWStream*, DoneProc, Encoder, SkScalar rasterDpi);
virtual ~PageCachingDocument();
virtual SkCanvas* onBeginPage(SkScalar width,
SkScalar height,
const SkRect& content) override;
void onEndPage() override;
bool onClose(SkWStream*) override;
void onAbort() override;
private:
struct Page {
SkScalar fWidth;
SkScalar fHeight;
SkAutoTUnref<SkPicture> fPic;
};
SkPictureRecorder fRecorder;
SkTDArray<Page> fPages;
Encoder fEncoder;
SkScalar fRasterDpi;
};
PageCachingDocument::PageCachingDocument(SkWStream* stream,
DoneProc done,
Encoder encoder,
SkScalar rasterDpi)
: SkDocument(stream, done), fEncoder(encoder), fRasterDpi(rasterDpi) {
}
PageCachingDocument::~PageCachingDocument() {
for (Page* p = fPages.begin(); p != fPages.end(); ++p) {
p->~Page();
}
}
SkCanvas* PageCachingDocument::onBeginPage(SkScalar width,
SkScalar height,
const SkRect& content) {
Page* page = fPages.push();
sk_bzero(page, sizeof(*page));
page->fWidth = width;
page->fHeight = height;
SkASSERT(!page->fPic.get());
SkCanvas* canvas = fRecorder.beginRecording(content);
return canvas;
}
void PageCachingDocument::onEndPage() {
SkASSERT(fPages.count() > 0);
SkASSERT(!fPages[fPages.count() - 1].fPic);
fPages[fPages.count() - 1].fPic.reset(fRecorder.endRecording());
}
bool PageCachingDocument::onClose(SkWStream* stream) {
SkAutoTUnref<SkDocument> doc(
SkDocument::CreatePDF(stream, NULL, fEncoder, fRasterDpi));
for (Page* page = fPages.begin(); page != fPages.end(); ++page) {
SkRect cullRect = page->fPic->cullRect();
SkCanvas* canvas =
doc->beginPage(page->fWidth, page->fHeight, &cullRect);
canvas->drawPicture(page->fPic);
doc->endPage();
}
return doc->close();
}
void PageCachingDocument::onAbort() {
}
} // namespace
SkDocument* CreatePageCachingDocument(SkWStream* stream,
DoneProc done,
Encoder encoder,
SkScalar rasterDpi) {
return SkNEW_ARGS(PageCachingDocument, (stream, done, encoder, rasterDpi));
}