7822d55e9e39e7934293f7465d59f5efb7eb1156
[platform/upstream/libSkiaSharp.git] / experimental / tools / PageCachingDocument.cpp
1 /*
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
15 namespace {
16
17 typedef void (*DoneProc)(SkWStream*, bool);
18 typedef 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.
22 class PageCachingDocument : public SkDocument {
23 public:
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     void onEndPage() SK_OVERRIDE;
30     bool onClose(SkWStream*) SK_OVERRIDE;
31     void onAbort() SK_OVERRIDE;
32
33 private:
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
45 PageCachingDocument::PageCachingDocument(SkWStream* stream,
46                                          DoneProc done,
47                                          Encoder encoder,
48                                          SkScalar rasterDpi)
49     : SkDocument(stream, done), fEncoder(encoder), fRasterDpi(rasterDpi) {
50 }
51
52 PageCachingDocument::~PageCachingDocument() {
53     for (Page* p = fPages.begin(); p != fPages.end(); ++p) {
54         p->~Page();
55     }
56 }
57
58 SkCanvas* 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
70 void 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
76 bool 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
89 void PageCachingDocument::onAbort() {
90 }
91 }  // namespace
92
93 SkDocument* CreatePageCachingDocument(SkWStream* stream,
94                                       DoneProc done,
95                                       Encoder encoder,
96                                       SkScalar rasterDpi) {
97     return SkNEW_ARGS(PageCachingDocument, (stream, done, encoder, rasterDpi));
98 }