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