• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkDocument_DEFINED
9 #define SkDocument_DEFINED
10 
11 #include "SkBitmap.h"
12 #include "SkPicture.h"
13 #include "SkRect.h"
14 #include "SkRefCnt.h"
15 #include "SkString.h"
16 #include "SkTime.h"
17 
18 class SkCanvas;
19 class SkWStream;
20 
21 #ifdef SK_BUILD_FOR_WIN
22 struct IXpsOMObjectFactory;
23 #endif
24 
25 /** SK_ScalarDefaultDPI is 72 DPI.
26 */
27 #define SK_ScalarDefaultRasterDPI           72.0f
28 
29 /**
30  *  High-level API for creating a document-based canvas. To use..
31  *
32  *  1. Create a document, specifying a stream to store the output.
33  *  2. For each "page" of content:
34  *      a. canvas = doc->beginPage(...)
35  *      b. draw_my_content(canvas);
36  *      c. doc->endPage();
37  *  3. Close the document with doc->close().
38  */
39 class SK_API SkDocument : public SkRefCnt {
40 public:
41     struct OptionalTimestamp {
42         SkTime::DateTime fDateTime;
43         bool fEnabled;
OptionalTimestampOptionalTimestamp44         OptionalTimestamp() : fEnabled(false) {}
45     };
46 
47     /**
48      *  Optional metadata to be passed into the PDF factory function.
49      */
50     struct PDFMetadata {
51         /**
52          * The document's title.
53          */
54         SkString fTitle;
55         /**
56          * The name of the person who created the document.
57          */
58         SkString fAuthor;
59         /**
60          * The subject of the document.
61          */
62         SkString fSubject;
63         /**
64          * Keywords associated with the document.  Commas may be used
65          * to delineate keywords within the string.
66          */
67         SkString fKeywords;
68         /**
69          * If the document was converted to PDF from another format,
70          * the name of the conforming product that created the
71          * original document from which it was converted.
72          */
73         SkString fCreator;
74         /**
75          * The product that is converting this document to PDF.
76          *
77          * Leave fProducer empty to get the default, correct value.
78          */
79         SkString fProducer;
80         /**
81          * The date and time the document was created.
82          */
83         OptionalTimestamp fCreation;
84         /**
85          * The date and time the document was most recently modified.
86          */
87         OptionalTimestamp fModified;
88 
89         /** The DPI (pixels-per-inch) at which features without
90          *  native PDF support will be rasterized (e.g. draw image
91          *  with perspective, draw text with perspective, ...)  A
92          *  larger DPI would create a PDF that reflects the
93          *  original intent with better fidelity, but it can make
94          *  for larger PDF files too, which would use more memory
95          *  while rendering, and it would be slower to be processed
96          *  or sent online or to printer.
97          */
98         SkScalar fRasterDPI = SK_ScalarDefaultRasterDPI;
99 
100         /** If true, include XMP metadata, a document UUID, and sRGB output intent information.
101          *  This adds length to the document and makes it non-reproducable, but are necessary
102          *  features for PDF/A-2b conformance
103          */
104         bool fPDFA = false;
105 
106         /**
107          *  Encoding quality controls the trade-off between size and quality. By default this is
108          *  set to 101 percent, which corresponds to lossless encoding. If this value is set to
109          *  a value <= 100, and the image is opaque, it will be encoded (using JPEG) with that
110          *  quality setting.
111          */
112         int fEncodingQuality = 101;
113     };
114 
115     /**
116      *  Create a PDF-backed document, writing the results into a
117      *  SkWStream.
118      *
119      *  PDF pages are sized in point units. 1 pt == 1/72 inch == 127/360 mm.
120      *
121      *  @param stream A PDF document will be written to this stream.  The document may write
122      *         to the stream at anytime during its lifetime, until either close() is
123      *         called or the document is deleted.
124      *  @param metadata a PDFmetadata object.  Any fields may be left empty.
125      *
126      *  @returns NULL if there is an error, otherwise a newly created PDF-backed SkDocument.
127      */
128     static sk_sp<SkDocument> MakePDF(SkWStream* stream, const PDFMetadata& metadata);
129     static sk_sp<SkDocument> MakePDF(SkWStream* stream);
130 
131 #ifdef SK_BUILD_FOR_WIN
132     /**
133      *  Create a XPS-backed document, writing the results into the stream.
134      *
135      *  @param stream A XPS document will be written to this stream.  The
136      *                document may write to the stream at anytime during its
137      *                lifetime, until either close() or abort() are called or
138      *                the document is deleted.
139      *  @param xpsFactory A pointer to a COM XPS factory.  Must be non-null.
140      *                    The document will take a ref to the factory. See
141      *                    dm/DMSrcSink.cpp for an example.
142      *  @param dpi The DPI (pixels-per-inch) at which features without
143      *             native XPS support will be rasterized (e.g. draw image
144      *             with perspective, draw text with perspective, ...)  A
145      *             larger DPI would create a XPS that reflects the
146      *             original intent with better fidelity, but it can make
147      *             for larger XPS files too, which would use more memory
148      *             while rendering, and it would be slower to be processed
149      *             or sent online or to printer.
150      *
151      *  @returns nullptr if XPS is not supported.
152      */
153     static sk_sp<SkDocument> MakeXPS(SkWStream* stream,
154                                      IXpsOMObjectFactory* xpsFactory,
155                                      SkScalar dpi = SK_ScalarDefaultRasterDPI);
156 #endif
157 
158     /**
159      *  Begin a new page for the document, returning the canvas that will draw
160      *  into the page. The document owns this canvas, and it will go out of
161      *  scope when endPage() or close() is called, or the document is deleted.
162      */
163     SkCanvas* beginPage(SkScalar width, SkScalar height, const SkRect* content = nullptr);
164 
165     /**
166      *  Call endPage() when the content for the current page has been drawn
167      *  (into the canvas returned by beginPage()). After this call the canvas
168      *  returned by beginPage() will be out-of-scope.
169      */
170     void endPage();
171 
172     /**
173      *  Call close() when all pages have been drawn. This will close the file
174      *  or stream holding the document's contents. After close() the document
175      *  can no longer add new pages. Deleting the document will automatically
176      *  call close() if need be.
177      */
178     void close();
179 
180     /**
181      *  Call abort() to stop producing the document immediately.
182      *  The stream output must be ignored, and should not be trusted.
183      */
184     void abort();
185 
186 protected:
187     SkDocument(SkWStream*);
188 
189     // note: subclasses must call close() in their destructor, as the base class
190     // cannot do this for them.
191     virtual ~SkDocument();
192 
193     virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height) = 0;
194     virtual void onEndPage() = 0;
195     virtual void onClose(SkWStream*) = 0;
196     virtual void onAbort() = 0;
197 
198     // Allows subclasses to write to the stream as pages are written.
getStream()199     SkWStream* getStream() { return fStream; }
200 
201     enum State {
202         kBetweenPages_State,
203         kInPage_State,
204         kClosed_State
205     };
getState()206     State getState() const { return fState; }
207 
208 private:
209     SkWStream* fStream;
210     State      fState;
211 
212     typedef SkRefCnt INHERITED;
213 };
214 
215 #endif
216