158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/*
258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Copyright 2013 Google Inc.
358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *
458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * found in the LICENSE file.
658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */
758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkDocument.h"
958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkPDFDocument.h"
100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkPDFDeviceFlattener.h"
1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerclass SkDocument_PDF : public SkDocument {
1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerpublic:
14910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    SkDocument_PDF(SkWStream* stream, void (*doneProc)(SkWStream*,bool),
150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                   SkPicture::EncodeBitmap encoder,
160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                   SkScalar rasterDpi)
170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            : SkDocument(stream, doneProc)
180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            , fEncoder(encoder)
190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            , fRasterDpi(rasterDpi) {
2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fDoc = SkNEW(SkPDFDocument);
2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fCanvas = NULL;
2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fDevice = NULL;
2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual ~SkDocument_PDF() {
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        // subclasses must call close() in their destructors
2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        this->close();
2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprotected:
3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height,
320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                  const SkRect& trimBox) SK_OVERRIDE {
3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkASSERT(NULL == fCanvas);
3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkASSERT(NULL == fDevice);
3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkSize mediaBoxSize;
370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        mediaBoxSize.set(width, height);
3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fDevice = SkNEW_ARGS(SkPDFDeviceFlattener, (mediaBoxSize, &trimBox));
400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (fEncoder) {
410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fDevice->setDCTEncoder(fEncoder);
420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (fRasterDpi != 0) {
440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fDevice->setRasterDpi(fRasterDpi);
450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
4658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fCanvas = SkNEW_ARGS(SkCanvas, (fDevice));
4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return fCanvas;
4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual void onEndPage() SK_OVERRIDE {
5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkASSERT(fCanvas);
5258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkASSERT(fDevice);
5358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fCanvas->flush();
5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fDoc->appendPage(fDevice);
5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fCanvas->unref();
5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fDevice->unref();
5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fCanvas = NULL;
6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fDevice = NULL;
6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual bool onClose(SkWStream* stream) SK_OVERRIDE {
6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkASSERT(NULL == fCanvas);
6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkASSERT(NULL == fDevice);
6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        bool success = fDoc->emitPDF(stream);
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDELETE(fDoc);
700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fDoc = NULL;
710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return success;
720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void onAbort() SK_OVERRIDE {
7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkDELETE(fDoc);
7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fDoc = NULL;
7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprivate:
8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPDFDocument*  fDoc;
810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkPDFDeviceFlattener* fDevice;
8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkCanvas*       fCanvas;
830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkPicture::EncodeBitmap fEncoder;
840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkScalar        fRasterDpi;
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger};
8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
89910f694aefb0b671dd8522a9afe9b6be645701c1Derek SollenbergerSkDocument* SkDocument::CreatePDF(SkWStream* stream, void (*done)(SkWStream*,bool),
900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                  SkPicture::EncodeBitmap enc,
910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                  SkScalar dpi) {
920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return stream ? SkNEW_ARGS(SkDocument_PDF, (stream, done, enc, dpi)) : NULL;
9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
95910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerstatic void delete_wstream(SkWStream* stream, bool aborted) {
9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkDELETE(stream);
9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
990a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerSkDocument* SkDocument::CreatePDF(const char path[],
1000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                  SkPicture::EncodeBitmap enc,
1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                  SkScalar dpi) {
10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkFILEWStream* stream = SkNEW_ARGS(SkFILEWStream, (path));
10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (!stream->isValid()) {
10458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkDELETE(stream);
10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return NULL;
10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return SkNEW_ARGS(SkDocument_PDF, (stream, delete_wstream, enc, dpi));
10858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
109