diff --git a/cpdftoc.ml b/cpdftoc.ml index e4bb34a..926236c 100644 --- a/cpdftoc.ml +++ b/cpdftoc.ml @@ -14,10 +14,17 @@ let rec real_newline = function | x::r -> x::real_newline r | [] -> [] +let width_table_cache = null_hash () + let rec width_of_runs runs = match runs with | Cpdftype.Font (f, fontsize)::Cpdftype.Text t::more -> - Cpdftype.width_of_string (Cpdftype.font_widths f fontsize) t +. width_of_runs more + let width_table = + match Hashtbl.find width_table_cache (f, fontsize) with + | w -> w + | exception Not_found -> let ws = Cpdftype.font_widths f fontsize in Hashtbl.add width_table_cache (f, fontsize) ws; ws + in + Cpdftype.width_of_string width_table t +. width_of_runs more | [] -> 0. | _ -> failwith "width_of_runs" @@ -44,7 +51,12 @@ let of_pdfdocencoding fontpack fontsize t = let rec shorten_text_inner l t = match rev t with | Cpdftype.Text text::Cpdftype.Font (f, fs)::more -> - if Cpdftype.width_of_string (Cpdftype.font_widths f fs) text > l then + let width_table = + match Hashtbl.find width_table_cache (f, fs) with + | w -> w + | exception Not_found -> let ws = Cpdftype.font_widths f fs in Hashtbl.add width_table_cache (f, fs) ws; ws + in + if Cpdftype.width_of_string width_table text > l then shorten_text_inner l (rev (Cpdftype.Text (all_but_last text)::Cpdftype.Font (f, fs)::more)) else t diff --git a/cpdftype.ml b/cpdftype.ml index 3f9f5ab..af1ad0e 100644 --- a/cpdftype.ml +++ b/cpdftype.ml @@ -5,8 +5,6 @@ For now, this is just an experiment for -table-of-contents and -typeset. To be continued... *) -(* TODO: Move fontpacks into here, and text runs up ourselves, as a preprocessing step or utility function? *) -(* TODO: Precompute widths and store with fonts, for speed *) open Pdfutil (* Main type *)