Support PDF/UA annotations

This commit is contained in:
John Whitington
2025-02-26 16:37:27 +00:00
parent d4563d2efc
commit 5c58029844
5 changed files with 17 additions and 12 deletions

View File

@ -4783,7 +4783,8 @@ let go () =
let cpdffont = embed_font () in
let pdf =
Cpdftoc.typeset_table_of_contents
~font:cpdffont ~fontsize:args.fontsize ~title:args.toc_title ~bookmark:args.toc_bookmark ~dotleader:args.dot_leader pdf
~font:cpdffont ~fontsize:args.fontsize ~title:args.toc_title
~bookmark:args.toc_bookmark ~dotleader:args.dot_leader ~process_struct_tree:args.process_struct_trees pdf
in
write_pdf false pdf
| Some (Typeset filename) ->

View File

@ -106,7 +106,7 @@ let make_dots space fontpack fontsize =
(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 ~dotleader pdf =
let typeset_table_of_contents ~font ~fontsize ~title ~bookmark ~dotleader ~process_struct_tree pdf =
Hashtbl.clear width_table_cache;
let marks = Pdfmarks.read_bookmarks pdf in
if marks = [] then (Pdfe.log "No bookmarks, not making table of contents\n"; pdf) else
@ -158,7 +158,7 @@ let typeset_table_of_contents ~font ~fontsize ~title ~bookmark ~dotleader pdf =
then make_dots space fontpack fontsize
else [Cpdftype.HGlue space]
in
[Cpdftype.BeginDest mark.Pdfmarks.target; Cpdftype.HGlue indent] @ textruns @ leader @ labelruns
[Cpdftype.BeginDest (mark.Pdfmarks.target, Some mark.Pdfmarks.text); Cpdftype.HGlue indent] @ textruns @ leader @ labelruns
@ [Cpdftype.EndDest; Cpdftype.NewLine])
(Pdfmarks.read_bookmarks pdf)
in
@ -181,7 +181,7 @@ let typeset_table_of_contents ~font ~fontsize ~title ~bookmark ~dotleader pdf =
let firstfont =
hd (keep (function Cpdftype.Font _ -> true | _ -> false) (title @ flatten lines))
in
Cpdftype.typeset ~process_struct_tree:false lm rm tm bm firstpage_papersize pdf
Cpdftype.typeset ~process_struct_tree lm rm tm bm firstpage_papersize pdf
([firstfont; Cpdftype.BeginDocument] @ title @ flatten lines)
in
let toc_pages =

View File

@ -1,4 +1,4 @@
(** Table of contents *)
(** Typeset a table of contents and prepend to the document. *)
val typeset_table_of_contents : font:Cpdfembed.cpdffont -> fontsize:float -> title:string -> bookmark:bool -> dotleader:bool -> Pdf.t -> Pdf.t
val typeset_table_of_contents : font:Cpdfembed.cpdffont -> fontsize:float -> title:string -> bookmark:bool -> dotleader:bool -> process_struct_tree:bool -> Pdf.t -> Pdf.t

View File

@ -15,7 +15,7 @@ type element =
| NewLine
| NewPage
| Font of string * Pdftext.font * float
| BeginDest of Pdfdest.t
| BeginDest of Pdfdest.t * string option
| EndDest
| BeginDocument
| Tag of string * int
@ -45,7 +45,7 @@ type state =
mutable width_table : float array; (* Widths for charcodes 0..255 *)
mutable xpos : float;
mutable ypos : float;
mutable dest : Pdfdest.t option}
mutable dest : (Pdfdest.t * string option) option}
let width_table_cache = null_hash ()
@ -232,7 +232,8 @@ let make_resources fontobjnums =
let make_annotations pdf annots =
if annots = [] then Pdf.Dictionary [] else
Pdf.Dictionary ["/Annots", Pdf.Array (map (function a -> Pdf.Indirect (Pdf.addobj pdf a)) annots)]
Pdf.Dictionary ["/Annots", Pdf.Array (map (function a -> Pdf.Indirect (Pdf.addobj pdf a)) annots);
"/Tabs", Pdf.Name "/S"]
let rec number_tags n = function
| Tag (s, _)::t -> Tag (s, n)::number_tags (n + 1) t
@ -329,17 +330,20 @@ let typeset ~process_struct_tree lmargin rmargin tmargin bmargin papersize pdf i
s.ypos <- tmargin +. s.fontsize
| BeginDocument ->
s.ypos <- tmargin +. s.fontsize
| BeginDest dest ->
s.dest <- Some dest
| BeginDest (dest, contents) ->
s.dest <- Some (dest, contents)
| EndDest ->
if !thisdestrectangles <> [] && s.dest <> None then
let annot (minx, miny, maxx, maxy) =
let dest, contents = unopt s.dest in
Pdf.Dictionary
((match contents with None -> [] | Some s -> [("/Contents", Pdf.String s)])
@
[("/Type", Pdf.Name "/Annot");
("/Subtype", Pdf.Name "/Link");
("/Border", Pdf.Array [Pdf.Real 0.; Pdf.Real 0.; Pdf.Real 0.]);
("/Rect", Pdf.Array [Pdf.Real minx; Pdf.Real miny; Pdf.Real maxx; Pdf.Real maxy]);
("/Dest", Pdfdest.pdfobject_of_destination (unopt s.dest))]
("/Dest", Pdfdest.pdfobject_of_destination dest)])
in
thispageannotations := map annot !thisdestrectangles @ !thispageannotations;
s.dest <- None;

View File

@ -6,7 +6,7 @@ type element =
| NewLine
| NewPage
| Font of string * Pdftext.font * float
| BeginDest of Pdfdest.t
| BeginDest of Pdfdest.t * string option
| EndDest
| BeginDocument
| Tag of string * int