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#ifndef SkDocument_DEFINED
958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#define SkDocument_DEFINED
1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkBitmap.h"
120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkPicture.h"
1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkRect.h"
1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkRefCnt.h"
1558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerclass SkCanvas;
1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerclass SkWStream;
1858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger/** SK_ScalarDefaultDPI is 72 DPI.
200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger*/
21910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#define SK_ScalarDefaultRasterDPI           72.0f
220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/**
2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *  High-level API for creating a document-based canvas. To use..
2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *  1. Create a document, specifying a stream to store the output.
2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *  2. For each "page" of content:
2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *      a. canvas = doc->beginPage(...)
2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *      b. draw_my_content(canvas);
3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *      c. doc->endPage();
3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *  3. Close the document with doc->close().
3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */
3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerclass SkDocument : public SkRefCnt {
3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerpublic:
3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SK_DECLARE_INST_COUNT(SkDocument)
3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    /**
3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  Create a PDF-backed document, writing the results into a file.
3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  If there is an error trying to create the doc, returns NULL.
400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  encoder sets the DCTEncoder for images, to encode a bitmap
410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *    as JPEG (DCT).
420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  rasterDpi - the DPI at which features without native PDF support
430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              will be rasterized (e.g. draw image with perspective,
440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              draw text with perspective, ...)
450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              A larger DPI would create a PDF that reflects the original
460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              intent with better fidelity, but it can make for larger
470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              PDF files too, which would use more memory while rendering,
480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              and it would be slower to be processed or sent online or
490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              to printer.
5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     */
510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static SkDocument* CreatePDF(
520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            const char filename[],
530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkPicture::EncodeBitmap encoder = NULL,
540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);
5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    /**
5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  Create a PDF-backed document, writing the results into a stream.
5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  If there is an error trying to create the doc, returns NULL.
5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *
6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  The document may write to the stream at anytime during its lifetime,
6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  until either close() is called or the document is deleted. Once close()
6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  has been called, and all of the data has been written to the stream,
6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  if there is a Done proc provided, it will be called with the stream.
6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  The proc can delete the stream, or whatever it needs to do.
650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  encoder sets the DCTEncoder for images, to encode a bitmap
660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *    as JPEG (DCT).
67910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *  Done - clean up method intended to allow deletion of the stream.
68910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *         Its aborted parameter is true if the cleanup is due to an abort
69910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger     *         call. It is false otherwise.
700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  rasterDpi - the DPI at which features without native PDF support
710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              will be rasterized (e.g. draw image with perspective,
720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              draw text with perspective, ...)
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              A larger DPI would create a PDF that reflects the original
740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              intent with better fidelity, but it can make for larger
750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              PDF files too, which would use more memory while rendering,
760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              and it would be slower to be processed or sent online or
770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *              to printer.     */
780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static SkDocument* CreatePDF(
79910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            SkWStream*, void (*Done)(SkWStream*,bool aborted) = NULL,
800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkPicture::EncodeBitmap encoder = NULL,
810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkScalar rasterDpi = SK_ScalarDefaultRasterDPI);
8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    /**
8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  Begin a new page for the document, returning the canvas that will draw
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  into the page. The document owns this canvas, and it will go out of
8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  scope when endPage() or close() is called, or the document is deleted.
8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     */
8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkCanvas* beginPage(SkScalar width, SkScalar height,
8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                        const SkRect* content = NULL);
9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    /**
9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  Call endPage() when the content for the current page has been drawn
9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  (into the canvas returned by beginPage()). After this call the canvas
9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  returned by beginPage() will be out-of-scope.
9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     */
9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    void endPage();
9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    /**
9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  Call close() when all pages have been drawn. This will close the file
10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  or stream holding the document's contents. After close() the document
10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  can no longer add new pages. Deleting the document will automatically
10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     *  call close() if need be.
1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  Returns true on success or false on failure.
1040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     */
1050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool close();
1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    /**
1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  Call abort() to stop producing the document immediately.
1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger     *  The stream output must be ignored, and should not be trusted.
11058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger     */
1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void abort();
11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
11358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprotected:
114910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted));
11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // note: subclasses must call close() in their destructor, as the base class
11658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    // cannot do this for them.
11758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual ~SkDocument();
11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
11958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height,
12058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                  const SkRect& content) = 0;
12158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual void onEndPage() = 0;
1220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual bool onClose(SkWStream*) = 0;
1230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void onAbort() = 0;
12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
12558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    enum State {
12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        kBetweenPages_State,
12758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        kInPage_State,
12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        kClosed_State
12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    };
13058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    State getState() const { return fState; }
13158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
13258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprivate:
13358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkWStream* fStream;
134910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    void       (*fDoneProc)(SkWStream*, bool aborted);
13558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    State      fState;
13658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
13758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    typedef SkRefCnt INHERITED;
13858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger};
13958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
14058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif
141