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

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

Issue 1864173004: SkPDF Fix PDF/A to be more valid (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.cpp ('k') | no next file » | 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 2015 Google Inc. 2 * Copyright 2015 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 "SkMilestone.h" 8 #include "SkMilestone.h"
9 #include "SkPDFMetadata.h" 9 #include "SkPDFMetadata.h"
10 #include "SkPDFTypes.h" 10 #include "SkPDFTypes.h"
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 *out++ = input[i]; 256 *out++ = input[i];
257 } 257 }
258 } 258 }
259 if (after) { 259 if (after) {
260 strncpy(out, after, afterLen); 260 strncpy(out, after, afterLen);
261 out += afterLen; 261 out += afterLen;
262 } 262 }
263 // Validate that we haven't written outside of our string. 263 // Validate that we haven't written outside of our string.
264 SkASSERT(out == &output.writable_str()[output.size()]); 264 SkASSERT(out == &output.writable_str()[output.size()]);
265 *out = '\0'; 265 *out = '\0';
266 return std::move(output); 266 return output;
267 } 267 }
268 268
269 SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc, 269 SkPDFObject* SkPDFMetadata::createXMPObject(const UUID& doc,
270 const UUID& instance) const { 270 const UUID& instance) const {
271 static const char templateString[] = 271 static const char templateString[] =
272 "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n" 272 "<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n"
273 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"\n" 273 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"\n"
274 " x:xmptk=\"Adobe XMP Core 5.4-c005 78.147326, " 274 " x:xmptk=\"Adobe XMP Core 5.4-c005 78.147326, "
275 "2012/08/23-13:03:03\">\n" 275 "2012/08/23-13:03:03\">\n"
276 "<rdf:RDF " 276 "<rdf:RDF "
277 "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n" 277 "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
278 "<rdf:Description rdf:about=\"\"\n" 278 "<rdf:Description rdf:about=\"\"\n"
279 " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n" 279 " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n"
280 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" 280 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
281 " xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n" 281 " xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n"
282 " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\"\n" 282 " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\"\n"
283 " xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\">\n" 283 " xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\">\n"
284 "<pdfaid:part>2</pdfaid:part>\n" 284 "<pdfaid:part>2</pdfaid:part>\n"
285 "<pdfaid:conformance>B</pdfaid:conformance>\n" 285 "<pdfaid:conformance>B</pdfaid:conformance>\n"
286 "%s" // ModifyDate 286 "%s" // ModifyDate
287 "%s" // CreateDate 287 "%s" // CreateDate
288 "%s" // MetadataDate
289 "%s" // xmp:CreatorTool 288 "%s" // xmp:CreatorTool
290 "<dc:format>application/pdf</dc:format>\n" 289 "<dc:format>application/pdf</dc:format>\n"
291 "%s" // dc:title 290 "%s" // dc:title
292 "%s" // dc:description 291 "%s" // dc:description
293 "%s" // author 292 "%s" // author
294 "%s" // keywords 293 "%s" // keywords
295 "<xmpMM:DocumentID>uuid:%s</xmpMM:DocumentID>\n" 294 "<xmpMM:DocumentID>uuid:%s</xmpMM:DocumentID>\n"
296 "<xmpMM:InstanceID>uuid:%s</xmpMM:InstanceID>\n" 295 "<xmpMM:InstanceID>uuid:%s</xmpMM:InstanceID>\n"
297 "<pdf:Producer>Skia/PDF m" SKPDF_STRING(SK_MILESTONE) "</pdf:Produce r>\n" 296 "<pdf:Producer>Skia/PDF m" SKPDF_STRING(SK_MILESTONE) "</pdf:Produce r>\n"
298 "%s" // pdf:Keywords 297 "%s" // pdf:Keywords
299 "</rdf:Description>\n" 298 "</rdf:Description>\n"
300 "</rdf:RDF>\n" 299 "</rdf:RDF>\n"
301 "</x:xmpmeta>\n" // Note: the standard suggests 4k of padding. 300 "</x:xmpmeta>\n" // Note: the standard suggests 4k of padding.
302 "<?xpacket end=\"w\"?>\n"; 301 "<?xpacket end=\"w\"?>\n";
303 302
304 SkString creationDate; 303 SkString creationDate;
305 SkString modificationDate; 304 SkString modificationDate;
306 SkString metadataDate;
307 if (fCreation) { 305 if (fCreation) {
308 SkString tmp; 306 SkString tmp;
309 fCreation->toISO8601(&tmp); 307 fCreation->toISO8601(&tmp);
310 SkASSERT(0 == count_xml_escape_size(tmp)); 308 SkASSERT(0 == count_xml_escape_size(tmp));
311 // YYYY-mm-ddTHH:MM:SS[+|-]ZZ:ZZ; no need to escape 309 // YYYY-mm-ddTHH:MM:SS[+|-]ZZ:ZZ; no need to escape
312 creationDate = sk_string_printf("<xmp:CreateDate>%s</xmp:CreateDate>\n", 310 creationDate = sk_string_printf("<xmp:CreateDate>%s</xmp:CreateDate>\n",
313 tmp.c_str()); 311 tmp.c_str());
314 } 312 }
315 if (fModified) { 313 if (fModified) {
316 SkString tmp; 314 SkString tmp;
317 fModified->toISO8601(&tmp); 315 fModified->toISO8601(&tmp);
318 SkASSERT(0 == count_xml_escape_size(tmp)); 316 SkASSERT(0 == count_xml_escape_size(tmp));
319 modificationDate = sk_string_printf( 317 modificationDate = sk_string_printf(
320 "<xmp:ModifyDate>%s</xmp:ModifyDate>\n", tmp.c_str()); 318 "<xmp:ModifyDate>%s</xmp:ModifyDate>\n", tmp.c_str());
321 metadataDate = sk_string_printf(
322 "<xmp:MetadataDate>%s</xmp:MetadataDate>\n", tmp.c_str());
323 } 319 }
324 320 SkString title = escape_xml(
325 SkString title = 321 get(fInfo, "Title"),
326 escape_xml(get(fInfo, "Title"), "<dc:title><rdf:Alt><rdf:li>", 322 "<dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">",
327 "</rdf:li></rdf:Alt></dc:title>\n"); 323 "</rdf:li></rdf:Alt></dc:title>\n");
328 SkString author = 324 SkString author = escape_xml(
329 escape_xml(get(fInfo, "Author"), "<dc:creator><rdf:Bag><rdf:li>", 325 get(fInfo, "Author"), "<dc:creator><rdf:Bag><rdf:li>",
330 "</rdf:li></rdf:Bag></dc:creator>\n"); 326 "</rdf:li></rdf:Bag></dc:creator>\n");
331 // TODO: in theory, XMP can support multiple authors. Split on a delimiter? 327 // TODO: in theory, XMP can support multiple authors. Split on a delimiter?
332 SkString subject = escape_xml(get(fInfo, "Subject"), 328 SkString subject = escape_xml(
333 "<dc:description><rdf:Alt><rdf:li>", 329 get(fInfo, "Subject"),
334 "</rdf:li></rdf:Alt></dc:description>\n"); 330 "<dc:description><rdf:Alt><rdf:li xml:lang=\"x-default\">",
335 SkString keywords1 = 331 "</rdf:li></rdf:Alt></dc:description>\n");
336 escape_xml(get(fInfo, "Keywords"), "<dc:subject><rdf:Bag><rdf:li>", 332 SkString keywords1 = escape_xml(
337 "</rdf:li></rdf:Bag></dc:subject>\n"); 333 get(fInfo, "Keywords"), "<dc:subject><rdf:Bag><rdf:li>",
338 SkString keywords2 = escape_xml(get(fInfo, "Keywords"), "<pdf:Keywords>", 334 "</rdf:li></rdf:Bag></dc:subject>\n");
339 "</pdf:Keywords>\n"); 335 SkString keywords2 = escape_xml(
336 get(fInfo, "Keywords"), "<pdf:Keywords>",
337 "</pdf:Keywords>\n");
340 338
341 // TODO: in theory, keywords can be a list too. 339 // TODO: in theory, keywords can be a list too.
342 SkString creator = escape_xml(get(fInfo, "Creator"), "<xmp:CreatorTool>", 340 SkString creator = escape_xml(get(fInfo, "Creator"), "<xmp:CreatorTool>",
343 "</xmp:CreatorTool>\n"); 341 "</xmp:CreatorTool>\n");
344 SkString documentID = uuid_to_string(doc); // no need to escape 342 SkString documentID = uuid_to_string(doc); // no need to escape
345 SkASSERT(0 == count_xml_escape_size(documentID)); 343 SkASSERT(0 == count_xml_escape_size(documentID));
346 SkString instanceID = uuid_to_string(instance); 344 SkString instanceID = uuid_to_string(instance);
347 SkASSERT(0 == count_xml_escape_size(instanceID)); 345 SkASSERT(0 == count_xml_escape_size(instanceID));
348 return new PDFXMLObject(sk_string_printf( 346 return new PDFXMLObject(sk_string_printf(
349 templateString, modificationDate.c_str(), creationDate.c_str(), 347 templateString, modificationDate.c_str(), creationDate.c_str(),
350 metadataDate.c_str(), creator.c_str(), title.c_str(), 348 creator.c_str(), title.c_str(),
351 subject.c_str(), author.c_str(), keywords1.c_str(), 349 subject.c_str(), author.c_str(), keywords1.c_str(),
352 documentID.c_str(), instanceID.c_str(), keywords2.c_str())); 350 documentID.c_str(), instanceID.c_str(), keywords2.c_str()));
353 } 351 }
354 352
355 #endif // SK_PDF_GENERATE_PDFA 353 #endif // SK_PDF_GENERATE_PDFA
356 354
357 #undef SKPDF_STRING 355 #undef SKPDF_STRING
358 #undef SKPDF_STRING_IMPL 356 #undef SKPDF_STRING_IMPL
359 357
OLDNEW
« no previous file with comments | « src/pdf/SkPDFDocument.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698