/src/skia/include/docs/SkPDFDocument.h
Line | Count | Source (jump to first uncovered line) |
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 | | #include "include/core/SkMilestone.h" |
8 | | #include "include/core/SkRefCnt.h" |
9 | | #include "include/core/SkScalar.h" |
10 | | #include "include/core/SkString.h" |
11 | | #include "include/private/base/SkAPI.h" |
12 | | #include "include/private/base/SkNoncopyable.h" |
13 | | |
14 | | #include <cstdint> |
15 | | #include <memory> |
16 | | #include <vector> |
17 | | |
18 | | class SkCanvas; |
19 | | class SkExecutor; |
20 | | class SkPDFArray; |
21 | | class SkPDFTagTree; |
22 | | class SkWStream; |
23 | | |
24 | | #define SKPDF_STRING(X) SKPDF_STRING_IMPL(X) |
25 | | #define SKPDF_STRING_IMPL(X) #X |
26 | | |
27 | | namespace SkPDF { |
28 | | |
29 | | /** Attributes for nodes in the PDF tree. */ |
30 | | class SK_API AttributeList : SkNoncopyable { |
31 | | public: |
32 | | AttributeList(); |
33 | | ~AttributeList(); |
34 | | |
35 | | // Each attribute must have an owner (e.g. "Layout", "List", "Table", etc) |
36 | | // and an attribute name (e.g. "BBox", "RowSpan", etc.) from PDF32000_2008 14.8.5, |
37 | | // and then a value of the proper type according to the spec. |
38 | | void appendInt(const char* owner, const char* name, int value); |
39 | | void appendFloat(const char* owner, const char* name, float value); |
40 | | void appendName(const char* owner, const char* attrName, const char* value); |
41 | | void appendFloatArray(const char* owner, |
42 | | const char* name, |
43 | | const std::vector<float>& value); |
44 | | void appendNodeIdArray(const char* owner, |
45 | | const char* attrName, |
46 | | const std::vector<int>& nodeIds); |
47 | | |
48 | | private: |
49 | | friend class ::SkPDFTagTree; |
50 | | |
51 | | std::unique_ptr<SkPDFArray> fAttrs; |
52 | | }; |
53 | | |
54 | | /** A node in a PDF structure tree, giving a semantic representation |
55 | | of the content. Each node ID is associated with content |
56 | | by passing the SkCanvas and node ID to SkPDF::SetNodeId() when drawing. |
57 | | NodeIDs should be unique within each tree. |
58 | | */ |
59 | | struct StructureElementNode { |
60 | | SkString fTypeString; |
61 | | std::vector<std::unique_ptr<StructureElementNode>> fChildVector; |
62 | | int fNodeId = 0; |
63 | | std::vector<int> fAdditionalNodeIds; |
64 | | AttributeList fAttributes; |
65 | | SkString fAlt; |
66 | | SkString fLang; |
67 | | }; |
68 | | |
69 | | struct DateTime { |
70 | | int16_t fTimeZoneMinutes; // The number of minutes that this |
71 | | // is ahead of or behind UTC. |
72 | | uint16_t fYear; //!< e.g. 2005 |
73 | | uint8_t fMonth; //!< 1..12 |
74 | | uint8_t fDayOfWeek; //!< 0..6, 0==Sunday |
75 | | uint8_t fDay; //!< 1..31 |
76 | | uint8_t fHour; //!< 0..23 |
77 | | uint8_t fMinute; //!< 0..59 |
78 | | uint8_t fSecond; //!< 0..59 |
79 | | |
80 | | void toISO8601(SkString* dst) const; |
81 | | }; |
82 | | |
83 | | /** Optional metadata to be passed into the PDF factory function. |
84 | | */ |
85 | | struct Metadata { |
86 | | /** The document's title. |
87 | | */ |
88 | | SkString fTitle; |
89 | | |
90 | | /** The name of the person who created the document. |
91 | | */ |
92 | | SkString fAuthor; |
93 | | |
94 | | /** The subject of the document. |
95 | | */ |
96 | | SkString fSubject; |
97 | | |
98 | | /** Keywords associated with the document. Commas may be used to delineate |
99 | | keywords within the string. |
100 | | */ |
101 | | SkString fKeywords; |
102 | | |
103 | | /** If the document was converted to PDF from another format, |
104 | | the name of the conforming product that created the |
105 | | original document from which it was converted. |
106 | | */ |
107 | | SkString fCreator; |
108 | | |
109 | | /** The product that is converting this document to PDF. |
110 | | */ |
111 | | SkString fProducer = SkString("Skia/PDF m" SKPDF_STRING(SK_MILESTONE)); |
112 | | |
113 | | /** The date and time the document was created. |
114 | | The zero default value represents an unknown/unset time. |
115 | | */ |
116 | | 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 | | DateTime fModified = {0, 0, 0, 0, 0, 0, 0, 0}; |
122 | | |
123 | | /** The natural language of the text in the PDF. If fLang is empty, the root |
124 | | StructureElementNode::fLang will be used (if not empty). Text not in |
125 | | this language should be marked with StructureElementNode::fLang. |
126 | | */ |
127 | | SkString fLang; |
128 | | |
129 | | /** The DPI (pixels-per-inch) at which features without native PDF support |
130 | | will be rasterized (e.g. draw image with perspective, draw text with |
131 | | perspective, ...) A larger DPI would create a PDF that reflects the |
132 | | original intent with better fidelity, but it can make for larger PDF |
133 | | files too, which would use more memory while rendering, and it would be |
134 | | slower to be processed or sent online or to printer. |
135 | | */ |
136 | | SkScalar fRasterDPI = SK_ScalarDefaultRasterDPI; |
137 | | |
138 | | /** If true, include XMP metadata, a document UUID, and sRGB output intent |
139 | | information. This adds length to the document and makes it |
140 | | non-reproducable, but are necessary features for PDF/A-2b conformance |
141 | | */ |
142 | | bool fPDFA = false; |
143 | | |
144 | | /** Encoding quality controls the trade-off between size and quality. By |
145 | | default this is set to 101 percent, which corresponds to lossless |
146 | | encoding. If this value is set to a value <= 100, and the image is |
147 | | opaque, it will be encoded (using JPEG) with that quality setting. |
148 | | */ |
149 | | int fEncodingQuality = 101; |
150 | | |
151 | | /** An optional tree of structured document tags that provide |
152 | | a semantic representation of the content. The caller |
153 | | should retain ownership. |
154 | | */ |
155 | | StructureElementNode* fStructureElementTreeRoot = nullptr; |
156 | | |
157 | | enum class Outline : int { |
158 | | None = 0, |
159 | | StructureElementHeaders = 1, |
160 | | } fOutline = Outline::None; |
161 | | |
162 | | /** Executor to handle threaded work within PDF Backend. If this is nullptr, |
163 | | then all work will be done serially on the main thread. To have worker |
164 | | threads assist with various tasks, set this to a valid SkExecutor |
165 | | instance. Currently used for executing Deflate algorithm in parallel. |
166 | | |
167 | | If set, the PDF output will be non-reproducible in the order and |
168 | | internal numbering of objects, but should render the same. |
169 | | |
170 | | Experimental. |
171 | | */ |
172 | | SkExecutor* fExecutor = nullptr; |
173 | | |
174 | | /** PDF streams may be compressed to save space. |
175 | | Use this to specify the desired compression vs time tradeoff. |
176 | | */ |
177 | | enum class CompressionLevel : int { |
178 | | Default = -1, |
179 | | None = 0, |
180 | | LowButFast = 1, |
181 | | Average = 6, |
182 | | HighButSlow = 9, |
183 | | } fCompressionLevel = CompressionLevel::Default; |
184 | | |
185 | | /** Preferred Subsetter. */ |
186 | | enum Subsetter { |
187 | | kHarfbuzz_Subsetter, |
188 | | } fSubsetter = kHarfbuzz_Subsetter; |
189 | | }; |
190 | | |
191 | | /** Associate a node ID with subsequent drawing commands in an |
192 | | SkCanvas. The same node ID can appear in a StructureElementNode |
193 | | in order to associate a document's structure element tree with |
194 | | its content. |
195 | | |
196 | | A node ID of zero indicates no node ID. |
197 | | |
198 | | @param canvas The canvas used to draw to the PDF. |
199 | | @param nodeId The node ID for subsequent drawing commands. |
200 | | */ |
201 | | SK_API void SetNodeId(SkCanvas* dst, int nodeID); |
202 | | |
203 | | /** Create a PDF-backed document, writing the results into a SkWStream. |
204 | | |
205 | | PDF pages are sized in point units. 1 pt == 1/72 inch == 127/360 mm. |
206 | | |
207 | | @param stream A PDF document will be written to this stream. The document may write |
208 | | to the stream at anytime during its lifetime, until either close() is |
209 | | called or the document is deleted. |
210 | | @param metadata a PDFmetadata object. Any fields may be left empty. |
211 | | |
212 | | @returns NULL if there is an error, otherwise a newly created PDF-backed SkDocument. |
213 | | */ |
214 | | SK_API sk_sp<SkDocument> MakeDocument(SkWStream* stream, const Metadata& metadata); |
215 | | |
216 | 0 | static inline sk_sp<SkDocument> MakeDocument(SkWStream* stream) { |
217 | 0 | return MakeDocument(stream, Metadata()); |
218 | 0 | } Unexecuted instantiation: FuzzCanvas.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFDocument.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFFont.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFMetadata.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFTag.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFType1Font.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFTypes.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFUtils.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFBitmap.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFDevice.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFGraphicState.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFShader.cpp:SkPDF::MakeDocument(SkWStream*) Unexecuted instantiation: SkPDFGradientShader.cpp:SkPDF::MakeDocument(SkWStream*) |
219 | | |
220 | | } // namespace SkPDF |
221 | | |
222 | | #undef SKPDF_STRING |
223 | | #undef SKPDF_STRING_IMPL |
224 | | #endif // SkPDFDocument_DEFINED |