diff --git a/cpdftoc.ml b/cpdftoc.ml index cf2e56c..c7f309b 100644 --- a/cpdftoc.ml +++ b/cpdftoc.ml @@ -25,7 +25,7 @@ let of_pdfdocencoding f t = of_utf8 f (Pdftext.utf8_of_pdfdocstring t) (* Typeset a table of contents with given font, font size and title. Mediabox - (and CropBox) copied from first page of existing PDF. Margin of 50pts inside + (and CropBox) copied from first page of existing PDF. Margin of 10% inside CropBox. Font size of title twice body font size. Null page labels added for TOC, others bumped up and so preserved. *) let typeset_table_of_contents ~font ~fontsize ~title ~bookmark pdf = @@ -34,33 +34,51 @@ let typeset_table_of_contents ~font ~fontsize ~title ~bookmark pdf = let f, fs = (Pdftext.StandardFont (font, Pdftext.WinAnsiEncoding), fontsize) in let big = (Pdftext.StandardFont (font, Pdftext.WinAnsiEncoding), fontsize *. 2.) in let firstpage = hd (Pdfpage.pages_of_pagetree pdf) in - let firstpage_papersize, pmaxx, pmaxy, margin = + let width, firstpage_papersize, pmaxx, pmaxy, margin = let width, height, xmax, ymax = match Pdf.parse_rectangle firstpage.Pdfpage.mediabox with xmin, ymin, xmax, ymax -> xmax -. xmin, ymax -. ymin, xmax, ymax in - Pdfpaper.make Pdfunits.PdfPoint width height, xmax, ymax, fmin width height *. 0.1 + width, Pdfpaper.make Pdfunits.PdfPoint width height, xmax, ymax, fmin width height *. 0.1 in let firstpage_cropbox = match Pdf.lookup_direct pdf "/CropBox" firstpage.Pdfpage.rest with | Some r -> Some (Pdf.parse_rectangle r) | None -> None in + let width = + match firstpage_cropbox with + | Some (xmin, _, xmax, _) -> xmax -. xmin + | None -> width + in let labels = Pdfpagelabels.read pdf in let lines = let refnums = Pdf.page_reference_numbers pdf in let fastrefnums = hashtable_of_dictionary (combine refnums (indx refnums)) in map (fun mark -> + let indent = float mark.Pdfmarks.level *. fontsize *. 2. in + let text = of_pdfdocencoding f mark.Pdfmarks.text in let label = - let pnum = Pdfpage.pagenumber_of_target ~fastrefnums pdf mark.Pdfmarks.target in - try Pdfpagelabels.pagelabeltext_of_pagenumber pnum labels with Not_found -> string_of_int pnum + let pde = + let pnum = Pdfpage.pagenumber_of_target ~fastrefnums pdf mark.Pdfmarks.target in + try Pdfpagelabels.pagelabeltext_of_pagenumber pnum labels with Not_found -> string_of_int pnum + in + of_pdfdocencoding f pde + in + let widths = Cpdftype.font_widths f fontsize in + let space = + width + -. margin *. 2. + -. Cpdftype.width_of_string widths text + -. Cpdftype.width_of_string widths label + -. indent in [Cpdftype.BeginDest mark.Pdfmarks.target; - Cpdftype.HGlue {Cpdftype.glen = float mark.Pdfmarks.level *. fontsize *. 2.; Cpdftype.gstretch = 0.}; - Cpdftype.Text (of_pdfdocencoding f mark.Pdfmarks.text); - Cpdftype.HGlue {Cpdftype.glen = 100.; Cpdftype.gstretch = 0.}; - Cpdftype.Text (of_pdfdocencoding f label); + Cpdftype.HGlue {Cpdftype.glen = indent; Cpdftype.gstretch = 0.}; + Cpdftype.Text text; + Cpdftype.HGlue {Cpdftype.glen = space; Cpdftype.gstretch = 0.}; + Cpdftype.Text label; Cpdftype.EndDest; Cpdftype.NewLine]) (Pdfmarks.read_bookmarks pdf) diff --git a/cpdftype.ml b/cpdftype.ml index 3c574d5..889cb10 100644 --- a/cpdftype.ml +++ b/cpdftype.ml @@ -1,6 +1,9 @@ (* A typesetter for cpdf. A list of elements is manipulated zero or more times to lay it out, paginate it, and so on. It is then typeset to produce a list - of pages *) + of pages. + + For now, this is just an experiment for -table-of-contents and -typeset. To + be continued... *) open Pdfutil (* Glue *) diff --git a/cpdftype.mli b/cpdftype.mli index b35c322..ed5c03f 100644 --- a/cpdftype.mli +++ b/cpdftype.mli @@ -16,4 +16,8 @@ type t = element list val to_string : t -> string +val font_widths : Pdftext.font -> float -> float array + +val width_of_string : float array -> char list -> float + val typeset : float -> float -> float -> float -> Pdfpaper.t -> Pdf.t -> t -> Pdfpage.t list