Fixed -stamp-on/-stamp-under with positions

This commit is contained in:
John Whitington 2014-10-06 14:32:53 +01:00
parent 21ce677313
commit a4f9d0322f
5 changed files with 257 additions and 234 deletions

423
cpdf.ml
View File

@ -1233,156 +1233,7 @@ let list_bookmarks encoding range pdf output =
(if mark.Pdfmarks.isopen then "open" else ""))) (if mark.Pdfmarks.isopen then "open" else "")))
inrange inrange
(* \section{Stamping files} *)
(* o is the stamp, u is the main pdf page *) (* o is the stamp, u is the main pdf page *)
let do_stamp fast scale_to_fit isover pdf o u opdf =
(* Scale page stamp o to fit page u *)
let o =
if scale_to_fit then
let sxmin, symin, sxmax, symax =
Pdf.parse_rectangle
(match Pdf.lookup_direct pdf "/CropBox" o.Pdfpage.rest with | Some r -> r | None -> o.Pdfpage.mediabox)
in let txmin, tymin, txmax, tymax =
Pdf.parse_rectangle
(match Pdf.lookup_direct pdf "/CropBox" u.Pdfpage.rest with | Some r -> r | None -> u.Pdfpage.mediabox)
in
let xmag = (txmax -. txmin) /. (sxmax -. sxmin)
in let ymag = (tymax -. tymin) /. (symax -. symin) in
let scale =
if xmag < 0.999 && ymag < 0.999 then
if xmag > ymag then xmag else ymag
else if xmag >= 1.001 && ymag >= 1.001 then
if xmag > ymag then ymag else xmag
else if xmag >= 1.001 then ymag
else xmag
in
let dx = txmin +. ((txmax -. txmin) -. (sxmax -. sxmin) *. scale) /. 2.
in let dy = tymin +. ((tymax -. tymin) -. (symax -. symin) *. scale) /. 2. in
let scale_op =
Pdfops.Op_cm
(Pdftransform.matrix_of_transform
[Pdftransform.Translate (dx, dy);
Pdftransform.Scale ((sxmin, symin), scale, scale)])
in
Pdfpage.prepend_operators opdf [scale_op] ~fast o
else
o
in
{u with
Pdfpage.content =
(if isover then ( @ ) else ( @@ ))
[protect_removeme pdf u.Pdfpage.resources u.Pdfpage.content]
[protect_removeme pdf o.Pdfpage.resources o.Pdfpage.content];
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
let over_firstpage_pdf =
match Pdfpage.pages_of_pagetree over with
| [] -> 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 renamed_pdf =
Pdfpage.change_pages true
merged (Pdfpage.renumber_pages merged (Pdfpage.pages_of_pagetree merged))
in
let renamed_pages = Pdfpage.pages_of_pagetree renamed_pdf in
let under_pages, over_page =
all_but_last renamed_pages, last renamed_pages
in
let new_pages =
map2
(fun pageseq under_page ->
do_stamp fast scale_to_fit isover renamed_pdf
(if mem pageseq range then over_page else
Pdfpage.blankpage Pdfpaper.a4)
under_page over)
pageseqs
under_pages
in
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. *)
(* If [over] has more pages than [under], chop the excess. If the converse, pad
[over] to the same length *)
let equalize_pages under over =
let length_under = Pdfpage.endpage under
in let length_over = Pdfpage.endpage over
in
if length_over > length_under then
under,
(Pdfpage.change_pages true over (take (Pdfpage.pages_of_pagetree over) length_under))
else if length_under > length_over then
under,
Pdfpage.change_pages true
over
(Pdfpage.pages_of_pagetree over @
(many (Pdfpage.blankpage Pdfpaper.a4) (length_under - length_over)))
else
under, over
let combine_pages (fast : bool) under over scaletofit swap equalize =
let marks_under = Pdfmarks.read_bookmarks under in
let marks_over = Pdfmarks.read_bookmarks over in
let under, over = if equalize then equalize_pages under over else under, over in
let under_length = Pdfpage.endpage under
in let over_length = Pdfpage.endpage over in
if under_length <> over_length then raise (Pdf.PDFError "combine_pages: not of equal length") else
let pageseqs_under = ilist 1 (Pdfpage.endpage under)
in let pageseqs_over = ilist 1 (Pdfpage.endpage over) in
let merged =
Pdfmerge.merge_pdfs ~rotations: [Pdfmerge.DNR; Pdfmerge.DNR] false false ["a"; "b"] [under; over] [pageseqs_under; pageseqs_over] in
let renamed_pdf =
Pdfpage.change_pages true
merged (Pdfpage.renumber_pages merged (Pdfpage.pages_of_pagetree merged))
in
let under_pages, over_pages =
cleave (Pdfpage.pages_of_pagetree renamed_pdf) under_length
in
let new_pages =
map2 (fun o u -> do_stamp fast scaletofit (not swap) renamed_pdf o u over) over_pages under_pages
in
Pdfmarks.add_bookmarks (marks_under @ marks_over) (Pdfpage.change_pages true renamed_pdf new_pages)
(* \section{Split at bookmarks} *) (* \section{Split at bookmarks} *)
@ -1627,56 +1478,6 @@ let print_fonts pdf =
flprint flprint
(fold_left ( ^ ) "" (map string_of_font (list_fonts pdf))) (fold_left ( ^ ) "" (map string_of_font (list_fonts pdf)))
(* \section{Nobbling for Demo Version} *)
let nobble_page pdf _ page =
let minx, miny, maxx, maxy =
(* Use cropbox if available *)
Pdf.parse_rectangle
(match Pdf.lookup_direct pdf "/CropBox" page.Pdfpage.rest with
| Some r -> r
| None -> page.Pdfpage.mediabox)
in
let fontdict =
match Pdf.lookup_direct pdf "/Font" page.Pdfpage.resources with
| None -> Pdf.Dictionary []
| Some d -> d
in
let fontname = Pdf.unique_key "F" fontdict in
let width = maxx -. minx in let height = maxy -. miny in
let scalex =
(width *. 1000.) /. float (Pdfstandard14.textwidth false Pdftext.Helvetica "DEMO")
in
let page' =
let font =
Pdf.Dictionary
[("/Type", Pdf.Name "/Font");
("/Subtype", Pdf.Name "/Type1");
("/BaseFont", Pdf.Name "/Helvetica")]
in let ops =
[Pdfops.Op_BMC "/CPDFSTAMP";
Pdfops.Op_cm
(Pdftransform.matrix_of_transform
[Pdftransform.Translate (minx, miny +. height /. 2.)]);
Pdfops.Op_gs "/gs0";
Pdfops.Op_BT;
Pdfops.Op_Tf (fontname, scalex);
Pdfops.Op_Tj "DEMO";
Pdfops.Op_ET;
Pdfops.Op_EMC]
in
{(Pdfpage.blankpage Pdfpaper.a4) with
Pdfpage.mediabox = page.Pdfpage.mediabox;
Pdfpage.content = [Pdfops.stream_of_ops ops];
Pdfpage.resources =
Pdf.Dictionary
[("/Font", Pdf.Dictionary [(fontname, font)]);
("/ExtGState", Pdf.Dictionary
["/gs0",
Pdf.Dictionary["/Type", Pdf.Name "/ExtGState"; "/ca", Pdf.Real 0.2]]);
]
}
in
do_stamp false false true pdf page' page (Pdf.empty ())
(* \section{Superimpose text, page numbers etc.} *) (* \section{Superimpose text, page numbers etc.} *)
@ -2397,6 +2198,230 @@ let hflip_pdf ?(fast=false) pdf range =
in in
process_pages (flip_page ~fast transform_op pdf) pdf range process_pages (flip_page ~fast transform_op pdf) pdf range
let stamp_shift_of_position sw sh w h p =
let half x = x /. 2. in
match p with
| PosCentre (ox, oy) -> ox -. half sw, oy
| PosLeft (ox, oy) -> ox, oy
| PosRight (ox, oy) -> ox -. sw, oy
| Top o -> half w -. half sw, h -. o -. sh
| TopLeft o -> o, h -. sh -. o
| TopRight o -> w -. sw -. o, h -. sh -. o
| Left o -> o, half h -. half sh
| BottomLeft o -> o, o
| Bottom o -> half w -. half sw, o
| BottomRight o -> w -. sw, o
| Right o -> w -. sw -. o, half h -. half sh
| Diagonal | ReverseDiagonal | Centre -> half w -. half sw, half h -. half sh
let do_stamp fast position scale_to_fit isover pdf o u opdf =
(* Scale page stamp o to fit page u *)
let sxmin, symin, sxmax, symax =
Pdf.parse_rectangle
(match Pdf.lookup_direct pdf "/CropBox" o.Pdfpage.rest with | Some r -> r | None -> o.Pdfpage.mediabox)
in let txmin, tymin, txmax, tymax =
Pdf.parse_rectangle
(match Pdf.lookup_direct pdf "/CropBox" u.Pdfpage.rest with | Some r -> r | None -> u.Pdfpage.mediabox)
in
let o =
if scale_to_fit then
let xmag = (txmax -. txmin) /. (sxmax -. sxmin) in
let ymag = (tymax -. tymin) /. (symax -. symin) in
let scale =
if xmag < 0.999 && ymag < 0.999 then
if xmag > ymag then xmag else ymag
else if xmag >= 1.001 && ymag >= 1.001 then
if xmag > ymag then ymag else xmag
else if xmag >= 1.001 then ymag
else xmag
in
let dx = txmin +. ((txmax -. txmin) -. (sxmax -. sxmin) *. scale) /. 2. in
let dy = tymin +. ((tymax -. tymin) -. (symax -. symin) *. scale) /. 2. in
let scale_op =
Pdfops.Op_cm
(Pdftransform.matrix_of_transform
[Pdftransform.Translate (dx, dy);
Pdftransform.Scale ((sxmin, symin), scale, scale)])
in
Pdfpage.prepend_operators pdf [scale_op] ~fast o
else
let sw = sxmax -. sxmin
and sh = symax -. symin
and w = txmax -. txmin
and h = tymax -. tymin in
let dx, dy = stamp_shift_of_position sw sh w h position in
let translate_op =
Pdfops.Op_cm
(Pdftransform.matrix_of_transform [Pdftransform.Translate (dx, dy)])
in
Pdfpage.prepend_operators pdf [translate_op] ~fast o
in
{u with
Pdfpage.content =
(if isover then ( @ ) else ( @@ ))
[protect_removeme pdf u.Pdfpage.resources u.Pdfpage.content]
[protect_removeme pdf o.Pdfpage.resources o.Pdfpage.content];
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 position fast 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
let over_firstpage_pdf =
match Pdfpage.pages_of_pagetree over with
| [] -> 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 renamed_pdf =
Pdfpage.change_pages true
merged (Pdfpage.renumber_pages merged (Pdfpage.pages_of_pagetree merged))
in
let renamed_pages = Pdfpage.pages_of_pagetree renamed_pdf in
let under_pages, over_page =
all_but_last renamed_pages, last renamed_pages
in
let new_pages =
map2
(fun pageseq under_page ->
do_stamp fast position scale_to_fit isover renamed_pdf
(if mem pageseq range then over_page else
Pdfpage.blankpage Pdfpaper.a4)
under_page over)
pageseqs
under_pages
in
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. *)
(* If [over] has more pages than [under], chop the excess. If the converse, pad
[over] to the same length *)
let equalize_pages under over =
let length_under = Pdfpage.endpage under
in let length_over = Pdfpage.endpage over
in
if length_over > length_under then
under,
(Pdfpage.change_pages true over (take (Pdfpage.pages_of_pagetree over) length_under))
else if length_under > length_over then
under,
Pdfpage.change_pages true
over
(Pdfpage.pages_of_pagetree over @
(many (Pdfpage.blankpage Pdfpaper.a4) (length_under - length_over)))
else
under, over
let combine_pages (fast : bool) under over scaletofit swap equalize =
let marks_under = Pdfmarks.read_bookmarks under in
let marks_over = Pdfmarks.read_bookmarks over in
let under, over = if equalize then equalize_pages under over else under, over in
let under_length = Pdfpage.endpage under
in let over_length = Pdfpage.endpage over in
if under_length <> over_length then raise (Pdf.PDFError "combine_pages: not of equal length") else
let pageseqs_under = ilist 1 (Pdfpage.endpage under)
in let pageseqs_over = ilist 1 (Pdfpage.endpage over) in
let merged =
Pdfmerge.merge_pdfs ~rotations: [Pdfmerge.DNR; Pdfmerge.DNR] false false ["a"; "b"] [under; over] [pageseqs_under; pageseqs_over] in
let renamed_pdf =
Pdfpage.change_pages true
merged (Pdfpage.renumber_pages merged (Pdfpage.pages_of_pagetree merged))
in
let under_pages, over_pages =
cleave (Pdfpage.pages_of_pagetree renamed_pdf) under_length
in
let new_pages =
map2 (fun o u -> do_stamp fast (BottomLeft 0.) scaletofit (not swap) renamed_pdf o u over) over_pages under_pages
in
Pdfmarks.add_bookmarks (marks_under @ marks_over) (Pdfpage.change_pages true renamed_pdf new_pages)
let nobble_page pdf _ page =
let minx, miny, maxx, maxy =
(* Use cropbox if available *)
Pdf.parse_rectangle
(match Pdf.lookup_direct pdf "/CropBox" page.Pdfpage.rest with
| Some r -> r
| None -> page.Pdfpage.mediabox)
in
let fontdict =
match Pdf.lookup_direct pdf "/Font" page.Pdfpage.resources with
| None -> Pdf.Dictionary []
| Some d -> d
in
let fontname = Pdf.unique_key "F" fontdict in
let width = maxx -. minx in let height = maxy -. miny in
let scalex =
(width *. 1000.) /. float (Pdfstandard14.textwidth false Pdftext.Helvetica "DEMO")
in
let page' =
let font =
Pdf.Dictionary
[("/Type", Pdf.Name "/Font");
("/Subtype", Pdf.Name "/Type1");
("/BaseFont", Pdf.Name "/Helvetica")]
in let ops =
[Pdfops.Op_BMC "/CPDFSTAMP";
Pdfops.Op_cm
(Pdftransform.matrix_of_transform
[Pdftransform.Translate (minx, miny +. height /. 2.)]);
Pdfops.Op_gs "/gs0";
Pdfops.Op_BT;
Pdfops.Op_Tf (fontname, scalex);
Pdfops.Op_Tj "DEMO";
Pdfops.Op_ET;
Pdfops.Op_EMC]
in
{(Pdfpage.blankpage Pdfpaper.a4) with
Pdfpage.mediabox = page.Pdfpage.mediabox;
Pdfpage.content = [Pdfops.stream_of_ops ops];
Pdfpage.resources =
Pdf.Dictionary
[("/Font", Pdf.Dictionary [(fontname, font)]);
("/ExtGState", Pdf.Dictionary
["/gs0",
Pdf.Dictionary["/Type", Pdf.Name "/ExtGState"; "/ca", Pdf.Real 0.2]]);
]
}
in
do_stamp false (BottomLeft 0.) false true pdf page' page (Pdf.empty ())
(* \section{Set media box} *) (* \section{Set media box} *)
let set_mediabox x y w h pdf range = let set_mediabox x y w h pdf range =
let crop_page _ page = let crop_page _ page =

View File

@ -14,6 +14,23 @@ exception HardError of string
(** Two exceptions recommended for use with the library, though currently not (** Two exceptions recommended for use with the library, though currently not
raised by any function in this module. Cpdfcommand uses them extensively. *) raised by any function in this module. Cpdfcommand uses them extensively. *)
(** Possible positions for adding text and other uses. See cpdfmanual.pdf *)
type position =
| PosCentre of float * float
| PosLeft of float * float
| PosRight of float * float
| Top of float
| TopLeft of float
| TopRight of float
| Left of float
| BottomLeft of float
| Bottom of float
| BottomRight of float
| Right of float
| Diagonal
| ReverseDiagonal
| Centre
(** {2 Debug} *) (** {2 Debug} *)
(** Debug: Print out a PDF in readable form to the terminal *) (** Debug: Print out a PDF in readable form to the terminal *)
@ -178,10 +195,10 @@ swapped. If [fast] is true, the PDFs are assumed to be well-formed and no
fixes are done. *) fixes are done. *)
val combine_pages : bool -> Pdf.t -> Pdf.t -> bool -> bool -> bool -> Pdf.t val combine_pages : bool -> Pdf.t -> Pdf.t -> bool -> bool -> bool -> Pdf.t
(** [stamp scale_to_fit fast isover range over pdf] stamps the first page of (** [stamp scale_to_fit position fast isover range over pdf] stamps the first page of
[over] over each page of the PDF. The arguments have the same meaning as in [over] over each page of the PDF. The arguments have the same meaning as in
[combine_pages]. *) [combine_pages]. *)
val stamp : bool -> bool -> bool -> int list -> Pdf.t -> Pdf.t -> Pdf.t val stamp : position -> bool -> bool -> bool -> int list -> Pdf.t -> Pdf.t -> Pdf.t
(** {2 Splitting PDFs} *) (** {2 Splitting PDFs} *)
@ -217,22 +234,6 @@ val list_fonts : Pdf.t -> (int * string * string * string * string) list
(** Expand the string "now" to a PDF date string, ignoring any other string *) (** Expand the string "now" to a PDF date string, ignoring any other string *)
val expand_date : string -> string val expand_date : string -> string
(** Possible positions for adding text and other uses. See cpdfmanual.pdf *)
type position =
| PosCentre of float * float
| PosLeft of float * float
| PosRight of float * float
| Top of float
| TopLeft of float
| TopRight of float
| Left of float
| BottomLeft of float
| Bottom of float
| BottomRight of float
| Right of float
| Diagonal
| ReverseDiagonal
| Centre
(** Produce a debug string of a [position] *) (** Produce a debug string of a [position] *)
val string_of_position : position -> string val string_of_position : position -> string

View File

@ -864,10 +864,13 @@ let setaddbookmarks s =
setop (AddBookmarks s) () setop (AddBookmarks s) ()
let setstampon f = let setstampon f =
setop (StampOn f) () setop (StampOn f) ();
(* Due to an earlier bad decision (default position), we have this nasty hack *)
if args.position = Cpdf.TopLeft 100. then args.position <- Cpdf.BottomLeft 0.
let setstampunder f = let setstampunder f =
setop (StampUnder f) () setop (StampUnder f) ();
if args.position = Cpdf.TopLeft 100. then args.position <- Cpdf.BottomLeft 0.
let setstamponmulti f = let setstamponmulti f =
setop (StampOn f) (); setop (StampOn f) ();
@ -3099,12 +3102,7 @@ let go () =
| Some Split -> | Some Split ->
begin match args.inputs, args.out with begin match args.inputs, args.out with
| [(f, ranges, _, _, _)], File output_spec -> | [(f, ranges, _, _, _)], File output_spec ->
let pdf = get_single_pdf args.op true let pdf = get_single_pdf args.op true in
(*and filename =
match f with
| InFile n -> n
| _ -> ""*)
in
let enc = let enc =
match args.crypt_method with match args.crypt_method with
| "" -> None | "" -> None
@ -3245,7 +3243,6 @@ let go () =
begin match args.inputs with begin match args.inputs with
| [(k, _, _, _, _) as input] -> | [(k, _, _, _, _) as input] ->
let pdf = get_pdf_from_input_kind input args.op k in let pdf = get_pdf_from_input_kind input args.op k in
(* Convert from string to int *)
let topage = let topage =
try try
match args.topage with match args.topage with
@ -3344,7 +3341,6 @@ let go () =
in in
let overpdf = if args.uprightstamp then Cpdf.upright ~fast:args.fast (ilist 1 (Pdfpage.endpage overpdf)) overpdf else overpdf 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 pdf = get_single_pdf args.op false in
(*let marks = Pdfmarks.read_bookmarks pdf in*)
let range = parse_pagespec pdf (get_pagespec ()) in let range = parse_pagespec pdf (get_pagespec ()) in
let pdf = let pdf =
if args.ismulti if args.ismulti
@ -3352,10 +3348,8 @@ let go () =
let overpdf = equalize_pages_extend pdf overpdf in let overpdf = equalize_pages_extend pdf overpdf in
Cpdf.combine_pages args.fast pdf overpdf true false false Cpdf.combine_pages args.fast pdf overpdf true false false
else else
Cpdf.stamp args.fast args.scale_stamp_to_fit true range overpdf pdf Cpdf.stamp args.position args.fast args.scale_stamp_to_fit true range overpdf pdf
in in
(*let p = Pdfmarks.add_bookmarks marks pdf in
Pdfwrite.debug_whole_pdf p;*)
write_pdf false pdf write_pdf false pdf
| Some (StampUnder under) -> | Some (StampUnder under) ->
let underpdf = let underpdf =
@ -3365,16 +3359,16 @@ let go () =
in in
let underpdf = if args.uprightstamp then Cpdf.upright ~fast:args.fast (ilist 1 (Pdfpage.endpage underpdf)) underpdf else underpdf 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 pdf = get_single_pdf args.op false in
(*let marks = Pdfmarks.read_bookmarks pdf in*)
let range = parse_pagespec pdf (get_pagespec ()) in let range = parse_pagespec pdf (get_pagespec ()) in
let pdf = let pdf =
if args.ismulti if args.ismulti
then then
let underpdf = equalize_pages_extend pdf underpdf in let underpdf = equalize_pages_extend pdf underpdf in
Cpdf.combine_pages args.fast pdf underpdf true true false Cpdf.combine_pages args.fast pdf underpdf true true false
else Cpdf.stamp args.fast args.scale_stamp_to_fit false range underpdf pdf else
Cpdf.stamp args.position args.fast args.scale_stamp_to_fit false range underpdf pdf
in in
write_pdf false pdf (*(Pdfmarks.add_bookmarks marks pdf)*) write_pdf false pdf
| Some (CombinePages over) -> | Some (CombinePages over) ->
write_pdf false write_pdf false
(Cpdf.combine_pages args.fast (get_single_pdf args.op false) (pdfread_pdf_of_file None None over) false false true) (Cpdf.combine_pages args.fast (get_single_pdf args.op false) (pdfread_pdf_of_file None None over) false false true)

Binary file not shown.

View File

@ -6,6 +6,7 @@
% Explain page labels in -page-info % Explain page labels in -page-info
% Correct the documentation for -diagonal and -reverse-diagonal % Correct the documentation for -diagonal and -reverse-diagonal
% Explain octal escape sequences in meta fields with -raw % Explain octal escape sequences in meta fields with -raw
% is scale_to_fit in do_stamp documented?
\documentclass[a4paper,makeidx]{memoir} \documentclass[a4paper,makeidx]{memoir}
\usepackage{palatino} \usepackage{palatino}
@ -1160,7 +1161,9 @@ writing to \texttt{out.pdf}. A watermark should go underneath each page:
\small\verb!cpdf -stamp-under topsecret.pdf in.pdf -o out.pdf! \small\verb!cpdf -stamp-under topsecret.pdf in.pdf -o out.pdf!
\end{framed} \end{framed}
\noindent The \texttt{-combine-pages} operation takes two PDF files and stamps each \noindent The position commands in \Sref{position} can be used to locate the stamp more precisely (they are calculated relative to the crop box of the stamp). Or, preprocess the stamp with \texttt{-shift} first.
The \texttt{-combine-pages} operation takes two PDF files and stamps each
page of one over each page of the other. The length of the output is the same page of one over each page of the other. The length of the output is the same
as the length of the ``under'' file. For instance: as the length of the ``under'' file. For instance:
\begin{framed} \begin{framed}