1
2/*
3 * Copyright 2010 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef SkPDFDocument_DEFINED
11#define SkPDFDocument_DEFINED
12
13#include "SkAdvancedTypefaceMetrics.h"
14#include "SkRefCnt.h"
15#include "SkTDArray.h"
16#include "SkTemplates.h"
17
18class SkPDFCatalog;
19class SkPDFDevice;
20class SkPDFDict;
21class SkPDFPage;
22class SkPDFObject;
23class SkWStream;
24template <typename T> class SkTSet;
25
26/** \class SkPDFDocument
27
28    A SkPDFDocument assembles pages together and generates the final PDF file.
29*/
30class SkPDFDocument {
31public:
32    enum Flags {
33        kNoCompression_Flags = 0x01,  //!< DEPRECATED.
34        kFavorSpeedOverSize_Flags = 0x01,  //!< Don't compress the stream, but
35                                           // if it is already compressed return
36                                           // the compressed stream.
37        kNoLinks_Flags       = 0x02,  //!< do not honor link annotations.
38
39        kDraftMode_Flags     = 0x01,
40    };
41    /** Create a PDF document.
42     */
43    explicit SK_API SkPDFDocument(Flags flags = (Flags)0);
44    SK_API ~SkPDFDocument();
45
46    /** Output the PDF to the passed stream.  It is an error to call this (it
47     *  will return false and not modify stream) if no pages have been added
48     *  or there are pages missing (i.e. page 1 and 3 have been added, but not
49     *  page 2).
50     *
51     *  @param stream    The writable output stream to send the PDF to.
52     */
53    SK_API bool emitPDF(SkWStream* stream);
54
55    /** Sets the specific page to the passed PDF device. If the specified
56     *  page is already set, this overrides it. Returns true if successful.
57     *  Will fail if the document has already been emitted.
58     *
59     *  @param pageNumber The position to add the passed device (1 based).
60     *  @param pdfDevice  The page to add to this document.
61     */
62    SK_API bool setPage(int pageNumber, SkPDFDevice* pdfDevice);
63
64    /** Append the passed pdf device to the document as a new page.  Returns
65     *  true if successful.  Will fail if the document has already been emitted.
66     *
67     *  @param pdfDevice The page to add to this document.
68     */
69    SK_API bool appendPage(SkPDFDevice* pdfDevice);
70
71    /** Get the count of unique font types used in the document.
72     * DEPRECATED.
73     */
74    SK_API void getCountOfFontTypes(
75        int counts[SkAdvancedTypefaceMetrics::kOther_Font + 2]) const;
76
77    /** Get the count of unique font types used in the document.
78     */
79    SK_API void getCountOfFontTypes(
80        int counts[SkAdvancedTypefaceMetrics::kOther_Font + 1],
81        int* notSubsettableCount,
82        int* notEmbedddableCount) const;
83
84private:
85    SkAutoTDelete<SkPDFCatalog> fCatalog;
86    int64_t fXRefFileOffset;
87
88    SkTDArray<SkPDFPage*> fPages;
89    SkTDArray<SkPDFDict*> fPageTree;
90    SkPDFDict* fDocCatalog;
91    SkTSet<SkPDFObject*>* fFirstPageResources;
92    SkTSet<SkPDFObject*>* fOtherPageResources;
93    SkTDArray<SkPDFObject*> fSubstitutes;
94
95    SkPDFDict* fTrailerDict;
96
97    /** Output the PDF header to the passed stream.
98     *  @param stream    The writable output stream to send the header to.
99     */
100    void emitHeader(SkWStream* stream);
101
102    /** Get the size of the header.
103     */
104    size_t headerSize();
105
106    /** Output the PDF footer to the passed stream.
107     *  @param stream    The writable output stream to send the footer to.
108     *  @param objCount  The number of objects in the PDF.
109     */
110    void emitFooter(SkWStream* stream, int64_t objCount);
111};
112
113#endif
114