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