blob: 38e883e839acb7735a7198cb842d8ca21fb0f0cc [file] [log] [blame]
halcanary84bc52a2014-12-02 14:01:46 -08001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "PageCachingDocument.h"
9#include "SkCanvas.h"
10#include "SkDocument.h"
11#include "SkPictureRecorder.h"
12#include "SkRect.h"
13#include "SkTDArray.h"
14
15namespace {
16
17typedef void (*DoneProc)(SkWStream*, bool);
18typedef SkData* (*Encoder)(size_t*, const SkBitmap&);
19
20// This class allows us to compare the relative memory consumption of
21// the PDF and SkPicture backends.
22class PageCachingDocument : public SkDocument {
23public:
24 PageCachingDocument(SkWStream*, DoneProc, Encoder, SkScalar rasterDpi);
25 virtual ~PageCachingDocument();
26 virtual SkCanvas* onBeginPage(SkScalar width,
27 SkScalar height,
28 const SkRect& content) SK_OVERRIDE;
29 virtual void onEndPage() SK_OVERRIDE;
30 virtual bool onClose(SkWStream*) SK_OVERRIDE;
31 virtual void onAbort() SK_OVERRIDE;
32
33private:
34 struct Page {
35 SkScalar fWidth;
36 SkScalar fHeight;
37 SkAutoTUnref<SkPicture> fPic;
38 };
39 SkPictureRecorder fRecorder;
40 SkTDArray<Page> fPages;
41 Encoder fEncoder;
42 SkScalar fRasterDpi;
43};
44
45PageCachingDocument::PageCachingDocument(SkWStream* stream,
46 DoneProc done,
47 Encoder encoder,
48 SkScalar rasterDpi)
49 : SkDocument(stream, done), fEncoder(encoder), fRasterDpi(rasterDpi) {
50}
51
52PageCachingDocument::~PageCachingDocument() {
53 for (Page* p = fPages.begin(); p != fPages.end(); ++p) {
54 p->~Page();
55 }
56}
57
58SkCanvas* PageCachingDocument::onBeginPage(SkScalar width,
59 SkScalar height,
60 const SkRect& content) {
61 Page* page = fPages.push();
62 sk_bzero(page, sizeof(*page));
63 page->fWidth = width;
64 page->fHeight = height;
65 SkASSERT(!page->fPic.get());
66 SkCanvas* canvas = fRecorder.beginRecording(content);
67 return canvas;
68}
69
70void PageCachingDocument::onEndPage() {
71 SkASSERT(fPages.count() > 0);
72 SkASSERT(!fPages[fPages.count() - 1].fPic);
73 fPages[fPages.count() - 1].fPic.reset(fRecorder.endRecording());
74}
75
76bool PageCachingDocument::onClose(SkWStream* stream) {
77 SkAutoTUnref<SkDocument> doc(
78 SkDocument::CreatePDF(stream, NULL, fEncoder, fRasterDpi));
79 for (Page* page = fPages.begin(); page != fPages.end(); ++page) {
80 SkRect cullRect = page->fPic->cullRect();
81 SkCanvas* canvas =
82 doc->beginPage(page->fWidth, page->fHeight, &cullRect);
83 canvas->drawPicture(page->fPic);
84 doc->endPage();
85 }
86 return doc->close();
87}
88
89void PageCachingDocument::onAbort() {
90}
91} // namespace
92
93SkDocument* CreatePageCachingDocument(SkWStream* stream,
94 DoneProc done,
95 Encoder encoder,
96 SkScalar rasterDpi) {
97 return SkNEW_ARGS(PageCachingDocument, (stream, done, encoder, rasterDpi));
98}