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

Side by Side Diff: src/pdf/SkPDFDocument.cpp

Issue 1916093002: SkDocument/PDF: new API (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2016-04-26 (Tuesday) 15:55:33 EDT Created 4 years, 8 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 | « src/pdf/SkPDFDocument.h ('k') | src/pdf/SkPDFMetadata.h » ('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 "SkPDFCanon.h" 8 #include "SkPDFCanon.h"
9 #include "SkPDFCanvas.h" 9 #include "SkPDFCanvas.h"
10 #include "SkPDFDevice.h" 10 #include "SkPDFDevice.h"
(...skipping 17 matching lines...) Expand all
28 fObjNumMap.addObjectRecursively(object.get(), fSubstituteMap); 28 fObjNumMap.addObjectRecursively(object.get(), fSubstituteMap);
29 } 29 }
30 30
31 #define SKPDF_MAGIC "\xD3\xEB\xE9\xE1" 31 #define SKPDF_MAGIC "\xD3\xEB\xE9\xE1"
32 #ifndef SK_BUILD_FOR_WIN32 32 #ifndef SK_BUILD_FOR_WIN32
33 static_assert((SKPDF_MAGIC[0] & 0x7F) == "Skia"[0], ""); 33 static_assert((SKPDF_MAGIC[0] & 0x7F) == "Skia"[0], "");
34 static_assert((SKPDF_MAGIC[1] & 0x7F) == "Skia"[1], ""); 34 static_assert((SKPDF_MAGIC[1] & 0x7F) == "Skia"[1], "");
35 static_assert((SKPDF_MAGIC[2] & 0x7F) == "Skia"[2], ""); 35 static_assert((SKPDF_MAGIC[2] & 0x7F) == "Skia"[2], "");
36 static_assert((SKPDF_MAGIC[3] & 0x7F) == "Skia"[3], ""); 36 static_assert((SKPDF_MAGIC[3] & 0x7F) == "Skia"[3], "");
37 #endif 37 #endif
38 void SkPDFObjectSerializer::serializeHeader(SkWStream* wStream, const SkPDFMetad ata& md) { 38 void SkPDFObjectSerializer::serializeHeader(SkWStream* wStream,
39 const SkDocument::PDFMetadata& md) {
39 fBaseOffset = wStream->bytesWritten(); 40 fBaseOffset = wStream->bytesWritten();
40 static const char kHeader[] = "%PDF-1.4\n%" SKPDF_MAGIC "\n"; 41 static const char kHeader[] = "%PDF-1.4\n%" SKPDF_MAGIC "\n";
41 wStream->write(kHeader, strlen(kHeader)); 42 wStream->write(kHeader, strlen(kHeader));
42 // The PDF spec recommends including a comment with four 43 // The PDF spec recommends including a comment with four
43 // bytes, all with their high bits set. "\xD3\xEB\xE9\xE1" is 44 // bytes, all with their high bits set. "\xD3\xEB\xE9\xE1" is
44 // "Skia" with the high bits set. 45 // "Skia" with the high bits set.
45 fInfoDict.reset(md.createDocumentInformationDict()); 46 fInfoDict = SkPDFMetadata::MakeDocumentInformationDict(md);
46 this->addObjectRecursively(fInfoDict); 47 this->addObjectRecursively(fInfoDict);
47 this->serializeObjects(wStream); 48 this->serializeObjects(wStream);
48 } 49 }
49 #undef SKPDF_MAGIC 50 #undef SKPDF_MAGIC
50 51
51 // Serialize all objects in the fObjNumMap that have not yet been serialized; 52 // Serialize all objects in the fObjNumMap that have not yet been serialized;
52 void SkPDFObjectSerializer::serializeObjects(SkWStream* wStream) { 53 void SkPDFObjectSerializer::serializeObjects(SkWStream* wStream) {
53 const SkTArray<sk_sp<SkPDFObject>>& objects = fObjNumMap.objects(); 54 const SkTArray<sk_sp<SkPDFObject>>& objects = fObjNumMap.objects();
54 while (fNextToBeSerialized < objects.count()) { 55 while (fNextToBeSerialized < objects.count()) {
55 SkPDFObject* object = objects[fNextToBeSerialized].get(); 56 SkPDFObject* object = objects[fNextToBeSerialized].get();
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 209 }
209 } 210 }
210 #endif 211 #endif
211 212
212 template <typename T> static T* clone(const T* o) { return o ? new T(*o) : nullp tr; } 213 template <typename T> static T* clone(const T* o) { return o ? new T(*o) : nullp tr; }
213 //////////////////////////////////////////////////////////////////////////////// 214 ////////////////////////////////////////////////////////////////////////////////
214 215
215 SkPDFDocument::SkPDFDocument(SkWStream* stream, 216 SkPDFDocument::SkPDFDocument(SkWStream* stream,
216 void (*doneProc)(SkWStream*, bool), 217 void (*doneProc)(SkWStream*, bool),
217 SkScalar rasterDpi, 218 SkScalar rasterDpi,
218 SkPixelSerializer* jpegEncoder, 219 const SkDocument::PDFMetadata& metadata,
220 sk_sp<SkPixelSerializer> jpegEncoder,
219 bool pdfa) 221 bool pdfa)
220 : SkDocument(stream, doneProc) 222 : SkDocument(stream, doneProc)
221 , fRasterDpi(rasterDpi) 223 , fRasterDpi(rasterDpi)
224 , fMetadata(metadata)
222 , fPDFA(pdfa) { 225 , fPDFA(pdfa) {
223 fCanon.setPixelSerializer(SkSafeRef(jpegEncoder)); 226 fCanon.setPixelSerializer(std::move(jpegEncoder));
224 } 227 }
225 228
226 SkPDFDocument::~SkPDFDocument() { 229 SkPDFDocument::~SkPDFDocument() {
227 // subclasses of SkDocument must call close() in their destructors. 230 // subclasses of SkDocument must call close() in their destructors.
228 this->close(); 231 this->close();
229 } 232 }
230 233
231 void SkPDFDocument::serialize(const sk_sp<SkPDFObject>& object) { 234 void SkPDFDocument::serialize(const sk_sp<SkPDFObject>& object) {
232 fObjectSerializer.addObjectRecursively(object); 235 fObjectSerializer.addObjectRecursively(object);
233 fObjectSerializer.serializeObjects(this->getStream()); 236 fObjectSerializer.serializeObjects(this->getStream());
234 } 237 }
235 238
236 SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height, 239 SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height,
237 const SkRect& trimBox) { 240 const SkRect& trimBox) {
238 SkASSERT(!fCanvas.get()); // endPage() was called before this. 241 SkASSERT(!fCanvas.get()); // endPage() was called before this.
239 if (fPages.empty()) { 242 if (fPages.empty()) {
240 // if this is the first page if the document. 243 // if this is the first page if the document.
241 fObjectSerializer.serializeHeader(this->getStream(), fMetadata); 244 fObjectSerializer.serializeHeader(this->getStream(), fMetadata);
242 fDests = sk_make_sp<SkPDFDict>(); 245 fDests = sk_make_sp<SkPDFDict>();
243 if (fPDFA) { 246 if (fPDFA) {
244 SkPDFMetadata::UUID uuid = fMetadata.uuid(); 247 SkPDFMetadata::UUID uuid = SkPDFMetadata::CreateUUID(fMetadata);
245 // We use the same UUID for Document ID and Instance ID since this 248 // We use the same UUID for Document ID and Instance ID since this
246 // is the first revision of this document (and Skia does not 249 // is the first revision of this document (and Skia does not
247 // support revising existing PDF documents). 250 // support revising existing PDF documents).
248 // If we are not in PDF/A mode, don't use a UUID since testing 251 // If we are not in PDF/A mode, don't use a UUID since testing
249 // works best with reproducible outputs. 252 // works best with reproducible outputs.
250 fID.reset(SkPDFMetadata::CreatePdfId(uuid, uuid)); 253 fID = SkPDFMetadata::MakePdfId(uuid, uuid);
251 fXMP.reset(fMetadata.createXMPObject(uuid, uuid)); 254 fXMP = SkPDFMetadata::MakeXMPObject(fMetadata, uuid, uuid);
252 fObjectSerializer.addObjectRecursively(fXMP); 255 fObjectSerializer.addObjectRecursively(fXMP);
253 fObjectSerializer.serializeObjects(this->getStream()); 256 fObjectSerializer.serializeObjects(this->getStream());
254 } 257 }
255 } 258 }
256 SkISize pageSize = SkISize::Make( 259 SkISize pageSize = SkISize::Make(
257 SkScalarRoundToInt(width), SkScalarRoundToInt(height)); 260 SkScalarRoundToInt(width), SkScalarRoundToInt(height));
258 fPageDevice.reset( 261 fPageDevice.reset(
259 SkPDFDevice::Create(pageSize, fRasterDpi, this)); 262 SkPDFDevice::Create(pageSize, fRasterDpi, this));
260 fCanvas = sk_make_sp<SkPDFCanvas>(fPageDevice); 263 fCanvas = sk_make_sp<SkPDFCanvas>(fPageDevice);
261 fCanvas->clipRect(trimBox); 264 fCanvas->clipRect(trimBox);
(...skipping 24 matching lines...) Expand all
286 fPageDevice.reset(nullptr); 289 fPageDevice.reset(nullptr);
287 } 290 }
288 291
289 void SkPDFDocument::onAbort() { 292 void SkPDFDocument::onAbort() {
290 fCanvas.reset(nullptr); 293 fCanvas.reset(nullptr);
291 fPages.reset(); 294 fPages.reset();
292 fCanon.reset(); 295 fCanon.reset();
293 renew(&fObjectSerializer); 296 renew(&fObjectSerializer);
294 } 297 }
295 298
299 #ifdef SK_SUPPORT_LEGACY_DOCUMENT_API
296 void SkPDFDocument::setMetadata(const SkDocument::Attribute info[], 300 void SkPDFDocument::setMetadata(const SkDocument::Attribute info[],
297 int infoCount, 301 int infoCount,
298 const SkTime::DateTime* creationDate, 302 const SkTime::DateTime* creationDate,
299 const SkTime::DateTime* modifiedDate) { 303 const SkTime::DateTime* modifiedDate) {
300 fMetadata.fInfo.reset(info, infoCount); 304 for (int i = 0; i < infoCount; ++i) {
301 fMetadata.fCreation.reset(clone(creationDate)); 305 const SkDocument::Attribute& kv = info[i];
302 fMetadata.fModified.reset(clone(modifiedDate)); 306 SkPDFMetadata::SetMetadataByKey(kv.fKey, kv.fValue, &fMetadata);
307 }
308 if (creationDate) {
309 fMetadata.fCreation.fEnabled = true;
310 fMetadata.fCreation.fDateTime = *creationDate;
311 }
312 if (modifiedDate) {
313 fMetadata.fModified.fEnabled = true;
314 fMetadata.fModified.fDateTime = *modifiedDate;
315 }
303 } 316 }
317 #endif // SK_SUPPORT_LEGACY_DOCUMENT_API
304 318
305 static sk_sp<SkData> SkSrgbIcm() { 319 static sk_sp<SkData> SkSrgbIcm() {
306 // Source: http://www.argyllcms.com/icclibsrc.html 320 // Source: http://www.argyllcms.com/icclibsrc.html
307 static const char kProfile[] = 321 static const char kProfile[] =
308 "\0\0\14\214argl\2 \0\0mntrRGB XYZ \7\336\0\1\0\6\0\26\0\17\0:acspM" 322 "\0\0\14\214argl\2 \0\0mntrRGB XYZ \7\336\0\1\0\6\0\26\0\17\0:acspM"
309 "SFT\0\0\0\0IEC sRGB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\366\326\0\1\0\0\0\0" 323 "SFT\0\0\0\0IEC sRGB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\366\326\0\1\0\0\0\0"
310 "\323-argl\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 324 "\323-argl\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
311 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\21desc\0\0\1P\0\0\0\231cprt\0" 325 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\21desc\0\0\1P\0\0\0\231cprt\0"
312 "\0\1\354\0\0\0gdmnd\0\0\2T\0\0\0pdmdd\0\0\2\304\0\0\0\210tech\0\0\3" 326 "\0\1\354\0\0\0gdmnd\0\0\2T\0\0\0pdmdd\0\0\2\304\0\0\0\210tech\0\0\3"
313 "L\0\0\0\14vued\0\0\3X\0\0\0gview\0\0\3\300\0\0\0$lumi\0\0\3\344\0\0" 327 "L\0\0\0\14vued\0\0\3X\0\0\0gview\0\0\3\300\0\0\0$lumi\0\0\3\344\0\0"
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 fCanon.reset(); 500 fCanon.reset();
487 renew(&fObjectSerializer); 501 renew(&fObjectSerializer);
488 return true; 502 return true;
489 } 503 }
490 504
491 /////////////////////////////////////////////////////////////////////////////// 505 ///////////////////////////////////////////////////////////////////////////////
492 506
493 sk_sp<SkDocument> SkPDFMakeDocument(SkWStream* stream, 507 sk_sp<SkDocument> SkPDFMakeDocument(SkWStream* stream,
494 void (*proc)(SkWStream*, bool), 508 void (*proc)(SkWStream*, bool),
495 SkScalar dpi, 509 SkScalar dpi,
496 SkPixelSerializer* jpeg, 510 const SkDocument::PDFMetadata& metadata,
511 sk_sp<SkPixelSerializer> jpeg,
497 bool pdfa) { 512 bool pdfa) {
498 return stream ? sk_make_sp<SkPDFDocument>(stream, proc, dpi, jpeg, pdfa) 513 return stream ? sk_make_sp<SkPDFDocument>(stream, proc, dpi, metadata,
514 std::move(jpeg), pdfa)
499 : nullptr; 515 : nullptr;
500 } 516 }
501 517
502 #ifdef SK_PDF_GENERATE_PDFA 518 sk_sp<SkDocument> SkDocument::MakePDF(const char path[], SkScalar dpi) {
503 static const bool kPDFA = true;
504 #else
505 static const bool kPDFA = false;
506 #endif
507
508 SkDocument* SkDocument::CreatePDF(SkWStream* stream, SkScalar dpi) {
509 return SkPDFMakeDocument(stream, nullptr, dpi, nullptr, kPDFA).release();
510 }
511
512 SkDocument* SkDocument::CreatePDF(SkWStream* stream,
513 SkScalar dpi,
514 SkPixelSerializer* jpegEncoder) {
515 return SkPDFMakeDocument(stream, nullptr, dpi,
516 jpegEncoder, kPDFA).release();
517 }
518
519 SkDocument* SkDocument::CreatePDF(const char path[], SkScalar dpi) {
520 auto delete_wstream = [](SkWStream* stream, bool) { delete stream; }; 519 auto delete_wstream = [](SkWStream* stream, bool) { delete stream; };
521 std::unique_ptr<SkFILEWStream> stream(new SkFILEWStream(path)); 520 std::unique_ptr<SkFILEWStream> stream(new SkFILEWStream(path));
522 return stream->isValid() 521 return stream->isValid()
523 ? SkPDFMakeDocument(stream.release(), delete_wstream, dpi, 522 ? SkPDFMakeDocument(stream.release(), delete_wstream, dpi,
524 nullptr, kPDFA).release() 523 SkDocument::PDFMetadata(), nullptr,
525 : nullptr; 524 false)
525 : nullptr;
526 } 526 }
527
528 sk_sp<SkDocument> SkDocument::MakePDF(SkWStream* stream,
529 SkScalar dpi,
530 const SkDocument::PDFMetadata& metadata,
531 sk_sp<SkPixelSerializer> jpegEncoder,
532 bool pdfa) {
533 return SkPDFMakeDocument(stream, nullptr, dpi, metadata,
534 std::move(jpegEncoder), pdfa);
535 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDocument.h ('k') | src/pdf/SkPDFMetadata.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698