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