SkPDF: fix PDF/A

TODO: get a bot to start testing this.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1864163004

Review URL: https://codereview.chromium.org/1864163004
This commit is contained in:
halcanary 2016-04-07 08:56:15 -07:00 committed by Commit bot
parent 6c71e0a065
commit 8cd4a24236
3 changed files with 29 additions and 19 deletions

View File

@ -238,6 +238,18 @@ SkCanvas* SkPDFDocument::onBeginPage(SkScalar width, SkScalar height,
// if this is the first page if the document.
fObjectSerializer.serializeHeader(this->getStream(), fMetadata);
fDests = sk_make_sp<SkPDFDict>();
#ifdef SK_PDF_GENERATE_PDFA
SkPDFMetadata::UUID uuid = fMetadata.uuid();
// We use the same UUID for Document ID and Instance ID since this
// is the first revision of this document (and Skia does not
// support revising existing PDF documents).
// If we are not in PDF/A mode, don't use a UUID since testing
// works best with reproducible outputs.
fID.reset(SkPDFMetadata::CreatePdfId(uuid, uuid));
fXMP.reset(fMetadata.createXMPObject(uuid, uuid));
fObjectSerializer.addObjectRecursively(fXMP);
fObjectSerializer.serializeObjects(this->getStream());
#endif
}
SkISize pageSize = SkISize::Make(
SkScalarRoundToInt(width), SkScalarRoundToInt(height));
@ -297,18 +309,9 @@ bool SkPDFDocument::onClose(SkWStream* stream) {
return false;
}
auto docCatalog = sk_make_sp<SkPDFDict>("Catalog");
sk_sp<SkPDFObject> id, xmp;
#ifdef SK_PDF_GENERATE_PDFA
SkPDFMetadata::UUID uuid = metadata.uuid();
// We use the same UUID for Document ID and Instance ID since this
// is the first revision of this document (and Skia does not
// support revising existing PDF documents).
// If we are not in PDF/A mode, don't use a UUID since testing
// works best with reproducible outputs.
id.reset(SkPDFMetadata::CreatePdfId(uuid, uuid));
xmp.reset(metadata.createXMPObject(uuid, uuid));
docCatalog->insertObjRef("Metadata", std::move(xmp));
SkASSERT(fXMP);
docCatalog->insertObjRef("Metadata", fXMP);
// sRGB is specified by HTML, CSS, and SVG.
auto outputIntent = sk_make_sp<SkPDFDict>("OutputIntent");
outputIntent->insertName("S", "GTS_PDFA1");
@ -321,7 +324,6 @@ bool SkPDFDocument::onClose(SkWStream* stream) {
// no one has ever asked for this feature.
docCatalog->insertObject("OutputIntents", std::move(intentArray));
#endif
docCatalog->insertObjRef("Pages", generate_page_tree(&fPages));
if (fDests->size() > 0) {
@ -340,9 +342,12 @@ bool SkPDFDocument::onClose(SkWStream* stream) {
fObjectSerializer.addObjectRecursively(docCatalog);
fObjectSerializer.serializeObjects(this->getStream());
fObjectSerializer.serializeFooter(
this->getStream(), docCatalog, std::move(id));
#ifdef SK_PDF_GENERATE_PDFA
fObjectSerializer.serializeFooter(this->getStream(), docCatalog, fID);
#else
fObjectSerializer.serializeFooter(
this->getStream(), docCatalog, nullptr);
#endif
SkASSERT(fPages.count() == 0);
fCanon.reset();
renew(&fObjectSerializer);

View File

@ -79,6 +79,10 @@ private:
sk_sp<SkPDFDict> fDests;
sk_sp<SkPDFDevice> fPageDevice;
sk_sp<SkCanvas> fCanvas;
#ifdef SK_PDF_GENERATE_PDFA
sk_sp<SkPDFObject> fID;
sk_sp<SkPDFObject> fXMP;
#endif
SkScalar fRasterDpi;
SkPDFMetadata fMetadata;
};

View File

@ -52,9 +52,6 @@ SkPDFObject* SkPDFMetadata::createDocumentInformationDict() const {
return dict.release();
}
#undef SKPDF_STRING
#undef SKPDF_STRING_IMPL
#ifdef SK_PDF_GENERATE_PDFA
SkPDFMetadata::UUID SkPDFMetadata::uuid() const {
// The main requirement is for the UUID to be unique; the exact
@ -297,7 +294,7 @@ SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc,
"%s" // keywords
"<xmpMM:DocumentID>uuid:%s</xmpMM:DocumentID>\n"
"<xmpMM:InstanceID>uuid:%s</xmpMM:InstanceID>\n"
"<pdf:Producer>Skia/PDF</pdf:Producer>\n"
"<pdf:Producer>Skia/PDF m" SKPDF_STRING(SK_MILESTONE) "</pdf:Producer>\n"
"%s" // pdf:Keywords
"</rdf:Description>\n"
"</rdf:RDF>\n"
@ -356,3 +353,7 @@ SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc,
}
#endif // SK_PDF_GENERATE_PDFA
#undef SKPDF_STRING
#undef SKPDF_STRING_IMPL