1 // Copyright 2018 Google LLC.
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3 #ifndef SkPDFDocument_DEFINED
4 #define SkPDFDocument_DEFINED
5
6 #include "include/core/SkDocument.h"
7
8 #include "include/core/SkScalar.h"
9 #include "include/core/SkString.h"
10 #include "include/core/SkTime.h"
11
12 class SkExecutor;
13
14 namespace SkPDF {
15
16 /** Table 333 in PDF 32000-1:2008 §14.8.4.2
17 */
18 enum class DocumentStructureType {
19 kDocument, //!< Document
20 kPart, //!< Part
21 kArt, //!< Article
22 kSect, //!< Section
23 kDiv, //!< Division
24 kBlockQuote, //!< Block quotation
25 kCaption, //!< Caption
26 kTOC, //!< Table of Contents
27 kTOCI, //!< Table of Contents Item
28 kIndex, //!< Index
29 kNonStruct, //!< Nonstructural element
30 kPrivate, //!< Private element
31 kH, //!< Heading
32 kH1, //!< Heading level 1
33 kH2, //!< Heading level 2
34 kH3, //!< Heading level 3
35 kH4, //!< Heading level 4
36 kH5, //!< Heading level 5
37 kH6, //!< Heading level 6
38 kP, //!< Paragraph
39 kL, //!< List
40 kLI, //!< List item
41 kLbl, //!< List item label
42 kLBody, //!< List item body
43 kTable, //!< Table
44 kTR, //!< Table row
45 kTH, //!< Table header cell
46 kTD, //!< Table data cell
47 kTHead, //!< Table header row group
48 kTBody, //!< Table body row group
49 kTFoot, //!< table footer row group
50 kSpan, //!< Span
51 kQuote, //!< Quotation
52 kNote, //!< Note
53 kReference, //!< Reference
54 kBibEntry, //!< Bibliography entry
55 kCode, //!< Code
56 kLink, //!< Link
57 kAnnot, //!< Annotation
58 kRuby, //!< Ruby annotation
59 kRB, //!< Ruby base text
60 kRT, //!< Ruby annotation text
61 kRP, //!< Ruby punctuation
62 kWarichu, //!< Warichu annotation
63 kWT, //!< Warichu text
64 kWP, //!< Warichu punctuation
65 kFigure, //!< Figure
66 kFormula, //!< Formula
67 kForm, //!< Form control (not like an HTML FORM element)
68 };
69
70 /** A node in a PDF structure tree, giving a semantic representation
71 of the content. Each node ID is associated with content
72 by passing the SkCanvas and node ID to SkPDF::SetNodeId() when drawing.
73 NodeIDs should be unique within each tree.
74 */
75 struct StructureElementNode {
76 const StructureElementNode* fChildren = nullptr;
77 size_t fChildCount;
78 int fNodeId;
79 DocumentStructureType fType;
80 };
81
82 /** Optional metadata to be passed into the PDF factory function.
83 */
84 struct Metadata {
85 /** The document's title.
86 */
87 SkString fTitle;
88
89 /** The name of the person who created the document.
90 */
91 SkString fAuthor;
92
93 /** The subject of the document.
94 */
95 SkString fSubject;
96
97 /** Keywords associated with the document. Commas may be used to delineate
98 keywords within the string.
99 */
100 SkString fKeywords;
101
102 /** If the document was converted to PDF from another format,
103 the name of the conforming product that created the
104 original document from which it was converted.
105 */
106 SkString fCreator;
107
108 /** The product that is converting this document to PDF.
109 Leave fProducer empty to get the default, correct value.
110 */
111 SkString fProducer;
112
113 /** The date and time the document was created.
114 The zero default value represents an unknown/unset time.
115 */
116 SkTime::DateTime fCreation = {0, 0, 0, 0, 0, 0, 0, 0};
117
118 /** The date and time the document was most recently modified.
119 The zero default value represents an unknown/unset time.
120 */
121 SkTime::DateTime fModified = {0, 0, 0, 0, 0, 0, 0, 0};
122
123 /** The DPI (pixels-per-inch) at which features without native PDF support
124 will be rasterized (e.g. draw image with perspective, draw text with
125 perspective, ...) A larger DPI would create a PDF that reflects the
126 original intent with better fidelity, but it can make for larger PDF
127 files too, which would use more memory while rendering, and it would be
128 slower to be processed or sent online or to printer.
129 */
130 SkScalar fRasterDPI = SK_ScalarDefaultRasterDPI;
131
132 /** If true, include XMP metadata, a document UUID, and sRGB output intent
133 information. This adds length to the document and makes it
134 non-reproducable, but are necessary features for PDF/A-2b conformance
135 */
136 bool fPDFA = false;
137
138 /** Encoding quality controls the trade-off between size and quality. By
139 default this is set to 101 percent, which corresponds to lossless
140 encoding. If this value is set to a value <= 100, and the image is
141 opaque, it will be encoded (using JPEG) with that quality setting.
142 */
143 int fEncodingQuality = 101;
144
145 /** An optional tree of structured document tags that provide
146 a semantic representation of the content. The caller
147 should retain ownership.
148 */
149 const StructureElementNode* fStructureElementTreeRoot = nullptr;
150
151 /** Executor to handle threaded work within PDF Backend. If this is nullptr,
152 then all work will be done serially on the main thread. To have worker
153 threads assist with various tasks, set this to a valid SkExecutor
154 instance. Currently used for executing Deflate algorithm in parallel.
155
156 If set, the PDF output will be non-reproducible in the order and
157 internal numbering of objects, but should render the same.
158
159 Experimental.
160 */
161 SkExecutor* fExecutor = nullptr;
162
163 /** Preferred Subsetter. Only respected if both are compiled in.
164 Experimental.
165 */
166 enum Subsetter {
167 kHarfbuzz_Subsetter,
168 kSfntly_Subsetter,
169 } fSubsetter = kHarfbuzz_Subsetter;
170 };
171
172 /** Associate a node ID with subsequent drawing commands in an
173 SkCanvas. The same node ID can appear in a StructureElementNode
174 in order to associate a document's structure element tree with
175 its content.
176
177 A node ID of zero indicates no node ID.
178
179 @param canvas The canvas used to draw to the PDF.
180 @param nodeId The node ID for subsequent drawing commands.
181 */
182 SK_API void SetNodeId(SkCanvas* dst, int nodeID);
183
184 /** Create a PDF-backed document, writing the results into a SkWStream.
185
186 PDF pages are sized in point units. 1 pt == 1/72 inch == 127/360 mm.
187
188 @param stream A PDF document will be written to this stream. The document may write
189 to the stream at anytime during its lifetime, until either close() is
190 called or the document is deleted.
191 @param metadata a PDFmetadata object. Any fields may be left empty.
192
193 @returns NULL if there is an error, otherwise a newly created PDF-backed SkDocument.
194 */
195 SK_API sk_sp<SkDocument> MakeDocument(SkWStream* stream, const Metadata& metadata);
196
MakeDocument(SkWStream * stream)197 static inline sk_sp<SkDocument> MakeDocument(SkWStream* stream) {
198 return MakeDocument(stream, Metadata());
199 }
200
201 } // namespace SkPDF
202 #endif // SkPDFDocument_DEFINED
203