/* * 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 fPic; }; SkPictureRecorder fRecorder; SkTDArray 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 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)); }