| /* |
| * 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) SK_OVERRIDE; |
| void onEndPage() SK_OVERRIDE; |
| bool onClose(SkWStream*) SK_OVERRIDE; |
| void onAbort() SK_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)); |
| } |