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: #ifndef SkDocument_DEFINED michael@0: #define SkDocument_DEFINED michael@0: michael@0: #include "SkBitmap.h" michael@0: #include "SkPicture.h" michael@0: #include "SkRect.h" michael@0: #include "SkRefCnt.h" michael@0: michael@0: class SkCanvas; michael@0: class SkWStream; michael@0: michael@0: /** SK_ScalarDefaultDPI is 72 DPI. michael@0: */ michael@0: #define SK_ScalarDefaultRasterDPI 72.0f michael@0: michael@0: /** michael@0: * High-level API for creating a document-based canvas. To use.. michael@0: * michael@0: * 1. Create a document, specifying a stream to store the output. michael@0: * 2. For each "page" of content: michael@0: * a. canvas = doc->beginPage(...) michael@0: * b. draw_my_content(canvas); michael@0: * c. doc->endPage(); michael@0: * 3. Close the document with doc->close(). michael@0: */ michael@0: class SkDocument : public SkRefCnt { michael@0: public: michael@0: SK_DECLARE_INST_COUNT(SkDocument) michael@0: michael@0: /** michael@0: * Create a PDF-backed document, writing the results into a file. michael@0: * If there is an error trying to create the doc, returns NULL. michael@0: * encoder sets the DCTEncoder for images, to encode a bitmap michael@0: * as JPEG (DCT). michael@0: * rasterDpi - the DPI at which features without native PDF support michael@0: * will be rasterized (e.g. draw image with perspective, michael@0: * draw text with perspective, ...) michael@0: * A larger DPI would create a PDF that reflects the original michael@0: * intent with better fidelity, but it can make for larger michael@0: * PDF files too, which would use more memory while rendering, michael@0: * and it would be slower to be processed or sent online or michael@0: * to printer. michael@0: */ michael@0: static SkDocument* CreatePDF( michael@0: const char filename[], michael@0: SkPicture::EncodeBitmap encoder = NULL, michael@0: SkScalar rasterDpi = SK_ScalarDefaultRasterDPI); michael@0: michael@0: /** michael@0: * Create a PDF-backed document, writing the results into a stream. michael@0: * If there is an error trying to create the doc, returns NULL. michael@0: * michael@0: * The document may write to the stream at anytime during its lifetime, michael@0: * until either close() is called or the document is deleted. Once close() michael@0: * has been called, and all of the data has been written to the stream, michael@0: * if there is a Done proc provided, it will be called with the stream. michael@0: * The proc can delete the stream, or whatever it needs to do. michael@0: * encoder sets the DCTEncoder for images, to encode a bitmap michael@0: * as JPEG (DCT). michael@0: * Done - clean up method intended to allow deletion of the stream. michael@0: * Its aborted parameter is true if the cleanup is due to an abort michael@0: * call. It is false otherwise. michael@0: * rasterDpi - the DPI at which features without native PDF support michael@0: * will be rasterized (e.g. draw image with perspective, michael@0: * draw text with perspective, ...) michael@0: * A larger DPI would create a PDF that reflects the original michael@0: * intent with better fidelity, but it can make for larger michael@0: * PDF files too, which would use more memory while rendering, michael@0: * and it would be slower to be processed or sent online or michael@0: * to printer. */ michael@0: static SkDocument* CreatePDF( michael@0: SkWStream*, void (*Done)(SkWStream*,bool aborted) = NULL, michael@0: SkPicture::EncodeBitmap encoder = NULL, michael@0: SkScalar rasterDpi = SK_ScalarDefaultRasterDPI); michael@0: michael@0: /** michael@0: * Begin a new page for the document, returning the canvas that will draw michael@0: * into the page. The document owns this canvas, and it will go out of michael@0: * scope when endPage() or close() is called, or the document is deleted. michael@0: */ michael@0: SkCanvas* beginPage(SkScalar width, SkScalar height, michael@0: const SkRect* content = NULL); michael@0: michael@0: /** michael@0: * Call endPage() when the content for the current page has been drawn michael@0: * (into the canvas returned by beginPage()). After this call the canvas michael@0: * returned by beginPage() will be out-of-scope. michael@0: */ michael@0: void endPage(); michael@0: michael@0: /** michael@0: * Call close() when all pages have been drawn. This will close the file michael@0: * or stream holding the document's contents. After close() the document michael@0: * can no longer add new pages. Deleting the document will automatically michael@0: * call close() if need be. michael@0: * Returns true on success or false on failure. michael@0: */ michael@0: bool close(); michael@0: michael@0: /** michael@0: * Call abort() to stop producing the document immediately. michael@0: * The stream output must be ignored, and should not be trusted. michael@0: */ michael@0: void abort(); michael@0: michael@0: protected: michael@0: SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted)); michael@0: // note: subclasses must call close() in their destructor, as the base class michael@0: // cannot do this for them. michael@0: virtual ~SkDocument(); michael@0: michael@0: virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height, michael@0: const SkRect& content) = 0; michael@0: virtual void onEndPage() = 0; michael@0: virtual bool onClose(SkWStream*) = 0; michael@0: virtual void onAbort() = 0; michael@0: michael@0: enum State { michael@0: kBetweenPages_State, michael@0: kInPage_State, michael@0: kClosed_State michael@0: }; michael@0: State getState() const { return fState; } michael@0: michael@0: private: michael@0: SkWStream* fStream; michael@0: void (*fDoneProc)(SkWStream*, bool aborted); michael@0: State fState; michael@0: michael@0: typedef SkRefCnt INHERITED; michael@0: }; michael@0: michael@0: #endif