Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: src/doc/SkDocument_PDF.cpp

Issue 1775143002: Revert of SkPDF: Add sk_sp setters; .release() becomes std::move() (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/pdf/SkPDFBitmap.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkDocument.h" 8 #include "SkDocument.h"
9 #include "SkPDFCanon.h" 9 #include "SkPDFCanon.h"
10 #include "SkPDFDevice.h" 10 #include "SkPDFDevice.h"
(...skipping 13 matching lines...) Expand all
24 stream->write32(0xD3EBE9E1); 24 stream->write32(0xD3EBE9E1);
25 stream->writeText("\n"); 25 stream->writeText("\n");
26 } 26 }
27 27
28 static void emit_pdf_footer(SkWStream* stream, 28 static void emit_pdf_footer(SkWStream* stream,
29 const SkPDFObjNumMap& objNumMap, 29 const SkPDFObjNumMap& objNumMap,
30 const SkPDFSubstituteMap& substitutes, 30 const SkPDFSubstituteMap& substitutes,
31 SkPDFObject* docCatalog, 31 SkPDFObject* docCatalog,
32 int64_t objCount, 32 int64_t objCount,
33 int32_t xRefFileOffset, 33 int32_t xRefFileOffset,
34 sk_sp<SkPDFObject> info, 34 SkPDFObject* info /* take ownership */,
35 sk_sp<SkPDFObject> id) { 35 SkPDFObject* id /* take ownership */) {
36 SkPDFDict trailerDict; 36 SkPDFDict trailerDict;
37 // TODO(http://crbug.com/80908): Linearized format will take a 37 // TODO(http://crbug.com/80908): Linearized format will take a
38 // Prev entry too. 38 // Prev entry too.
39 trailerDict.insertInt("Size", int(objCount)); 39 trailerDict.insertInt("Size", int(objCount));
40 trailerDict.insertObjRef("Root", sk_sp<SkPDFObject>(SkRef(docCatalog))); 40 trailerDict.insertObjRef("Root", SkRef(docCatalog));
41 SkASSERT(info); 41 SkASSERT(info);
42 trailerDict.insertObjRef("Info", std::move(info)); 42 trailerDict.insertObjRef("Info", info);
43 if (id) { 43 if (id) {
44 trailerDict.insertObject("ID", std::move(id)); 44 trailerDict.insertObject("ID", id);
45 } 45 }
46 stream->writeText("trailer\n"); 46 stream->writeText("trailer\n");
47 trailerDict.emitObject(stream, objNumMap, substitutes); 47 trailerDict.emitObject(stream, objNumMap, substitutes);
48 stream->writeText("\nstartxref\n"); 48 stream->writeText("\nstartxref\n");
49 stream->writeBigDecAsText(xRefFileOffset); 49 stream->writeBigDecAsText(xRefFileOffset);
50 stream->writeText("\n%%EOF"); 50 stream->writeText("\n%%EOF");
51 } 51 }
52 52
53 static void perform_font_subsetting( 53 static void perform_font_subsetting(
54 const SkTArray<sk_sp<const SkPDFDevice>>& pageDevices, 54 const SkTDArray<const SkPDFDevice*>& pageDevices,
55 SkPDFSubstituteMap* substituteMap) { 55 SkPDFSubstituteMap* substituteMap) {
56 SkASSERT(substituteMap); 56 SkASSERT(substituteMap);
57 57
58 SkPDFGlyphSetMap usage; 58 SkPDFGlyphSetMap usage;
59 for (const sk_sp<const SkPDFDevice>& pageDevice : pageDevices) { 59 for (int i = 0; i < pageDevices.count(); ++i) {
60 usage.merge(pageDevice->getFontGlyphUsage()); 60 usage.merge(pageDevices[i]->getFontGlyphUsage());
61 } 61 }
62 SkPDFGlyphSetMap::F2BIter iterator(usage); 62 SkPDFGlyphSetMap::F2BIter iterator(usage);
63 const SkPDFGlyphSetMap::FontGlyphSetPair* entry = iterator.next(); 63 const SkPDFGlyphSetMap::FontGlyphSetPair* entry = iterator.next();
64 while (entry) { 64 while (entry) {
65 sk_sp<SkPDFFont> subsetFont( 65 sk_sp<SkPDFFont> subsetFont(
66 entry->fFont->getFontSubset(entry->fGlyphSet)); 66 entry->fFont->getFontSubset(entry->fGlyphSet));
67 if (subsetFont) { 67 if (subsetFont) {
68 substituteMap->setSubstitute(entry->fFont, subsetFont.get()); 68 substituteMap->setSubstitute(entry->fFont, subsetFont.get());
69 } 69 }
70 entry = iterator.next(); 70 entry = iterator.next();
71 } 71 }
72 } 72 }
73 73
74 static sk_sp<SkPDFDict> create_pdf_page(const SkPDFDevice* pageDevice) { 74 static SkPDFObject* create_pdf_page_content(const SkPDFDevice* pageDevice) {
75 SkAutoTDelete<SkStreamAsset> content(pageDevice->content());
76 return new SkPDFStream(content.get());
77 }
78
79 static SkPDFDict* create_pdf_page(const SkPDFDevice* pageDevice) {
75 auto page = sk_make_sp<SkPDFDict>("Page"); 80 auto page = sk_make_sp<SkPDFDict>("Page");
76 page->insertObject("Resources", pageDevice->makeResourceDict()); 81 page->insertObject("Resources", pageDevice->createResourceDict());
77 page->insertObject("MediaBox", pageDevice->copyMediaBox()); 82 page->insertObject("MediaBox", pageDevice->copyMediaBox());
78 auto annotations = sk_make_sp<SkPDFArray>(); 83 auto annotations = sk_make_sp<SkPDFArray>();
79 pageDevice->appendAnnotations(annotations.get()); 84 pageDevice->appendAnnotations(annotations.get());
80 if (annotations->size() > 0) { 85 if (annotations->size() > 0) {
81 page->insertObject("Annots", std::move(annotations)); 86 page->insertObject("Annots", annotations.release());
82 } 87 }
83 auto content = pageDevice->content(); 88 page->insertObjRef("Contents", create_pdf_page_content(pageDevice));
84 page->insertObjRef("Contents", sk_make_sp<SkPDFStream>(content.get())); 89 return page.release();
85 return std::move(page);
86 } 90 }
87 91
88 // return root node. 92 static void generate_page_tree(const SkTDArray<SkPDFDict*>& pages,
89 static sk_sp<SkPDFDict> generate_page_tree( 93 SkTDArray<SkPDFDict*>* pageTree,
90 const SkTDArray<SkPDFDict*>& pages, 94 SkPDFDict** rootNode) {
91 SkTDArray<SkPDFDict*>* pageTree) {
92 // PDF wants a tree describing all the pages in the document. We arbitrary 95 // PDF wants a tree describing all the pages in the document. We arbitrary
93 // choose 8 (kNodeSize) as the number of allowed children. The internal 96 // choose 8 (kNodeSize) as the number of allowed children. The internal
94 // nodes have type "Pages" with an array of children, a parent pointer, and 97 // nodes have type "Pages" with an array of children, a parent pointer, and
95 // the number of leaves below the node as "Count." The leaves are passed 98 // the number of leaves below the node as "Count." The leaves are passed
96 // into the method, have type "Page" and need a parent pointer. This method 99 // into the method, have type "Page" and need a parent pointer. This method
97 // builds the tree bottom up, skipping internal nodes that would have only 100 // builds the tree bottom up, skipping internal nodes that would have only
98 // one child. 101 // one child.
99 static const int kNodeSize = 8; 102 static const int kNodeSize = 8;
100 103
101 // curNodes takes a reference to its items, which it passes to pageTree. 104 // curNodes takes a reference to its items, which it passes to pageTree.
(...skipping 15 matching lines...) Expand all
117 nextRoundNodes.push(curNodes[i]); 120 nextRoundNodes.push(curNodes[i]);
118 break; 121 break;
119 } 122 }
120 123
121 auto newNode = sk_make_sp<SkPDFDict>("Pages"); 124 auto newNode = sk_make_sp<SkPDFDict>("Pages");
122 auto kids = sk_make_sp<SkPDFArray>(); 125 auto kids = sk_make_sp<SkPDFArray>();
123 kids->reserve(kNodeSize); 126 kids->reserve(kNodeSize);
124 127
125 int count = 0; 128 int count = 0;
126 for (; i < curNodes.count() && count < kNodeSize; i++, count++) { 129 for (; i < curNodes.count() && count < kNodeSize; i++, count++) {
127 curNodes[i]->insertObjRef("Parent", newNode); 130 curNodes[i]->insertObjRef("Parent", SkRef(newNode.get()));
128 kids->appendObjRef(sk_sp<SkPDFDict>(SkRef(curNodes[i]))); 131 kids->appendObjRef(SkRef(curNodes[i]));
129 132
130 // TODO(vandebo): put the objects in strict access order. 133 // TODO(vandebo): put the objects in strict access order.
131 // Probably doesn't matter because they are so small. 134 // Probably doesn't matter because they are so small.
132 if (curNodes[i] != pages[0]) { 135 if (curNodes[i] != pages[0]) {
133 pageTree->push(curNodes[i]); // Transfer reference. 136 pageTree->push(curNodes[i]); // Transfer reference.
134 } else { 137 } else {
135 SkSafeUnref(curNodes[i]); 138 SkSafeUnref(curNodes[i]);
136 } 139 }
137 } 140 }
138 141
139 // treeCapacity is the number of leaf nodes possible for the 142 // treeCapacity is the number of leaf nodes possible for the
140 // current set of subtrees being generated. (i.e. 8, 64, 512, ...). 143 // current set of subtrees being generated. (i.e. 8, 64, 512, ...).
141 // It is hard to count the number of leaf nodes in the current 144 // It is hard to count the number of leaf nodes in the current
142 // subtree. However, by construction, we know that unless it's the 145 // subtree. However, by construction, we know that unless it's the
143 // last subtree for the current depth, the leaf count will be 146 // last subtree for the current depth, the leaf count will be
144 // treeCapacity, otherwise it's what ever is left over after 147 // treeCapacity, otherwise it's what ever is left over after
145 // consuming treeCapacity chunks. 148 // consuming treeCapacity chunks.
146 int pageCount = treeCapacity; 149 int pageCount = treeCapacity;
147 if (i == curNodes.count()) { 150 if (i == curNodes.count()) {
148 pageCount = ((pages.count() - 1) % treeCapacity) + 1; 151 pageCount = ((pages.count() - 1) % treeCapacity) + 1;
149 } 152 }
150 newNode->insertInt("Count", pageCount); 153 newNode->insertInt("Count", pageCount);
151 newNode->insertObject("Kids", std::move(kids)); 154 newNode->insertObject("Kids", kids.release());
152 nextRoundNodes.push(newNode.release()); // Transfer reference. 155 nextRoundNodes.push(newNode.release()); // Transfer reference.
153 } 156 }
154 157
155 curNodes = nextRoundNodes; 158 curNodes = nextRoundNodes;
156 nextRoundNodes.rewind(); 159 nextRoundNodes.rewind();
157 treeCapacity *= kNodeSize; 160 treeCapacity *= kNodeSize;
158 } while (curNodes.count() > 1); 161 } while (curNodes.count() > 1);
159 162
160 pageTree->push(curNodes[0]); // Transfer reference. 163 pageTree->push(curNodes[0]); // Transfer reference.
161 return sk_sp<SkPDFDict>(SkRef(curNodes[0])); 164 if (rootNode) {
165 *rootNode = curNodes[0];
166 }
162 } 167 }
163 168
164 static bool emit_pdf_document(const SkTArray<sk_sp<const SkPDFDevice>>& pageDevi ces, 169 static bool emit_pdf_document(const SkTDArray<const SkPDFDevice*>& pageDevices,
165 const SkPDFMetadata& metadata, 170 const SkPDFMetadata& metadata,
166 SkWStream* stream) { 171 SkWStream* stream) {
167 if (pageDevices.empty()) { 172 if (pageDevices.isEmpty()) {
168 return false; 173 return false;
169 } 174 }
170 175
171 SkTDArray<SkPDFDict*> pages; // TODO: SkTArray<sk_sp<SkPDFDict>> 176 SkTDArray<SkPDFDict*> pages;
172 auto dests = sk_make_sp<SkPDFDict>(); 177 auto dests = sk_make_sp<SkPDFDict>();
173 178
174 for (const sk_sp<const SkPDFDevice>& pageDevice : pageDevices) { 179 for (int i = 0; i < pageDevices.count(); i++) {
175 SkASSERT(pageDevice); 180 SkASSERT(pageDevices[i]);
176 SkASSERT(pageDevices[0]->getCanon() == pageDevice->getCanon()); 181 SkASSERT(i == 0 ||
177 sk_sp<SkPDFDict> page(create_pdf_page(pageDevice.get())); 182 pageDevices[i - 1]->getCanon() == pageDevices[i]->getCanon());
178 pageDevice->appendDestinations(dests.get(), page.get()); 183 sk_sp<SkPDFDict> page(create_pdf_page(pageDevices[i]));
184 pageDevices[i]->appendDestinations(dests.get(), page.get());
179 pages.push(page.release()); 185 pages.push(page.release());
180 } 186 }
181 187
182 auto docCatalog = sk_make_sp<SkPDFDict>("Catalog"); 188 auto docCatalog = sk_make_sp<SkPDFDict>("Catalog");
183 189
184 sk_sp<SkPDFObject> infoDict(metadata.createDocumentInformationDict()); 190 sk_sp<SkPDFObject> infoDict(
191 metadata.createDocumentInformationDict());
185 192
186 sk_sp<SkPDFObject> id, xmp; 193 sk_sp<SkPDFObject> id, xmp;
187 #ifdef SK_PDF_GENERATE_PDFA 194 #ifdef SK_PDF_GENERATE_PDFA
188 SkPDFMetadata::UUID uuid = metadata.uuid(); 195 SkPDFMetadata::UUID uuid = metadata.uuid();
189 // We use the same UUID for Document ID and Instance ID since this 196 // We use the same UUID for Document ID and Instance ID since this
190 // is the first revision of this document (and Skia does not 197 // is the first revision of this document (and Skia does not
191 // support revising existing PDF documents). 198 // support revising existing PDF documents).
192 // If we are not in PDF/A mode, don't use a UUID since testing 199 // If we are not in PDF/A mode, don't use a UUID since testing
193 // works best with reproducible outputs. 200 // works best with reproducible outputs.
194 id.reset(SkPDFMetadata::CreatePdfId(uuid, uuid)); 201 id.reset(SkPDFMetadata::CreatePdfId(uuid, uuid));
195 xmp.reset(metadata.createXMPObject(uuid, uuid)); 202 xmp.reset(metadata.createXMPObject(uuid, uuid));
196 docCatalog->insertObjRef("Metadata", std::move(xmp)); 203 docCatalog->insertObjRef("Metadata", xmp.release());
197 204
198 // sRGB is specified by HTML, CSS, and SVG. 205 // sRGB is specified by HTML, CSS, and SVG.
199 auto outputIntent = sk_make_sp<SkPDFDict>("OutputIntent"); 206 auto outputIntent = sk_make_sp<SkPDFDict>("OutputIntent");
200 outputIntent->insertName("S", "GTS_PDFA1"); 207 outputIntent->insertName("S", "GTS_PDFA1");
201 outputIntent->insertString("RegistryName", "http://www.color.org"); 208 outputIntent->insertString("RegistryName", "http://www.color.org");
202 outputIntent->insertString("OutputConditionIdentifier", 209 outputIntent->insertString("OutputConditionIdentifier",
203 "sRGB IEC61966-2.1"); 210 "sRGB IEC61966-2.1");
204 auto intentArray = sk_make_sp<SkPDFArray>(); 211 auto intentArray = sk_make_sp<SkPDFArray>();
205 intentArray->appendObject(std::move(outputIntent)); 212 intentArray->appendObject(outputIntent.release());
206 // Don't specify OutputIntents if we are not in PDF/A mode since 213 // Don't specify OutputIntents if we are not in PDF/A mode since
207 // no one has ever asked for this feature. 214 // no one has ever asked for this feature.
208 docCatalog->insertObject("OutputIntents", std::move(intentArray)); 215 docCatalog->insertObject("OutputIntents", intentArray.release());
209 #endif 216 #endif
210 217
211 SkTDArray<SkPDFDict*> pageTree; 218 SkTDArray<SkPDFDict*> pageTree;
212 docCatalog->insertObjRef("Pages", generate_page_tree(pages, &pageTree)); 219 SkPDFDict* pageTreeRoot;
220 generate_page_tree(pages, &pageTree, &pageTreeRoot);
221 docCatalog->insertObjRef("Pages", SkRef(pageTreeRoot));
213 222
214 if (dests->size() > 0) { 223 if (dests->size() > 0) {
215 docCatalog->insertObjRef("Dests", std::move(dests)); 224 docCatalog->insertObjRef("Dests", dests.release());
216 } 225 }
217 226
218 // Build font subsetting info before proceeding. 227 // Build font subsetting info before proceeding.
219 SkPDFSubstituteMap substitutes; 228 SkPDFSubstituteMap substitutes;
220 perform_font_subsetting(pageDevices, &substitutes); 229 perform_font_subsetting(pageDevices, &substitutes);
221 230
222 SkPDFObjNumMap objNumMap; 231 SkPDFObjNumMap objNumMap;
223 objNumMap.addObjectRecursively(infoDict.get(), substitutes); 232 objNumMap.addObjectRecursively(infoDict.get(), substitutes);
224 objNumMap.addObjectRecursively(docCatalog.get(), substitutes); 233 objNumMap.addObjectRecursively(docCatalog.get(), substitutes);
225 size_t baseOffset = stream->bytesWritten(); 234 size_t baseOffset = stream->bytesWritten();
(...skipping 20 matching lines...) Expand all
246 255
247 stream->writeText("xref\n0 "); 256 stream->writeText("xref\n0 ");
248 stream->writeDecAsText(objCount); 257 stream->writeDecAsText(objCount);
249 stream->writeText("\n0000000000 65535 f \n"); 258 stream->writeText("\n0000000000 65535 f \n");
250 for (int i = 0; i < offsets.count(); i++) { 259 for (int i = 0; i < offsets.count(); i++) {
251 SkASSERT(offsets[i] > 0); 260 SkASSERT(offsets[i] > 0);
252 stream->writeBigDecAsText(offsets[i], 10); 261 stream->writeBigDecAsText(offsets[i], 10);
253 stream->writeText(" 00000 n \n"); 262 stream->writeText(" 00000 n \n");
254 } 263 }
255 emit_pdf_footer(stream, objNumMap, substitutes, docCatalog.get(), objCount, 264 emit_pdf_footer(stream, objNumMap, substitutes, docCatalog.get(), objCount,
256 xRefFileOffset, std::move(infoDict), std::move(id)); 265 xRefFileOffset, infoDict.release(), id.release());
257 266
258 // The page tree has both child and parent pointers, so it creates a 267 // The page tree has both child and parent pointers, so it creates a
259 // reference cycle. We must clear that cycle to properly reclaim memory. 268 // reference cycle. We must clear that cycle to properly reclaim memory.
260 for (int i = 0; i < pageTree.count(); i++) { 269 for (int i = 0; i < pageTree.count(); i++) {
261 pageTree[i]->clear(); 270 pageTree[i]->clear();
262 } 271 }
263 pageTree.safeUnrefAll(); 272 pageTree.safeUnrefAll();
264 pages.unrefAll(); 273 pages.unrefAll();
265 return true; 274 return true;
266 } 275 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 protected: 337 protected:
329 SkCanvas* onBeginPage(SkScalar width, SkScalar height, 338 SkCanvas* onBeginPage(SkScalar width, SkScalar height,
330 const SkRect& trimBox) override { 339 const SkRect& trimBox) override {
331 SkASSERT(!fCanvas.get()); 340 SkASSERT(!fCanvas.get());
332 341
333 SkISize pageSize = SkISize::Make( 342 SkISize pageSize = SkISize::Make(
334 SkScalarRoundToInt(width), SkScalarRoundToInt(height)); 343 SkScalarRoundToInt(width), SkScalarRoundToInt(height));
335 sk_sp<SkPDFDevice> device( 344 sk_sp<SkPDFDevice> device(
336 SkPDFDevice::Create(pageSize, fRasterDpi, &fCanon)); 345 SkPDFDevice::Create(pageSize, fRasterDpi, &fCanon));
337 fCanvas.reset(new SkCanvas(device.get())); 346 fCanvas.reset(new SkCanvas(device.get()));
338 fPageDevices.push_back(std::move(device)); 347 fPageDevices.push(device.release());
339 fCanvas->clipRect(trimBox); 348 fCanvas->clipRect(trimBox);
340 fCanvas->translate(trimBox.x(), trimBox.y()); 349 fCanvas->translate(trimBox.x(), trimBox.y());
341 return fCanvas.get(); 350 return fCanvas.get();
342 } 351 }
343 352
344 void onEndPage() override { 353 void onEndPage() override {
345 SkASSERT(fCanvas.get()); 354 SkASSERT(fCanvas.get());
346 fCanvas->flush(); 355 fCanvas->flush();
347 fCanvas.reset(nullptr); 356 fCanvas.reset(nullptr);
348 } 357 }
349 358
350 bool onClose(SkWStream* stream) override { 359 bool onClose(SkWStream* stream) override {
351 SkASSERT(!fCanvas.get()); 360 SkASSERT(!fCanvas.get());
352 361
353 bool success = emit_pdf_document(fPageDevices, fMetadata, stream); 362 bool success = emit_pdf_document(fPageDevices, fMetadata, stream);
354 fPageDevices.reset(); 363 fPageDevices.unrefAll();
355 fCanon.reset(); 364 fCanon.reset();
356 return success; 365 return success;
357 } 366 }
358 367
359 void onAbort() override { 368 void onAbort() override {
360 fPageDevices.reset(); 369 fPageDevices.unrefAll();
361 fCanon.reset(); 370 fCanon.reset();
362 } 371 }
363 372
364 void setMetadata(const SkDocument::Attribute info[], 373 void setMetadata(const SkDocument::Attribute info[],
365 int infoCount, 374 int infoCount,
366 const SkTime::DateTime* creationDate, 375 const SkTime::DateTime* creationDate,
367 const SkTime::DateTime* modifiedDate) override { 376 const SkTime::DateTime* modifiedDate) override {
368 fMetadata.fInfo.reset(info, infoCount); 377 fMetadata.fInfo.reset(info, infoCount);
369 fMetadata.fCreation.reset(clone(creationDate)); 378 fMetadata.fCreation.reset(clone(creationDate));
370 fMetadata.fModified.reset(clone(modifiedDate)); 379 fMetadata.fModified.reset(clone(modifiedDate));
371 } 380 }
372 381
373 private: 382 private:
374 SkPDFCanon fCanon; 383 SkPDFCanon fCanon;
375 SkTArray<sk_sp<const SkPDFDevice>> fPageDevices; 384 SkTDArray<const SkPDFDevice*> fPageDevices;
376 sk_sp<SkCanvas> fCanvas; 385 sk_sp<SkCanvas> fCanvas;
377 SkScalar fRasterDpi; 386 SkScalar fRasterDpi;
378 SkPDFMetadata fMetadata; 387 SkPDFMetadata fMetadata;
379 }; 388 };
380 } // namespace 389 } // namespace
381 /////////////////////////////////////////////////////////////////////////////// 390 ///////////////////////////////////////////////////////////////////////////////
382 391
383 SkDocument* SkDocument::CreatePDF(SkWStream* stream, SkScalar dpi) { 392 SkDocument* SkDocument::CreatePDF(SkWStream* stream, SkScalar dpi) {
384 return stream ? new SkDocument_PDF(stream, nullptr, dpi, nullptr) : nullptr; 393 return stream ? new SkDocument_PDF(stream, nullptr, dpi, nullptr) : nullptr;
385 } 394 }
386 395
387 SkDocument* SkDocument::CreatePDF(SkWStream* stream, 396 SkDocument* SkDocument::CreatePDF(SkWStream* stream,
388 SkScalar dpi, 397 SkScalar dpi,
389 SkPixelSerializer* jpegEncoder) { 398 SkPixelSerializer* jpegEncoder) {
390 return stream 399 return stream
391 ? new SkDocument_PDF(stream, nullptr, dpi, jpegEncoder) 400 ? new SkDocument_PDF(stream, nullptr, dpi, jpegEncoder)
392 : nullptr; 401 : nullptr;
393 } 402 }
394 403
395 SkDocument* SkDocument::CreatePDF(const char path[], SkScalar dpi) { 404 SkDocument* SkDocument::CreatePDF(const char path[], SkScalar dpi) {
396 SkFILEWStream* stream = new SkFILEWStream(path); 405 SkFILEWStream* stream = new SkFILEWStream(path);
397 if (!stream->isValid()) { 406 if (!stream->isValid()) {
398 delete stream; 407 delete stream;
399 return nullptr; 408 return nullptr;
400 } 409 }
401 auto delete_wstream = [](SkWStream* stream, bool) { delete stream; }; 410 auto delete_wstream = [](SkWStream* stream, bool) { delete stream; };
402 return new SkDocument_PDF(stream, delete_wstream, dpi, nullptr); 411 return new SkDocument_PDF(stream, delete_wstream, dpi, nullptr);
403 } 412 }
OLDNEW
« no previous file with comments | « no previous file | src/pdf/SkPDFBitmap.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698