From e5074c20a37ce5606c36b7372799633b63d0f99f Mon Sep 17 00:00:00 2001 From: John Whitington Date: Tue, 23 Nov 2021 14:20:38 -0800 Subject: [PATCH] more --- cpdfcommand.ml | 10 +++++++--- cpdftype.ml | 30 ++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 1169817..e7fac2e 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -3,7 +3,7 @@ let demo = false let noncomp = false let major_version = 2 let minor_version = 5 -let version_date = "(devel, 15th Nov 2021)" +let version_date = "(devel, 22nd Nov 2021)" open Pdfutil open Pdfio @@ -2953,6 +2953,7 @@ let typeset_table_of_contents pdf = let marks = Pdfmarks.read_bookmarks pdf in 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 big = (Pdftext.StandardFont (Pdftext.Courier, Pdftext.WinAnsiEncoding), 20.) in let firstpage = hd (Pdfpage.pages_of_pagetree pdf) in let firstpage_papersize = let width, height = @@ -2971,10 +2972,13 @@ let typeset_table_of_contents pdf = Cpdftype.NewLine]) (Pdfmarks.read_bookmarks pdf) in - print_string (Cpdftype.to_string (flatten lines)); let toc_pages = 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 let original_pages = Pdfpage.pages_of_pagetree pdf in let changes = diff --git a/cpdftype.ml b/cpdftype.ml index d4d3d3a..3bd6275 100644 --- a/cpdftype.ml +++ b/cpdftype.ml @@ -156,6 +156,10 @@ let make_resources fontobjnums = Pdf.Dictionary [("/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 NewPage elements. Split on NewPages, typeset each page, add font dictionaries. New page only @@ -176,6 +180,8 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i = let ops = ref [] in let fonts = ref [] in let thispagefontnums = ref [] in + let thispageannotations = ref [] in + let thisdestrectangles = ref [] in let pages = ref [] in let write_page () = if !ops <> [] then @@ -184,7 +190,7 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i = Pdfpage.mediabox = Pdfpage.rectangle_of_paper papersize; Pdfpage.resources = make_resources !thispagefontnums; Pdfpage.rotate = Pdfpage.Rotate0; - Pdfpage.rest = Pdf.Dictionary []} + Pdfpage.rest = make_annotations !thispageannotations} in pages := page :: !pages in @@ -197,8 +203,12 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i = ::Pdfops.Op_BT ::Pdfops.Op_cm (Pdftransform.mktranslate s.xpos (height -. s.ypos)) ::Pdfops.Op_q - ::!ops + ::!ops; (* 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) -> let name, objnum = match List.assoc_opt f !fonts with @@ -209,6 +219,7 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i = fonts := (f, num) :: !fonts; (n, num) in + s.width_table <- font_widths f fontsize; s.font <- Some f; s.fontsize <- fontsize; thispagefontnums := objnum :: !thispagefontnums; @@ -223,6 +234,7 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i = | NewPage -> write_page (); thispagefontnums := []; + thispageannotations := []; ops := []; if s.font <> None then typeset_element (Font (unopt s.font, s.fontsize)); s.xpos <- lmargin; @@ -230,8 +242,18 @@ let typeset lmargin rmargin tmargin bmargin papersize pdf i = | BeginDest dest -> s.dest <- Some dest | EndDest -> - (* Collect together the rectangles for this annotation, merge? and output *) - s.dest <- None + if !thisdestrectangles <> [] && s.dest <> None then + 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 iter typeset_element i; write_page ();