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

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

Issue 1864163004: SkPDF: fix PDF/A (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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.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 "SkPDFCanon.h" 8 #include "SkPDFCanon.h"
9 #include "SkPDFCanvas.h" 9 #include "SkPDFCanvas.h"
10 #include "SkPDFDevice.h" 10 #include "SkPDFDevice.h"
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 fObjectSerializer.serializeObjects(this->getStream()); 231 fObjectSerializer.serializeObjects(this->getStream());
232 } 232 }
233 233
234 SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height, 234 SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height,
235 const SkRect& trimBox) { 235 const SkRect& trimBox) {
236 SkASSERT(!fCanvas.get()); // endPage() was called before this. 236 SkASSERT(!fCanvas.get()); // endPage() was called before this.
237 if (fPages.empty()) { 237 if (fPages.empty()) {
238 // if this is the first page if the document. 238 // if this is the first page if the document.
239 fObjectSerializer.serializeHeader(this->getStream(), fMetadata); 239 fObjectSerializer.serializeHeader(this->getStream(), fMetadata);
240 fDests = sk_make_sp<SkPDFDict>(); 240 fDests = sk_make_sp<SkPDFDict>();
241 #ifdef SK_PDF_GENERATE_PDFA
242 SkPDFMetadata::UUID uuid = fMetadata.uuid();
243 // We use the same UUID for Document ID and Instance ID since this
244 // is the first revision of this document (and Skia does not
245 // support revising existing PDF documents).
246 // If we are not in PDF/A mode, don't use a UUID since testing
247 // works best with reproducible outputs.
248 fID.reset(SkPDFMetadata::CreatePdfId(uuid, uuid));
249 fXMP.reset(fMetadata.createXMPObject(uuid, uuid));
250 fObjectSerializer.addObjectRecursively(fXMP);
251 fObjectSerializer.serializeObjects(this->getStream());
252 #endif
241 } 253 }
242 SkISize pageSize = SkISize::Make( 254 SkISize pageSize = SkISize::Make(
243 SkScalarRoundToInt(width), SkScalarRoundToInt(height)); 255 SkScalarRoundToInt(width), SkScalarRoundToInt(height));
244 fPageDevice.reset( 256 fPageDevice.reset(
245 SkPDFDevice::Create(pageSize, fRasterDpi, this)); 257 SkPDFDevice::Create(pageSize, fRasterDpi, this));
246 fCanvas = sk_make_sp<SkPDFCanvas>(fPageDevice); 258 fCanvas = sk_make_sp<SkPDFCanvas>(fPageDevice);
247 fCanvas->clipRect(trimBox); 259 fCanvas->clipRect(trimBox);
248 fCanvas->translate(trimBox.x(), trimBox.y()); 260 fCanvas->translate(trimBox.x(), trimBox.y());
249 return fCanvas.get(); 261 return fCanvas.get();
250 } 262 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 302
291 bool SkPDFDocument::onClose(SkWStream* stream) { 303 bool SkPDFDocument::onClose(SkWStream* stream) {
292 SkASSERT(!fCanvas.get()); 304 SkASSERT(!fCanvas.get());
293 if (fPages.empty()) { 305 if (fPages.empty()) {
294 fPages.reset(); 306 fPages.reset();
295 fCanon.reset(); 307 fCanon.reset();
296 renew(&fObjectSerializer); 308 renew(&fObjectSerializer);
297 return false; 309 return false;
298 } 310 }
299 auto docCatalog = sk_make_sp<SkPDFDict>("Catalog"); 311 auto docCatalog = sk_make_sp<SkPDFDict>("Catalog");
300 sk_sp<SkPDFObject> id, xmp;
301 #ifdef SK_PDF_GENERATE_PDFA 312 #ifdef SK_PDF_GENERATE_PDFA
302 SkPDFMetadata::UUID uuid = metadata.uuid(); 313 SkASSERT(fXMP);
303 // We use the same UUID for Document ID and Instance ID since this 314 docCatalog->insertObjRef("Metadata", fXMP);
304 // is the first revision of this document (and Skia does not
305 // support revising existing PDF documents).
306 // If we are not in PDF/A mode, don't use a UUID since testing
307 // works best with reproducible outputs.
308 id.reset(SkPDFMetadata::CreatePdfId(uuid, uuid));
309 xmp.reset(metadata.createXMPObject(uuid, uuid));
310 docCatalog->insertObjRef("Metadata", std::move(xmp));
311
312 // sRGB is specified by HTML, CSS, and SVG. 315 // sRGB is specified by HTML, CSS, and SVG.
313 auto outputIntent = sk_make_sp<SkPDFDict>("OutputIntent"); 316 auto outputIntent = sk_make_sp<SkPDFDict>("OutputIntent");
314 outputIntent->insertName("S", "GTS_PDFA1"); 317 outputIntent->insertName("S", "GTS_PDFA1");
315 outputIntent->insertString("RegistryName", "http://www.color.org"); 318 outputIntent->insertString("RegistryName", "http://www.color.org");
316 outputIntent->insertString("OutputConditionIdentifier", 319 outputIntent->insertString("OutputConditionIdentifier",
317 "sRGB IEC61966-2.1"); 320 "sRGB IEC61966-2.1");
318 auto intentArray = sk_make_sp<SkPDFArray>(); 321 auto intentArray = sk_make_sp<SkPDFArray>();
319 intentArray->appendObject(std::move(outputIntent)); 322 intentArray->appendObject(std::move(outputIntent));
320 // Don't specify OutputIntents if we are not in PDF/A mode since 323 // Don't specify OutputIntents if we are not in PDF/A mode since
321 // no one has ever asked for this feature. 324 // no one has ever asked for this feature.
322 docCatalog->insertObject("OutputIntents", std::move(intentArray)); 325 docCatalog->insertObject("OutputIntents", std::move(intentArray));
323 #endif 326 #endif
324
325 docCatalog->insertObjRef("Pages", generate_page_tree(&fPages)); 327 docCatalog->insertObjRef("Pages", generate_page_tree(&fPages));
326 328
327 if (fDests->size() > 0) { 329 if (fDests->size() > 0) {
328 docCatalog->insertObjRef("Dests", std::move(fDests)); 330 docCatalog->insertObjRef("Dests", std::move(fDests));
329 } 331 }
330 332
331 // Build font subsetting info before calling addObjectRecursively(). 333 // Build font subsetting info before calling addObjectRecursively().
332 for (const auto& entry : fGlyphUsage) { 334 for (const auto& entry : fGlyphUsage) {
333 sk_sp<SkPDFFont> subsetFont( 335 sk_sp<SkPDFFont> subsetFont(
334 entry.fFont->getFontSubset(entry.fGlyphSet)); 336 entry.fFont->getFontSubset(entry.fGlyphSet));
335 if (subsetFont) { 337 if (subsetFont) {
336 fObjectSerializer.fSubstituteMap.setSubstitute( 338 fObjectSerializer.fSubstituteMap.setSubstitute(
337 entry.fFont, subsetFont.get()); 339 entry.fFont, subsetFont.get());
338 } 340 }
339 } 341 }
340 342
341 fObjectSerializer.addObjectRecursively(docCatalog); 343 fObjectSerializer.addObjectRecursively(docCatalog);
342 fObjectSerializer.serializeObjects(this->getStream()); 344 fObjectSerializer.serializeObjects(this->getStream());
343 fObjectSerializer.serializeFooter( 345 #ifdef SK_PDF_GENERATE_PDFA
344 this->getStream(), docCatalog, std::move(id)); 346 fObjectSerializer.serializeFooter(this->getStream(), docCatalog, fID);
345 347 #else
348 fObjectSerializer.serializeFooter(
349 this->getStream(), docCatalog, nullptr);
350 #endif
346 SkASSERT(fPages.count() == 0); 351 SkASSERT(fPages.count() == 0);
347 fCanon.reset(); 352 fCanon.reset();
348 renew(&fObjectSerializer); 353 renew(&fObjectSerializer);
349 return true; 354 return true;
350 } 355 }
351 356
352 /////////////////////////////////////////////////////////////////////////////// 357 ///////////////////////////////////////////////////////////////////////////////
353 358
354 sk_sp<SkDocument> SkPDFMakeDocument(SkWStream* stream, 359 sk_sp<SkDocument> SkPDFMakeDocument(SkWStream* stream,
355 void (*proc)(SkWStream*, bool), 360 void (*proc)(SkWStream*, bool),
(...skipping 12 matching lines...) Expand all
368 return SkPDFMakeDocument(stream, nullptr, dpi, jpegEncoder).release(); 373 return SkPDFMakeDocument(stream, nullptr, dpi, jpegEncoder).release();
369 } 374 }
370 375
371 SkDocument* SkDocument::CreatePDF(const char path[], SkScalar dpi) { 376 SkDocument* SkDocument::CreatePDF(const char path[], SkScalar dpi) {
372 auto delete_wstream = [](SkWStream* stream, bool) { delete stream; }; 377 auto delete_wstream = [](SkWStream* stream, bool) { delete stream; };
373 std::unique_ptr<SkFILEWStream> stream(new SkFILEWStream(path)); 378 std::unique_ptr<SkFILEWStream> stream(new SkFILEWStream(path));
374 return stream->isValid() 379 return stream->isValid()
375 ? SkPDFMakeDocument(stream.release(), delete_wstream, dpi, nullptr).rele ase() 380 ? SkPDFMakeDocument(stream.release(), delete_wstream, dpi, nullptr).rele ase()
376 : nullptr; 381 : nullptr;
377 } 382 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDocument.h ('k') | src/pdf/SkPDFMetadata.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698