1/* 2 * Copyright 2013 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 "SkDocument.h" 9#include "SkPDFDocument.h" 10#include "SkPDFDeviceFlattener.h" 11 12class SkDocument_PDF : public SkDocument { 13public: 14 SkDocument_PDF(SkWStream* stream, void (*doneProc)(SkWStream*,bool), 15 SkPicture::EncodeBitmap encoder, 16 SkScalar rasterDpi) 17 : SkDocument(stream, doneProc) 18 , fEncoder(encoder) 19 , fRasterDpi(rasterDpi) { 20 fDoc = SkNEW(SkPDFDocument); 21 fCanvas = NULL; 22 fDevice = NULL; 23 } 24 25 virtual ~SkDocument_PDF() { 26 // subclasses must call close() in their destructors 27 this->close(); 28 } 29 30protected: 31 virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height, 32 const SkRect& trimBox) SK_OVERRIDE { 33 SkASSERT(NULL == fCanvas); 34 SkASSERT(NULL == fDevice); 35 36 SkSize mediaBoxSize; 37 mediaBoxSize.set(width, height); 38 39 fDevice = SkNEW_ARGS(SkPDFDeviceFlattener, (mediaBoxSize, &trimBox)); 40 if (fEncoder) { 41 fDevice->setDCTEncoder(fEncoder); 42 } 43 if (fRasterDpi != 0) { 44 fDevice->setRasterDpi(fRasterDpi); 45 } 46 fCanvas = SkNEW_ARGS(SkCanvas, (fDevice)); 47 return fCanvas; 48 } 49 50 virtual void onEndPage() SK_OVERRIDE { 51 SkASSERT(fCanvas); 52 SkASSERT(fDevice); 53 54 fCanvas->flush(); 55 fDoc->appendPage(fDevice); 56 57 fCanvas->unref(); 58 fDevice->unref(); 59 60 fCanvas = NULL; 61 fDevice = NULL; 62 } 63 64 virtual bool onClose(SkWStream* stream) SK_OVERRIDE { 65 SkASSERT(NULL == fCanvas); 66 SkASSERT(NULL == fDevice); 67 68 bool success = fDoc->emitPDF(stream); 69 SkDELETE(fDoc); 70 fDoc = NULL; 71 return success; 72 } 73 74 virtual void onAbort() SK_OVERRIDE { 75 SkDELETE(fDoc); 76 fDoc = NULL; 77 } 78 79private: 80 SkPDFDocument* fDoc; 81 SkPDFDeviceFlattener* fDevice; 82 SkCanvas* fCanvas; 83 SkPicture::EncodeBitmap fEncoder; 84 SkScalar fRasterDpi; 85}; 86 87/////////////////////////////////////////////////////////////////////////////// 88 89SkDocument* SkDocument::CreatePDF(SkWStream* stream, void (*done)(SkWStream*,bool), 90 SkPicture::EncodeBitmap enc, 91 SkScalar dpi) { 92 return stream ? SkNEW_ARGS(SkDocument_PDF, (stream, done, enc, dpi)) : NULL; 93} 94 95static void delete_wstream(SkWStream* stream, bool aborted) { 96 SkDELETE(stream); 97} 98 99SkDocument* SkDocument::CreatePDF(const char path[], 100 SkPicture::EncodeBitmap enc, 101 SkScalar dpi) { 102 SkFILEWStream* stream = SkNEW_ARGS(SkFILEWStream, (path)); 103 if (!stream->isValid()) { 104 SkDELETE(stream); 105 return NULL; 106 } 107 return SkNEW_ARGS(SkDocument_PDF, (stream, delete_wstream, enc, dpi)); 108} 109