From 5303068dd6c0e063ef9e74ca61af6b02e3f2015d Mon Sep 17 00:00:00 2001 From: John Whitington Date: Mon, 18 Dec 2017 19:44:02 +0000 Subject: [PATCH] Beginning implementation of -pad-with --- cpdf.ml | 55 ++++++++++++++++++++++++++++---------------------- cpdf.mli | 4 ++-- cpdfcommand.ml | 29 +++++++++++++++++++++----- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/cpdf.ml b/cpdf.ml index ce48d7c..9b68401 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -2063,38 +2063,45 @@ let rec insert_after_many_changes isbefore padsize offset range = function let print_changes = List.iter (fun (f, t) -> Printf.printf "%i --> %i\n" f t) -let pad range pdf isbefore = - let i = if isbefore then 1 else 0 in - let pages = Pdfpage.pages_of_pagetree pdf in - let blankpages = - map - (fun n -> - {Pdfpage.content = []; - Pdfpage.mediabox = (select (n + i) pages).Pdfpage.mediabox; - Pdfpage.resources = Pdf.Dictionary []; - Pdfpage.rotate = (select (n + i) pages).Pdfpage.rotate; - Pdfpage.rest = (select (n + i) pages).Pdfpage.rest}) - range - in - let pages' = insert_after_many pages (combine range blankpages) in - let changes = - insert_after_many_changes - isbefore 1 0 (List.map (fun x -> x + i) range) (ilist 1 (length pages)) - in - (*print_changes changes;*) - Pdfpage.change_pages ~changes true pdf pages' +let pad_with_pdf range pdf isbefore padfile = + (* 1. Split the input pdf around the range, taking account of isbefore *) + (* 2. Build a merge after "a p b p c p" or before "p a p b p c" *) + pdf -let padafter range pdf = +let pad padwith range pdf isbefore = + match padwith with + Some padfile -> pad_with_pdf range pdf isbefore padfile + | None -> + let i = if isbefore then 1 else 0 in + let pages = Pdfpage.pages_of_pagetree pdf in + let blankpages = + map + (fun n -> + {Pdfpage.content = []; + Pdfpage.mediabox = (select (n + i) pages).Pdfpage.mediabox; + Pdfpage.resources = Pdf.Dictionary []; + Pdfpage.rotate = (select (n + i) pages).Pdfpage.rotate; + Pdfpage.rest = (select (n + i) pages).Pdfpage.rest}) + range + in + let pages' = insert_after_many pages (combine range blankpages) in + let changes = + insert_after_many_changes + isbefore 1 0 (List.map (fun x -> x + i) range) (ilist 1 (length pages)) + in + Pdfpage.change_pages ~changes true pdf pages' + +let padafter ?padwith range pdf = let isinpdf n = mem n (ilist 1 (Pdfpage.endpage pdf)) in if not (fold_left ( && ) true (map isinpdf range)) then raise (Failure "padafter: range contains pages not present in pdf"); - pad range pdf false + pad padwith range pdf false -let padbefore range pdf = +let padbefore ?padwith range pdf = let isinpdf n = mem n (ilist 1 (Pdfpage.endpage pdf)) in if not (fold_left ( && ) true (map isinpdf range)) then raise (Failure "padbefore: range contains pages not present in pdf"); - pad (map pred range) pdf true + pad padwith (map pred range) pdf true let padmultiple n pdf = let pages = Pdfpage.pages_of_pagetree pdf in diff --git a/cpdf.mli b/cpdf.mli index 4c04141..3eec02b 100644 --- a/cpdf.mli +++ b/cpdf.mli @@ -364,10 +364,10 @@ val scale_contents : ?fast:bool -> position -> float -> Pdf.t -> int list -> Pdf (** {2 Padding} *) (** Put blank pages before the given page numbers *) -val padbefore : int list -> Pdf.t -> Pdf.t +val padbefore : ?padwith:Pdf.t -> int list -> Pdf.t -> Pdf.t (** Put blank pages after the given page numbers *) -val padafter : int list -> Pdf.t -> Pdf.t +val padafter : ?padwith:Pdf.t -> int list -> Pdf.t -> Pdf.t (** Pad to a multiple of n pages *) val padmultiple : int -> Pdf.t -> Pdf.t diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 3d023c1..4a3fe67 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -381,7 +381,8 @@ type args = mutable creator : string option; mutable producer : string option; mutable embedfonts : bool; - mutable extract_text_font_size : float option} + mutable extract_text_font_size : float option; + mutable padwith : string option} let args = {op = None; @@ -465,7 +466,8 @@ let args = producer = None; creator = None; embedfonts = true; - extract_text_font_size = None} + extract_text_font_size = None; + padwith = None} let reset_arguments () = args.op <- None; @@ -546,7 +548,8 @@ let reset_arguments () = args.embedfonts <- true; args.creator <- None; args.producer <- None; - args.extract_text_font_size <- None + args.extract_text_font_size <- None; + args.padwith <- None (* Do not reset original_filename or cpdflin or was_encrypted or * was_decrypted_with_owner or recrypt, since we want these to work across ANDs. *) @@ -1378,6 +1381,9 @@ let setpadevery i = else error "PadEvery: must be > 0" +let setpadwith filename = + args.padwith <- Some filename + let setpadmultiple i = args.op <- Some (PadMultiple i) @@ -1874,6 +1880,9 @@ and specs = ("-pad-every", Arg.Int setpadevery, " Add a blank page after every n pages"); + ("-pad-with", + Arg.String setpadwith, + " Use a given PDF instead of a blank page"); ("-pad-multiple", Arg.Int setpadmultiple, " Pad the document to a multiple of n pages"); @@ -3756,11 +3765,21 @@ let go () = | Some PadBefore -> let pdf = get_single_pdf args.op false in let range = parse_pagespec pdf (get_pagespec ()) in - write_pdf false (Cpdf.padbefore range pdf) + let padwith = + match args.padwith with + None -> None + | Some filename -> Some (pdfread_pdf_of_file None None filename) + in + write_pdf false (Cpdf.padbefore ?padwith range pdf) | Some PadAfter -> let pdf = get_single_pdf args.op false in let range = parse_pagespec pdf (get_pagespec ()) in - write_pdf false (Cpdf.padafter range pdf) + let padwith = + match args.padwith with + None -> None + | Some filename -> Some (pdfread_pdf_of_file None None filename) + in + write_pdf false (Cpdf.padafter ?padwith range pdf) | Some (PadEvery n) -> let pdf = get_single_pdf args.op false in let range =