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