diff --git a/cpdfcommand.ml b/cpdfcommand.ml index ba98cf1..b4ae63e 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -192,6 +192,7 @@ type op = | ExtractText | OpenAtPage of string | OpenAtPageFit of string + | OpenAtPageCustom of string | AddPageLabels | RemovePageLabels | PrintPageLabels @@ -319,6 +320,7 @@ let string_of_op = function | ExtractText -> "ExtractText" | OpenAtPage _ -> "OpenAtPage" | OpenAtPageFit _ -> "OpenAtPageFit" + | OpenAtPageCustom _ -> "OpenAtPageCustom" | AddPageLabels -> "AddPageLabels" | RemovePageLabels -> "RemovePageLabels" | PrintPageLabels -> "PrintPageLabels" @@ -822,7 +824,7 @@ let banned banlist = function | DumpAttachedFiles | RemoveMetadata | EmbedMissingFonts | BookmarksOpenToLevel _ | CreatePDF | SetPageMode _ | SetNonFullScreenPageMode _ | HideToolbar _ | HideMenubar _ | HideWindowUI _ | FitWindow _ | CenterWindow _ | DisplayDocTitle _ - | RemoveId | OpenAtPageFit _ | OpenAtPage _ | SetPageLayout _ + | RemoveId | OpenAtPageFit _ | OpenAtPage _ | OpenAtPageCustom _ | SetPageLayout _ | ShowBoxes | TrimMarks | CreateMetadata | SetMetadataDate _ | SetVersion _ | SetAuthor _|SetTitle _|SetSubject _|SetKeywords _|SetCreate _ | SetModify _|SetCreator _|SetProducer _|RemoveDictEntry _ | ReplaceDictEntry _ | PrintDictEntry _ | SetMetadata _ @@ -1566,6 +1568,10 @@ let setopenatpagefit n = detect_duplicate_op (OpenAtPageFit n); args.op <- Some (OpenAtPageFit n) +let setopenatpagecustom n = + detect_duplicate_op (OpenAtPageCustom n); + args.op <- Some (OpenAtPageCustom n) + let setlabelstyle s = let style = match s with @@ -2564,6 +2570,9 @@ and specs = ("-open-at-page-fit", Arg.String setopenatpagefit, " Set inital page, scaling to fit"); + ("-open-at-page-custom", + Arg.String setopenatpagecustom, + " Set inital page, with custom scaling"); ("-set-metadata", Arg.String setmetadata, " Set metadata to the contents of a file"); @@ -3822,8 +3831,11 @@ let go () = | Some (OpenAtPageFit str) -> let pdf = get_single_pdf args.op false in let range = parse_pagespec_allow_empty pdf str in - let n = match range with [x] -> x | _ -> error "open_at_page: range does not specify single page" in + let n = match range with [x] -> x | _ -> error "open_at_page_fit: range does not specify single page" in write_pdf false (Cpdfmetadata.set_open_action pdf true n) + | Some (OpenAtPageCustom dest) -> + let pdf = get_single_pdf args.op false in + write_pdf false (Cpdfmetadata.set_open_action ~dest pdf true 1) | Some (SetMetadata metadata_file) -> write_pdf false (Cpdfmetadata.set_metadata args.keepversion metadata_file (get_single_pdf args.op false)) | Some (SetVersion v) -> diff --git a/cpdfmanual.tex b/cpdfmanual.tex index 86e7615..ed97bd6 100644 --- a/cpdfmanual.tex +++ b/cpdfmanual.tex @@ -12,6 +12,7 @@ %Document Topleft2 etc. %Test new camlpdf unit conversions %Document -non-full-screen-page-mode +%Documnet -open-at-page-custom \documentclass{book} % Edit here to produce cpdfmanual.pdf, cpdflibmanual.pdf, pycpdfmanual.pdf, % dotnetcpdflibmanual.pdf, jcpdflibmanual.pdf jscpdflibmanual.pdf etc. diff --git a/cpdfmetadata.ml b/cpdfmetadata.ml index 564b679..030dae2 100644 --- a/cpdfmetadata.ml +++ b/cpdfmetadata.ml @@ -682,16 +682,30 @@ let set_non_full_screen_page_mode pdf s = | _ -> error "Unknown non full screen page mode" (* Set open action *) -let set_open_action pdf fit pagenumber = +let set_open_action pdf ?dest 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] + match dest with + | Some s -> + begin match Pdfread.parse_single_object s with + | Pdf.Array (Pdf.Integer pagenum::more) -> + begin try + let pageobjectnumber = select pagenum (Pdf.page_reference_numbers pdf) in + Pdf.Array (Pdf.Indirect pageobjectnumber::more) + with + _ -> raise (Pdf.PDFError "bad page number in custom destination") + end + | _ | exception _ -> + raise (Pdf.PDFError "Bad destination syntax") + end + | None -> + 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")] diff --git a/cpdfmetadata.mli b/cpdfmetadata.mli index cb778bf..8084a30 100644 --- a/cpdfmetadata.mli +++ b/cpdfmetadata.mli @@ -39,7 +39,7 @@ val set_page_mode : Pdf.t -> string -> Pdf.t val set_non_full_screen_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 +val set_open_action : Pdf.t -> ?dest:string -> bool -> int -> Pdf.t (** Set the PDF version number *) val set_version : int -> Pdf.t -> unit