| Index: src/pdf/SkPDFMetadata.cpp
|
| diff --git a/src/pdf/SkPDFMetadata.cpp b/src/pdf/SkPDFMetadata.cpp
|
| index d3abd78312caecdcfff651cc6d7698b28abc6149..b9aa3bb5a9515b25d408cb1148fc0b440527b41f 100644
|
| --- a/src/pdf/SkPDFMetadata.cpp
|
| +++ b/src/pdf/SkPDFMetadata.cpp
|
| @@ -28,28 +28,54 @@ static SkString pdf_date(const SkTime::DateTime& dt) {
|
| #define SKPDF_STRING(X) SKPDF_STRING_IMPL(X)
|
| #define SKPDF_STRING_IMPL(X) #X
|
|
|
| -SkPDFObject* SkPDFMetadata::createDocumentInformationDict() const {
|
| +namespace {
|
| +static const struct {
|
| + const char* const key;
|
| + SkString SkDocument::PDFMetadata::*const valuePtr;
|
| +} gMetadataKeys[] = {
|
| + {"Title", &SkDocument::PDFMetadata::fTitle},
|
| + {"Author", &SkDocument::PDFMetadata::fAuthor},
|
| + {"Subject", &SkDocument::PDFMetadata::fSubject},
|
| + {"Keywords", &SkDocument::PDFMetadata::fKeywords},
|
| + {"Creator", &SkDocument::PDFMetadata::fCreator},
|
| +};
|
| +} // namespace
|
| +
|
| +#ifdef SK_SUPPORT_LEGACY_DOCUMENT_API
|
| +void SkPDFMetadata::SetMetadataByKey(const SkString& key,
|
| + const SkString& value,
|
| + SkDocument::PDFMetadata* metadata) {
|
| + for (const auto keyValuePtr : gMetadataKeys) {
|
| + if (key.equals(keyValuePtr.key)) {
|
| + metadata->*(keyValuePtr.valuePtr) = value;
|
| + }
|
| + }
|
| +}
|
| +
|
| +#endif
|
| +
|
| +sk_sp<SkPDFObject> SkPDFMetadata::MakeDocumentInformationDict(
|
| + const SkDocument::PDFMetadata& metadata) {
|
| auto dict = sk_make_sp<SkPDFDict>();
|
| - static const char* keys[] = {
|
| - "Title", "Author", "Subject", "Keywords", "Creator"};
|
| - for (const char* key : keys) {
|
| - for (const SkDocument::Attribute& keyValue : fInfo) {
|
| - if (keyValue.fKey.equals(key)) {
|
| - dict->insertString(key, keyValue.fValue);
|
| - }
|
| + for (const auto keyValuePtr : gMetadataKeys) {
|
| + const SkString& value = metadata.*(keyValuePtr.valuePtr);
|
| + if (value.size() > 0) {
|
| + dict->insertString(keyValuePtr.key, value);
|
| }
|
| }
|
| dict->insertString("Producer", "Skia/PDF m" SKPDF_STRING(SK_MILESTONE));
|
| - if (fCreation) {
|
| - dict->insertString("CreationDate", pdf_date(*fCreation.get()));
|
| + if (metadata.fCreation.fEnabled) {
|
| + dict->insertString("CreationDate",
|
| + pdf_date(metadata.fCreation.fDateTime));
|
| }
|
| - if (fModified) {
|
| - dict->insertString("ModDate", pdf_date(*fModified.get()));
|
| + if (metadata.fModified.fEnabled) {
|
| + dict->insertString("ModDate", pdf_date(metadata.fModified.fDateTime));
|
| }
|
| - return dict.release();
|
| + return dict;
|
| }
|
|
|
| -SkPDFMetadata::UUID SkPDFMetadata::uuid() const {
|
| +SkPDFMetadata::UUID SkPDFMetadata::CreateUUID(
|
| + const SkDocument::PDFMetadata& metadata) {
|
| // The main requirement is for the UUID to be unique; the exact
|
| // format of the data that will be hashed is not important.
|
| SkMD5 md5;
|
| @@ -60,16 +86,20 @@ SkPDFMetadata::UUID SkPDFMetadata::uuid() const {
|
| SkTime::DateTime dateTime;
|
| SkTime::GetDateTime(&dateTime);
|
| md5.write(&dateTime, sizeof(dateTime));
|
| - if (fCreation) {
|
| - md5.write(fCreation.get(), sizeof(fCreation));
|
| + if (metadata.fCreation.fEnabled) {
|
| + md5.write(&metadata.fCreation.fDateTime,
|
| + sizeof(metadata.fCreation.fDateTime));
|
| }
|
| - if (fModified) {
|
| - md5.write(fModified.get(), sizeof(fModified));
|
| + if (metadata.fModified.fEnabled) {
|
| + md5.write(&metadata.fModified.fDateTime,
|
| + sizeof(metadata.fModified.fDateTime));
|
| }
|
| - for (const auto& kv : fInfo) {
|
| - md5.write(kv.fKey.c_str(), kv.fKey.size());
|
| +
|
| + for (const auto keyValuePtr : gMetadataKeys) {
|
| + md5.write(keyValuePtr.key, strlen(keyValuePtr.key));
|
| md5.write("\037", 1);
|
| - md5.write(kv.fValue.c_str(), kv.fValue.size());
|
| + const SkString& value = metadata.*(keyValuePtr.valuePtr);
|
| + md5.write(value.c_str(), value.size());
|
| md5.write("\036", 1);
|
| }
|
| SkMD5::Digest digest;
|
| @@ -83,26 +113,17 @@ SkPDFMetadata::UUID SkPDFMetadata::uuid() const {
|
| return uuid;
|
| }
|
|
|
| -SkPDFObject* SkPDFMetadata::CreatePdfId(const UUID& doc, const UUID& instance) {
|
| +sk_sp<SkPDFObject> SkPDFMetadata::MakePdfId(const UUID& doc,
|
| + const UUID& instance) {
|
| // /ID [ <81b14aafa313db63dbd6f981e49f94f4>
|
| // <81b14aafa313db63dbd6f981e49f94f4> ]
|
| auto array = sk_make_sp<SkPDFArray>();
|
| - static_assert(sizeof(UUID) == 16, "uuid_size");
|
| + static_assert(sizeof(SkPDFMetadata::UUID) == 16, "uuid_size");
|
| array->appendString(
|
| SkString(reinterpret_cast<const char*>(&doc), sizeof(UUID)));
|
| array->appendString(
|
| SkString(reinterpret_cast<const char*>(&instance), sizeof(UUID)));
|
| - return array.release();
|
| -}
|
| -
|
| -static const SkString get(const SkTArray<SkDocument::Attribute>& info,
|
| - const char* key) {
|
| - for (const auto& keyValue : info) {
|
| - if (keyValue.fKey.equals(key)) {
|
| - return keyValue.fValue;
|
| - }
|
| - }
|
| - return SkString();
|
| + return array;
|
| }
|
|
|
| #define HEXIFY(INPUT_PTR, OUTPUT_PTR, HEX_STRING, BYTE_COUNT) \
|
| @@ -214,8 +235,10 @@ const SkString escape_xml(const SkString& input,
|
| return output;
|
| }
|
|
|
| -SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc,
|
| - const UUID& instance) const {
|
| +sk_sp<SkPDFObject> SkPDFMetadata::MakeXMPObject(
|
| + const SkDocument::PDFMetadata& metadata,
|
| + const UUID& doc,
|
| + const UUID& instance) {
|
| static const char templateString[] =
|
| "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n"
|
| "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"\n"
|
| @@ -250,54 +273,52 @@ SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc,
|
|
|
| SkString creationDate;
|
| SkString modificationDate;
|
| - if (fCreation) {
|
| + if (metadata.fCreation.fEnabled) {
|
| SkString tmp;
|
| - fCreation->toISO8601(&tmp);
|
| + metadata.fCreation.fDateTime.toISO8601(&tmp);
|
| SkASSERT(0 == count_xml_escape_size(tmp));
|
| // YYYY-mm-ddTHH:MM:SS[+|-]ZZ:ZZ; no need to escape
|
| creationDate = SkStringPrintf("<xmp:CreateDate>%s</xmp:CreateDate>\n",
|
| tmp.c_str());
|
| }
|
| - if (fModified) {
|
| + if (metadata.fModified.fEnabled) {
|
| SkString tmp;
|
| - fModified->toISO8601(&tmp);
|
| + metadata.fModified.fDateTime.toISO8601(&tmp);
|
| SkASSERT(0 == count_xml_escape_size(tmp));
|
| modificationDate = SkStringPrintf(
|
| "<xmp:ModifyDate>%s</xmp:ModifyDate>\n", tmp.c_str());
|
| }
|
| - SkString title = escape_xml(
|
| - get(fInfo, "Title"),
|
| - "<dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">",
|
| - "</rdf:li></rdf:Alt></dc:title>\n");
|
| - SkString author = escape_xml(
|
| - get(fInfo, "Author"), "<dc:creator><rdf:Bag><rdf:li>",
|
| - "</rdf:li></rdf:Bag></dc:creator>\n");
|
| + SkString title =
|
| + escape_xml(metadata.fTitle,
|
| + "<dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">",
|
| + "</rdf:li></rdf:Alt></dc:title>\n");
|
| + SkString author =
|
| + escape_xml(metadata.fAuthor, "<dc:creator><rdf:Bag><rdf:li>",
|
| + "</rdf:li></rdf:Bag></dc:creator>\n");
|
| // TODO: in theory, XMP can support multiple authors. Split on a delimiter?
|
| SkString subject = escape_xml(
|
| - get(fInfo, "Subject"),
|
| + metadata.fSubject,
|
| "<dc:description><rdf:Alt><rdf:li xml:lang=\"x-default\">",
|
| "</rdf:li></rdf:Alt></dc:description>\n");
|
| - SkString keywords1 = escape_xml(
|
| - get(fInfo, "Keywords"), "<dc:subject><rdf:Bag><rdf:li>",
|
| - "</rdf:li></rdf:Bag></dc:subject>\n");
|
| - SkString keywords2 = escape_xml(
|
| - get(fInfo, "Keywords"), "<pdf:Keywords>",
|
| - "</pdf:Keywords>\n");
|
| + SkString keywords1 =
|
| + escape_xml(metadata.fKeywords, "<dc:subject><rdf:Bag><rdf:li>",
|
| + "</rdf:li></rdf:Bag></dc:subject>\n");
|
| + SkString keywords2 = escape_xml(metadata.fKeywords, "<pdf:Keywords>",
|
| + "</pdf:Keywords>\n");
|
|
|
| // TODO: in theory, keywords can be a list too.
|
| - SkString creator = escape_xml(get(fInfo, "Creator"), "<xmp:CreatorTool>",
|
| + SkString creator = escape_xml(metadata.fCreator, "<xmp:CreatorTool>",
|
| "</xmp:CreatorTool>\n");
|
| SkString documentID = uuid_to_string(doc); // no need to escape
|
| SkASSERT(0 == count_xml_escape_size(documentID));
|
| SkString instanceID = uuid_to_string(instance);
|
| SkASSERT(0 == count_xml_escape_size(instanceID));
|
| - return new PDFXMLObject(SkStringPrintf(
|
| + return sk_make_sp<PDFXMLObject>(SkStringPrintf(
|
| templateString, modificationDate.c_str(), creationDate.c_str(),
|
| - creator.c_str(), title.c_str(),
|
| - subject.c_str(), author.c_str(), keywords1.c_str(),
|
| - documentID.c_str(), instanceID.c_str(), keywords2.c_str()));
|
| + creator.c_str(), title.c_str(), subject.c_str(), author.c_str(),
|
| + keywords1.c_str(), documentID.c_str(), instanceID.c_str(),
|
| + keywords2.c_str()));
|
| }
|
|
|
| #undef SKPDF_STRING
|
| #undef SKPDF_STRING_IMPL
|
| -
|
|
|