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