Added support for open actions

This commit is contained in:
John Whitington 2013-10-02 15:29:53 +01:00
parent 3a35095682
commit 71f37228ce
4 changed files with 58 additions and 7 deletions

27
cpdf.ml
View File

@ -827,6 +827,33 @@ let set_page_mode pdf s =
end end
| _ -> error "Unknown page mode" | _ -> error "Unknown page mode"
(* Set open action *)
let set_open_action pdf fit pagenumber =
if pagenumber > Pdfpage.endpage pdf || pagenumber < 0 then
raise (error "set_open_action: invalid page number")
else
let pageobjectnumber = select pagenumber (Pdf.page_reference_numbers pdf) in
let destination =
if fit then
Pdf.Array [Pdf.Indirect pageobjectnumber; Pdf.Name "/Fit"]
else
Pdf.Array [Pdf.Indirect pageobjectnumber; Pdf.Name "/XYZ"; Pdf.Null; Pdf.Null; Pdf.Null]
in
let open_action =
Pdf.Dictionary [("/D", destination); ("/S", Pdf.Name "/GoTo")]
in
match Pdf.lookup_direct pdf "/Root" pdf.Pdf.trailerdict with
| Some catalog ->
let catalog' =
Pdf.add_dict_entry catalog "/OpenAction" open_action
in
let catalognum = Pdf.addobj pdf catalog' in
let trailerdict' =
Pdf.add_dict_entry pdf.Pdf.trailerdict "/Root" (Pdf.Indirect catalognum)
in
{pdf with Pdf.root = catalognum; Pdf.trailerdict = trailerdict'}
| None -> error "bad root"
(* \section{Set viewer preferences} *) (* \section{Set viewer preferences} *)
let set_viewer_preference (key, value, version) pdf = let set_viewer_preference (key, value, version) pdf =
match Pdf.lookup_direct pdf "/Root" pdf.Pdf.trailerdict with match Pdf.lookup_direct pdf "/Root" pdf.Pdf.trailerdict with

View File

@ -105,6 +105,9 @@ val set_page_layout : Pdf.t -> string -> Pdf.t
(** Set the page layout to the given name (sans slash) e.g SinglePage *) (** Set the page layout to the given name (sans slash) e.g SinglePage *)
val set_page_mode : Pdf.t -> string -> Pdf.t val set_page_mode : Pdf.t -> string -> Pdf.t
(** Set the open action. If the boolean is true, /Fit will be used, otherwise /XYZ *)
val set_open_action : Pdf.t -> bool -> int -> Pdf.t
(** Set the PDF version number *) (** Set the PDF version number *)
val set_version : int -> Pdf.t -> unit val set_version : int -> Pdf.t -> unit
@ -248,8 +251,6 @@ val calculate_position :
float * float * float * float -> float * float * float * float ->
orientation -> position -> float * float * float orientation -> position -> float * float * float
(** Call [add_texts metrics linewidth outline fast fontname font bates colour (** Call [add_texts metrics linewidth outline fast fontname font bates colour
position linespacing fontsize underneath text pages orientation position linespacing fontsize underneath text pages orientation
relative_to_cropbox midline_adjust filename pdf]. For details see cpdfmanual.pdf *) relative_to_cropbox midline_adjust filename pdf]. For details see cpdfmanual.pdf *)

View File

@ -1,9 +1,9 @@
(* cpdf command line tools} *) (* cpdf command line tools *)
let demo = false let demo = false
and noncomp = true and noncomp = true
and major_version = 1 and major_version = 1
and minor_version = 7 and minor_version = 8
and version_date = "(7th August 2013)" and version_date = "(unreleased)"
open Pdfutil open Pdfutil
open Pdfio open Pdfio
@ -150,6 +150,8 @@ type op =
| ExtractFontFile | ExtractFontFile
| ExtractText | ExtractText
| PrintLinearization | PrintLinearization
| OpenAtPage of int
| OpenAtPageFit of int
(* Inputs: filename, pagespec. *) (* Inputs: filename, pagespec. *)
type input_kind = type input_kind =
@ -399,7 +401,8 @@ let reset_arguments () =
args.makenewid <- false; args.makenewid <- false;
args.ismulti <- false; args.ismulti <- false;
args.uprightstamp <- false args.uprightstamp <- false
(* We don't reset args.do_ask and args.verbose, because they operate on all parts of the AND-ed command line sent from cpdftk. *) (* We don't reset args.do_ask and args.verbose, because they operate on all
parts of the AND-ed command line sent from cpdftk. *)
let banlist_of_args () = let banlist_of_args () =
let l = ref [] in let l = ref [] in
@ -1178,6 +1181,12 @@ let setstdinowner o =
| (StdIn, x, y, u, _)::t -> args.inputs <- (StdIn, x, y, u, o)::t | (StdIn, x, y, u, _)::t -> args.inputs <- (StdIn, x, y, u, o)::t
| _ -> error "-stdin-user: must follow -stdin" | _ -> error "-stdin-user: must follow -stdin"
let setopenatpage n =
args.op <- Some (OpenAtPage n)
let setopenatpagefit n =
args.op <- Some (OpenAtPageFit n)
(* Parse a control file, make an argv, and then make Arg parse it. *) (* Parse a control file, make an argv, and then make Arg parse it. *)
let rec make_control_argv_and_parse filename = let rec make_control_argv_and_parse filename =
control_args := !control_args @ parse_control_file filename control_args := !control_args @ parse_control_file filename
@ -1539,6 +1548,12 @@ and specs =
("-set-page-mode", ("-set-page-mode",
Arg.String setpagemode, Arg.String setpagemode,
" Set page mode upon document opening"); " Set page mode upon document opening");
("-open-at-page",
Arg.Int setopenatpage,
" Set initial page");
("-open-at-page-fit",
Arg.Int setopenatpagefit,
" Set inital page, scaling to fit");
("-set-metadata", ("-set-metadata",
Arg.String setmetadata, Arg.String setmetadata,
" Set metadata to the contents of a file"); " Set metadata to the contents of a file");
@ -2621,7 +2636,7 @@ let addrectangle (w, h) color position relative_to_cropbox underneath range pdf
in in
Cpdf.process_pages addrectangle_page pdf range Cpdf.process_pages addrectangle_page pdf range
(* \section{Main function} *) (* Main function *)
let go () = let go () =
match args.op with match args.op with
| Some Version -> | Some Version ->
@ -2938,6 +2953,10 @@ let go () =
let version = if args.keepversion then pdf.Pdf.minor else version in let version = if args.keepversion then pdf.Pdf.minor else version in
write_pdf false (Cpdf.set_viewer_preference (key, value, version) pdf) write_pdf false (Cpdf.set_viewer_preference (key, value, version) pdf)
end end
| Some (OpenAtPage n) ->
write_pdf false (Cpdf.set_open_action (get_single_pdf args.op false) false n)
| Some (OpenAtPageFit n) ->
write_pdf false (Cpdf.set_open_action (get_single_pdf args.op true) false n)
| Some (SetMetadata metadata_file) -> | Some (SetMetadata metadata_file) ->
write_pdf false (Cpdf.set_metadata args.keepversion metadata_file (get_single_pdf args.op false)) write_pdf false (Cpdf.set_metadata args.keepversion metadata_file (get_single_pdf args.op false))
| Some (SetVersion v) -> | Some (SetVersion v) ->

View File

@ -1,3 +1,7 @@
%To document for next version:
% Anil's changes to output format of -list-annotations
% The new -open-at-page, -open-at-page-fit options
\documentclass[a4paper,makeidx]{memoir} \documentclass[a4paper,makeidx]{memoir}
\usepackage{palatino} \usepackage{palatino}
\usepackage{microtype} \usepackage{microtype}