mirror of
https://github.com/johnwhitington/cpdf-source.git
synced 2025-06-05 22:09:39 +02:00
Support PDF/UA annotations
This commit is contained in:
@ -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) ->
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
16
cpdftype.ml
16
cpdftype.ml
@ -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;
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user