This commit is contained in:
John Whitington 2021-11-23 14:20:38 -08:00
parent 35d1675553
commit e5074c20a3
2 changed files with 33 additions and 7 deletions

View File

@ -3,7 +3,7 @@ let demo = false
let noncomp = false let noncomp = false
let major_version = 2 let major_version = 2
let minor_version = 5 let minor_version = 5
let version_date = "(devel, 15th Nov 2021)" let version_date = "(devel, 22nd Nov 2021)"
open Pdfutil open Pdfutil
open Pdfio open Pdfio
@ -2953,6 +2953,7 @@ let typeset_table_of_contents pdf =
let marks = Pdfmarks.read_bookmarks pdf in let marks = Pdfmarks.read_bookmarks pdf in
if marks = [] then (Printf.eprintf "No bookmarks, not making table of contents\n%!"; pdf) else if marks = [] then (Printf.eprintf "No bookmarks, not making table of contents\n%!"; pdf) else
let f = (Pdftext.StandardFont (Pdftext.Courier, Pdftext.WinAnsiEncoding), 10.) in let f = (Pdftext.StandardFont (Pdftext.Courier, Pdftext.WinAnsiEncoding), 10.) in
let big = (Pdftext.StandardFont (Pdftext.Courier, Pdftext.WinAnsiEncoding), 20.) in
let firstpage = hd (Pdfpage.pages_of_pagetree pdf) in let firstpage = hd (Pdfpage.pages_of_pagetree pdf) in
let firstpage_papersize = let firstpage_papersize =
let width, height = let width, height =
@ -2971,10 +2972,13 @@ let typeset_table_of_contents pdf =
Cpdftype.NewLine]) Cpdftype.NewLine])
(Pdfmarks.read_bookmarks pdf) (Pdfmarks.read_bookmarks pdf)
in in
print_string (Cpdftype.to_string (flatten lines));
let toc_pages = let toc_pages =
Cpdftype.typeset 50. 50. 50. 50. firstpage_papersize pdf Cpdftype.typeset 50. 50. 50. 50. firstpage_papersize pdf
([Cpdftype.Font f] @ flatten lines) ([Cpdftype.Font big;
Cpdftype.Text "Table of Contents";
Cpdftype.NewLine;
Cpdftype.VGlue {glen = 20.; gstretch = 0.};
Cpdftype.Font f] @ flatten lines)
in in
let original_pages = Pdfpage.pages_of_pagetree pdf in let original_pages = Pdfpage.pages_of_pagetree pdf in
let changes = let changes =

View File

@ -156,6 +156,10 @@ let make_resources fontobjnums =
Pdf.Dictionary Pdf.Dictionary
[("/Font", Pdf.Dictionary (map (fun fo -> ("/F" ^ string_of_int fo, Pdf.Indirect fo)) fontobjnums))] [("/Font", Pdf.Dictionary (map (fun fo -> ("/F" ^ string_of_int fo, Pdf.Indirect fo)) fontobjnums))]
let make_annotations annots =
if annots = [] then Pdf.Dictionary [] else
Pdf.Dictionary ["/Annots", Pdf.Array annots]
(* At this stage, just Font and Text and HGlue 0. and VGlue 0. and Newline and (* At this stage, just Font and Text and HGlue 0. and VGlue 0. and Newline and
NewPage elements. Split on NewPages, typeset each page, add font NewPage elements. Split on NewPages, typeset each page, add font
dictionaries. New page only dictionaries. New page only
@ -176,6 +180,8 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i =
let ops = ref [] in let ops = ref [] in
let fonts = ref [] in let fonts = ref [] in
let thispagefontnums = ref [] in let thispagefontnums = ref [] in
let thispageannotations = ref [] in
let thisdestrectangles = ref [] in
let pages = ref [] in let pages = ref [] in
let write_page () = let write_page () =
if !ops <> [] then if !ops <> [] then
@ -184,7 +190,7 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i =
Pdfpage.mediabox = Pdfpage.rectangle_of_paper papersize; Pdfpage.mediabox = Pdfpage.rectangle_of_paper papersize;
Pdfpage.resources = make_resources !thispagefontnums; Pdfpage.resources = make_resources !thispagefontnums;
Pdfpage.rotate = Pdfpage.Rotate0; Pdfpage.rotate = Pdfpage.Rotate0;
Pdfpage.rest = Pdf.Dictionary []} Pdfpage.rest = make_annotations !thispageannotations}
in in
pages := page :: !pages pages := page :: !pages
in in
@ -197,8 +203,12 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i =
::Pdfops.Op_BT ::Pdfops.Op_BT
::Pdfops.Op_cm (Pdftransform.mktranslate s.xpos (height -. s.ypos)) ::Pdfops.Op_cm (Pdftransform.mktranslate s.xpos (height -. s.ypos))
::Pdfops.Op_q ::Pdfops.Op_q
::!ops ::!ops;
(* If a destination, add the rectangle to the pile of rectangles for this annotation. *) (* If a destination, add the rectangle to the pile of rectangles for this annotation. *)
if s.dest <> None then
thisdestrectangles :=
let minx, miny = s.xpos, height -. s.ypos in
(minx, miny, minx +. width_of_string s.width_table (explode cps), miny +. s.fontsize)::!thisdestrectangles
| Font (f, fontsize) -> | Font (f, fontsize) ->
let name, objnum = let name, objnum =
match List.assoc_opt f !fonts with match List.assoc_opt f !fonts with
@ -209,6 +219,7 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i =
fonts := (f, num) :: !fonts; fonts := (f, num) :: !fonts;
(n, num) (n, num)
in in
s.width_table <- font_widths f fontsize;
s.font <- Some f; s.font <- Some f;
s.fontsize <- fontsize; s.fontsize <- fontsize;
thispagefontnums := objnum :: !thispagefontnums; thispagefontnums := objnum :: !thispagefontnums;
@ -223,6 +234,7 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i =
| NewPage -> | NewPage ->
write_page (); write_page ();
thispagefontnums := []; thispagefontnums := [];
thispageannotations := [];
ops := []; ops := [];
if s.font <> None then typeset_element (Font (unopt s.font, s.fontsize)); if s.font <> None then typeset_element (Font (unopt s.font, s.fontsize));
s.xpos <- lmargin; s.xpos <- lmargin;
@ -230,8 +242,18 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i =
| BeginDest dest -> | BeginDest dest ->
s.dest <- Some dest s.dest <- Some dest
| EndDest -> | EndDest ->
(* Collect together the rectangles for this annotation, merge? and output *) if !thisdestrectangles <> [] && s.dest <> None then
s.dest <- None let annot (minx, miny, maxx, maxy) =
Pdf.Dictionary
[("/Type", Pdf.Name "/Annot");
("/Subtype", Pdf.Name "/Link");
("/Border", Pdf.Array [Pdf.Real 0.; Pdf.Real 0.; Pdf.Real 1.]);
("/Rect", Pdf.Array [Pdf.Real minx; Pdf.Real miny; Pdf.Real maxx; Pdf.Real maxy]);
("/Dest", Pdfdest.pdfobject_of_destination (unopt s.dest))]
in
thispageannotations := map annot !thisdestrectangles @ !thispageannotations;
s.dest <- None;
thisdestrectangles := []
in in
iter typeset_element i; iter typeset_element i;
write_page (); write_page ();