From 645be7b3421f66b818536a0170682e32e3a64601 Mon Sep 17 00:00:00 2001 From: John Whitington Date: Sun, 28 May 2017 19:19:17 +0100 Subject: [PATCH] More efficient bookmark code --- cpdf.ml | 21 ++++++++++++++------- cpdfcommand.ml | 18 ++++++++++-------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/cpdf.ml b/cpdf.ml index 7d82719..8e64351 100644 --- a/cpdf.ml +++ b/cpdf.ml @@ -932,15 +932,19 @@ let read_lines input = (* Verify a list of bookmarks. Positive jumps of > 1 not allowed, no numbers smaller than 0. *) -let rec verify_bookmarks pdf lastlevel endpage = function +let rec verify_bookmarks pdf lastlevel refnums endpage = function | [] -> true | {Pdfmarks.level = level; Pdfmarks.target = target}::more -> - let page = Pdfpage.pagenumber_of_target pdf target in + let page = Pdfpage.pagenumber_of_target pdf ~refnums target in level < lastlevel + 2 && level >= 0 && page <= endpage && page >= 0 && - verify_bookmarks pdf level endpage more + verify_bookmarks pdf level refnums endpage more + +let verify_bookmarks pdf lastlevel endpage marks = + let refnums = Pdf.page_reference_numbers pdf in + verify_bookmarks pdf lastlevel refnums endpage marks (* Parse a line of the bookmarks file. *) @@ -1186,11 +1190,12 @@ let list_bookmarks encoding range pdf output = | Raw -> s in let bookmarks = Pdfmarks.read_bookmarks pdf in + let refnums = Pdf.page_reference_numbers pdf in let inrange = keep (function x -> x.Pdfmarks.target = Pdfdest.NullDestination || - mem (Pdfpage.pagenumber_of_target pdf x.Pdfmarks.target) range) bookmarks + mem (Pdfpage.pagenumber_of_target ~refnums pdf x.Pdfmarks.target) range) bookmarks in iter (function mark -> @@ -1198,7 +1203,7 @@ let list_bookmarks encoding range pdf output = (Printf.sprintf "%i \"%s\" %i %s\n" mark.Pdfmarks.level (process_string mark.Pdfmarks.text) - (Pdfpage.pagenumber_of_target pdf mark.Pdfmarks.target) + (Pdfpage.pagenumber_of_target ~refnums pdf mark.Pdfmarks.target) (if mark.Pdfmarks.isopen then "open" else ""))) inrange @@ -1223,7 +1228,8 @@ let remove_unsafe_characters s = | chars -> implode chars let get_bookmark_name pdf marks splitlevel n _ = - match keep (function m -> n = Pdfpage.pagenumber_of_target pdf m.Pdfmarks.target && m.Pdfmarks.level <= splitlevel) marks with + let refnums = Pdf.page_reference_numbers pdf in + match keep (function m -> n = Pdfpage.pagenumber_of_target ~refnums pdf m.Pdfmarks.target && m.Pdfmarks.level <= splitlevel) marks with | {Pdfmarks.text = title}::_ -> remove_unsafe_characters title | _ -> "" @@ -1267,9 +1273,10 @@ let stem s = (* Return list, in order, a *set* of page numbers of bookmarks at a given level *) let bookmark_pages level pdf = + let refnums = Pdf.page_reference_numbers pdf in setify_preserving_order (option_map - (function l when l.Pdfmarks.level = level -> Some (Pdfpage.pagenumber_of_target pdf l.Pdfmarks.target) | _ -> None) + (function l when l.Pdfmarks.level = level -> Some (Pdfpage.pagenumber_of_target ~refnums pdf l.Pdfmarks.target) | _ -> None) (Pdfmarks.read_bookmarks pdf)) (* Called from cpdflib.ml - different from above *) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 97982cf..3e03d4f 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -2340,7 +2340,8 @@ let remove_unsafe_characters s = | chars -> implode chars let get_bookmark_name pdf marks splitlevel n _ = - match keep (function m -> n = Pdfpage.pagenumber_of_target pdf m.Pdfmarks.target && m.Pdfmarks.level <= splitlevel) marks with + let refnums = Pdf.page_reference_numbers pdf in + match keep (function m -> n = Pdfpage.pagenumber_of_target ~refnums pdf m.Pdfmarks.target && m.Pdfmarks.level <= splitlevel) marks with | {Pdfmarks.text = title}::_ -> remove_unsafe_characters title | _ -> "" @@ -2406,13 +2407,14 @@ let fast_write_split_pdfs (* Return list, in order, a *set* of page numbers of bookmarks at a given level *) let bookmark_pages level pdf = - setify_preserving_order - (option_map - (function - l when l.Pdfmarks.level = level -> - Some (Pdfpage.pagenumber_of_target pdf l.Pdfmarks.target) - | _ -> None) - (Pdfmarks.read_bookmarks pdf)) + let refnums = Pdf.page_reference_numbers pdf in + setify_preserving_order + (option_map + (function + l when l.Pdfmarks.level = level -> + Some (Pdfpage.pagenumber_of_target ~refnums pdf l.Pdfmarks.target) + | _ -> None) + (Pdfmarks.read_bookmarks pdf)) let split_at_bookmarks enc original_filename ~squeeze nobble level spec pdf