From 3cbd3595ef8662dad9a27d5963d9327c08efb3fb Mon Sep 17 00:00:00 2001 From: John Whitington Date: Fri, 28 Jun 2019 15:01:28 +0100 Subject: [PATCH] Plumbing for XMP metadata setting --- cpdf.ml | 49 +++++++++++++++++++++++++++++++++++-------------- cpdf.mli | 2 +- cpdfcommand.ml | 9 ++++++++- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/cpdf.ml b/cpdf.ml index 495e3d2..3471763 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -1110,20 +1110,7 @@ let set_viewer_preference (key, value, version) pdf = Pdf.trailerdict = trailerdict'} | None -> error "bad root" -(* \section{Set an entry in the /Info dictionary} *) -let set_pdf_info (key, value, version) pdf = - let infodict = - match Pdf.lookup_direct pdf "/Info" pdf.Pdf.trailerdict with - | Some d -> d - | None -> Pdf.Dictionary [] - in - let infodict' = Pdf.add_dict_entry infodict key value in - let objnum = Pdf.addobj pdf infodict' in - pdf.Pdf.trailerdict <- - Pdf.add_dict_entry pdf.Pdf.trailerdict "/Info" (Pdf.Indirect objnum); - pdf.Pdf.minor <- - max pdf.Pdf.minor version; - pdf + (* \section{Set page layout} *) let set_page_layout pdf s = @@ -1409,6 +1396,40 @@ let print_metadata pdf = Printf.printf "%c" (char_of_int (bget data x)) done +(* Set XMP info *) +let set_pdf_info_xml only_when_present (key, value, version) xmldata pdf = xmldata + +(* \section{Set an entry in the /Info dictionary} *) +let set_pdf_info ?(xmp_also=false) ?(xmp_also_when_present=false) ?(xmp_just_set=false) (key, value, version) pdf = + let infodict = + match Pdf.lookup_direct pdf "/Info" pdf.Pdf.trailerdict with + | Some d -> d + | None -> Pdf.Dictionary [] + in + let infodict' = Pdf.add_dict_entry infodict key value in + let objnum = Pdf.addobj pdf infodict' in + if not xmp_just_set then + begin + pdf.Pdf.trailerdict <- + Pdf.add_dict_entry pdf.Pdf.trailerdict "/Info" (Pdf.Indirect objnum); + pdf.Pdf.minor <- + max pdf.Pdf.minor version + end; + if xmp_also || xmp_also_when_present then + begin match get_metadata pdf with + None -> pdf + | Some xmldata -> + let pdf = + set_metadata_from_bytes + true + (set_pdf_info_xml xmp_also_when_present (key, value, version) xmldata pdf) + pdf + in + pdf + end + else + pdf + (* \section{Print font data} *) let list_font pdf page (name, dict) = let subtype = diff --git a/cpdf.mli b/cpdf.mli index 2bebaa0..df53565 100644 --- a/cpdf.mli +++ b/cpdf.mli @@ -112,7 +112,7 @@ val copy_id : bool -> Pdf.t -> Pdf.t -> Pdf.t (** [set_pdf_info (key, value, version)] sets the entry [key] in the /Info directory, updating the PDF minor version to [version].*) -val set_pdf_info : (string * Pdf.pdfobject * int) -> Pdf.t -> Pdf.t +val set_pdf_info : ?xmp_also:bool -> ?xmp_also_when_present:bool -> ?xmp_just_set:bool -> (string * Pdf.pdfobject * int) -> Pdf.t -> Pdf.t (** [set_pdf_info (key, value, version)] sets the entry [key] in the /ViewerPreferences directory, updating the PDF minor version to [version].*) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index cdd05d4..0585447 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -3691,7 +3691,14 @@ let go () = in let pdf = get_single_pdf args.op false in let version = if args.keepversion then pdf.Pdf.minor else version in - write_pdf false (Cpdf.set_pdf_info (key, value, version) pdf) + write_pdf false + (Cpdf.set_pdf_info + ~xmp_also:args.alsosetxml + ~xmp_also_when_present:args.alsosetxmlwhenpresent + ~xmp_just_set:args.justsetxml + (key, value, version) pdf) + | Some (SetMetadataDate date) -> + failwith "SetMetadataDate unimplemented" | Some ((HideToolbar _ | HideMenubar _ | HideWindowUI _ | FitWindow _ | CenterWindow _ | DisplayDocTitle _) as op) -> begin match args.out with