michael@0: /* michael@0: * Copyright 2013 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #include "SkDocument.h" michael@0: #include "SkPDFDocument.h" michael@0: #include "SkPDFDeviceFlattener.h" michael@0: michael@0: class SkDocument_PDF : public SkDocument { michael@0: public: michael@0: SkDocument_PDF(SkWStream* stream, void (*doneProc)(SkWStream*,bool), michael@0: SkPicture::EncodeBitmap encoder, michael@0: SkScalar rasterDpi) michael@0: : SkDocument(stream, doneProc) michael@0: , fEncoder(encoder) michael@0: , fRasterDpi(rasterDpi) { michael@0: fDoc = SkNEW(SkPDFDocument); michael@0: fCanvas = NULL; michael@0: fDevice = NULL; michael@0: } michael@0: michael@0: virtual ~SkDocument_PDF() { michael@0: // subclasses must call close() in their destructors michael@0: this->close(); michael@0: } michael@0: michael@0: protected: michael@0: virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height, michael@0: const SkRect& trimBox) SK_OVERRIDE { michael@0: SkASSERT(NULL == fCanvas); michael@0: SkASSERT(NULL == fDevice); michael@0: michael@0: SkSize mediaBoxSize; michael@0: mediaBoxSize.set(width, height); michael@0: michael@0: fDevice = SkNEW_ARGS(SkPDFDeviceFlattener, (mediaBoxSize, &trimBox)); michael@0: if (fEncoder) { michael@0: fDevice->setDCTEncoder(fEncoder); michael@0: } michael@0: if (fRasterDpi != 0) { michael@0: fDevice->setRasterDpi(fRasterDpi); michael@0: } michael@0: fCanvas = SkNEW_ARGS(SkCanvas, (fDevice)); michael@0: return fCanvas; michael@0: } michael@0: michael@0: virtual void onEndPage() SK_OVERRIDE { michael@0: SkASSERT(fCanvas); michael@0: SkASSERT(fDevice); michael@0: michael@0: fCanvas->flush(); michael@0: fDoc->appendPage(fDevice); michael@0: michael@0: fCanvas->unref(); michael@0: fDevice->unref(); michael@0: michael@0: fCanvas = NULL; michael@0: fDevice = NULL; michael@0: } michael@0: michael@0: virtual bool onClose(SkWStream* stream) SK_OVERRIDE { michael@0: SkASSERT(NULL == fCanvas); michael@0: SkASSERT(NULL == fDevice); michael@0: michael@0: bool success = fDoc->emitPDF(stream); michael@0: SkDELETE(fDoc); michael@0: fDoc = NULL; michael@0: return success; michael@0: } michael@0: michael@0: virtual void onAbort() SK_OVERRIDE { michael@0: SkDELETE(fDoc); michael@0: fDoc = NULL; michael@0: } michael@0: michael@0: private: michael@0: SkPDFDocument* fDoc; michael@0: SkPDFDeviceFlattener* fDevice; michael@0: SkCanvas* fCanvas; michael@0: SkPicture::EncodeBitmap fEncoder; michael@0: SkScalar fRasterDpi; michael@0: }; michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: SkDocument* SkDocument::CreatePDF(SkWStream* stream, void (*done)(SkWStream*,bool), michael@0: SkPicture::EncodeBitmap enc, michael@0: SkScalar dpi) { michael@0: return stream ? SkNEW_ARGS(SkDocument_PDF, (stream, done, enc, dpi)) : NULL; michael@0: } michael@0: michael@0: static void delete_wstream(SkWStream* stream, bool aborted) { michael@0: SkDELETE(stream); michael@0: } michael@0: michael@0: SkDocument* SkDocument::CreatePDF(const char path[], michael@0: SkPicture::EncodeBitmap enc, michael@0: SkScalar dpi) { michael@0: SkFILEWStream* stream = SkNEW_ARGS(SkFILEWStream, (path)); michael@0: if (!stream->isValid()) { michael@0: SkDELETE(stream); michael@0: return NULL; michael@0: } michael@0: return SkNEW_ARGS(SkDocument_PDF, (stream, delete_wstream, enc, dpi)); michael@0: }