From f00a9c5b048be6fe3b58533ec442b3aca9337edd Mon Sep 17 00:00:00 2001 From: John Whitington Date: Fri, 18 Apr 2014 15:33:15 +0100 Subject: [PATCH] Fixed StampOn / StampUnder support for retaining bookmarks. --- cpdf.ml | 38 ++++++++++++++++++++++++++++++++++++-- cpdfcommand.ml | 10 ++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/cpdf.ml b/cpdf.ml index fab39fc..4be3b77 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -1050,8 +1050,34 @@ let do_stamp fast scale_to_fit isover pdf o u opdf = Pdfpage.resources = combine_pdf_resources pdf u.Pdfpage.resources o.Pdfpage.resources} +(* Alter bookmark destinations given a hash table of (old page reference + * number, new page reference number) pairings *) +let change_destination t = function + Pdfdest.XYZ (Pdfdest.PageObject p, a, b, c) -> + Pdfdest.XYZ (Pdfdest.PageObject (Hashtbl.find t p), a, b, c) + | Pdfdest.Fit (Pdfdest.PageObject p) -> + Pdfdest.Fit (Pdfdest.PageObject (Hashtbl.find t p)) + | Pdfdest.FitH (Pdfdest.PageObject p, x) -> + Pdfdest.FitH (Pdfdest.PageObject (Hashtbl.find t p), x) + | Pdfdest.FitV (Pdfdest.PageObject p, x) -> + Pdfdest.FitV (Pdfdest.PageObject (Hashtbl.find t p), x) + | Pdfdest.FitR (Pdfdest.PageObject p, a, b, c, d) -> + Pdfdest.FitR (Pdfdest.PageObject (Hashtbl.find t p), a, b, c, d) + | Pdfdest.FitB (Pdfdest.PageObject p) -> + Pdfdest.Fit (Pdfdest.PageObject (Hashtbl.find t p)) + | Pdfdest.FitBH (Pdfdest.PageObject p, x) -> + Pdfdest.FitBH (Pdfdest.PageObject (Hashtbl.find t p), x) + | Pdfdest.FitBV (Pdfdest.PageObject p, x) -> + Pdfdest.FitBV (Pdfdest.PageObject (Hashtbl.find t p), x) + | x -> x + +let change_bookmark t m = + {m with Pdfmarks.target = + try change_destination t m.Pdfmarks.target with Not_found -> m.Pdfmarks.target} + let stamp (fast : bool) scale_to_fit isover range over pdf = let marks = Pdfmarks.read_bookmarks pdf in + let marks_refnumbers = Pdf.page_reference_numbers pdf in let pdf = Pdfmarks.remove_bookmarks pdf in let over = Pdfmarks.remove_bookmarks over in let pageseqs = ilist 1 (Pdfpage.endpage pdf) in @@ -1060,7 +1086,11 @@ let stamp (fast : bool) scale_to_fit isover range over pdf = | [] -> error "empty PDF" | h::_ -> Pdfpage.change_pages true over [h] in - let merged = Pdfmerge.merge_pdfs ~rotations:[Pdfmerge.DNR; Pdfmerge.DNR] false false ["a"; "b"] [pdf; over_firstpage_pdf] [pageseqs; [1]] in + let merged = + Pdfmerge.merge_pdfs + ~rotations:[Pdfmerge.DNR; Pdfmerge.DNR] + false false ["a"; "b"] [pdf; over_firstpage_pdf] [pageseqs; [1]] + in let renamed_pdf = Pdfpage.change_pages true merged (Pdfpage.renumber_pages merged (Pdfpage.pages_of_pagetree merged)) @@ -1079,7 +1109,11 @@ let stamp (fast : bool) scale_to_fit isover range over pdf = pageseqs under_pages in - Pdfmarks.add_bookmarks marks (Pdfpage.change_pages true renamed_pdf new_pages) + let changed = Pdfpage.change_pages true renamed_pdf new_pages in + let new_refnumbers = Pdf.page_reference_numbers changed in + let changetable = hashtable_of_dictionary (List.combine marks_refnumbers new_refnumbers) in + let new_marks = map (change_bookmark changetable) marks in + Pdfmarks.add_bookmarks new_marks changed (* Combine pages from two PDFs. For now, assume equal length. *) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 2c35c0a..a7b83f0 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -3277,7 +3277,7 @@ let go () = in let overpdf = if args.uprightstamp then Cpdf.upright ~fast:args.fast (ilist 1 (Pdfpage.endpage overpdf)) overpdf else overpdf in let pdf = get_single_pdf args.op false in - let marks = Pdfmarks.read_bookmarks pdf in + (*let marks = Pdfmarks.read_bookmarks pdf in*) let range = parse_pagespec pdf (get_pagespec ()) in let pdf = if args.ismulti @@ -3287,7 +3287,9 @@ let go () = else Cpdf.stamp args.fast args.scale_stamp_to_fit true range overpdf pdf in - write_pdf false (Pdfmarks.add_bookmarks marks pdf) + (*let p = Pdfmarks.add_bookmarks marks pdf in + Pdfwrite.debug_whole_pdf p;*) + write_pdf false pdf | Some (StampUnder under) -> let underpdf = match under with @@ -3296,7 +3298,7 @@ let go () = in let underpdf = if args.uprightstamp then Cpdf.upright ~fast:args.fast (ilist 1 (Pdfpage.endpage underpdf)) underpdf else underpdf in let pdf = get_single_pdf args.op false in - let marks = Pdfmarks.read_bookmarks pdf in + (*let marks = Pdfmarks.read_bookmarks pdf in*) let range = parse_pagespec pdf (get_pagespec ()) in let pdf = if args.ismulti @@ -3305,7 +3307,7 @@ let go () = Cpdf.combine_pages args.fast pdf underpdf true true false else Cpdf.stamp args.fast args.scale_stamp_to_fit false range underpdf pdf in - write_pdf false (Pdfmarks.add_bookmarks marks pdf) + write_pdf false pdf (*(Pdfmarks.add_bookmarks marks pdf)*) | Some (CombinePages over) -> write_pdf false (Cpdf.combine_pages args.fast (get_single_pdf args.op false) (pdfread_pdf_of_file None None over) false false true)