diff --git a/Makefile b/Makefile index 3445c27..63a0f44 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,9 @@ NONDOC = cpdfyojson cpdfxmlm cpdfutil DOC = cpdfunicodedata cpdferror cpdfdebug cpdfjson cpdfstrftime cpdfcoord \ cpdfattach cpdfpagespec cpdfposition cpdfpresent cpdfmetadata \ cpdfbookmarks cpdfpage cpdfaddtext cpdfimage cpdffont cpdftype \ - cpdftexttopdf cpdftoc cpdfpad cpdfocg cpdfsqueeze cpdfdraft cpdfspot \ + cpdfpad cpdfocg cpdfsqueeze cpdfdraft cpdfspot \ cpdfpagelabels cpdfcreate cpdfannot cpdfxobject cpdfimpose cpdftweak \ - cpdftruetype cpdfembed \ + cpdftruetype cpdfembed cpdftexttopdf cpdftoc\ cpdfcommand MODS = $(NONDOC) $(DOC) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index f7676a0..bb906aa 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -3973,27 +3973,29 @@ let go () = Cpdffont.print_font_table pdf fontname args.copyfontpage | Some TableOfContents -> let pdf = get_single_pdf args.op false in - let font = + let font, embedinfo = match args.font with - | StandardFont f -> Pdftext.StandardFont (f, args.fontencoding) + | StandardFont f -> (Pdftext.StandardFont (f, args.fontencoding), None) | FontToEmbed fontfile -> - Cpdfembed.embed_truetype pdf ~fontfile ~fontname:args.fontname ~codepoints:[] ~encoding:args.fontencoding + Cpdfembed.embed_truetype pdf ~fontfile ~fontname:args.fontname ~codepoints:[] ~encoding:args.fontencoding, + (Some (pdf, fontfile, args.fontname, args.fontencoding)) | _ -> error "TOC: not a standard or embedded font" in - let pdf = Cpdftoc.typeset_table_of_contents ~font ~fontsize:args.fontsize ~title:args.toc_title ~bookmark:args.toc_bookmark pdf in + let pdf = Cpdftoc.typeset_table_of_contents ?embedinfo ~font ~fontsize:args.fontsize ~title:args.toc_title ~bookmark:args.toc_bookmark pdf in write_pdf false pdf | Some (Typeset filename) -> let text = Pdfio.bytes_of_input_channel (open_in filename) in let pdf = Pdf.empty () in - let font = + let font, embedinfo = match args.font with - | StandardFont f -> Pdftext.StandardFont (f, args.fontencoding) + | StandardFont f -> (Pdftext.StandardFont (f, args.fontencoding), None) | FontToEmbed fontfile -> - Cpdfembed.embed_truetype pdf ~fontfile ~fontname:args.fontname ~codepoints:[] ~encoding:args.fontencoding + Cpdfembed.embed_truetype pdf ~fontfile ~fontname:args.fontname ~codepoints:[] ~encoding:args.fontencoding, + (Some (pdf, fontfile, args.fontname, args.fontencoding)) | _ -> error "text to PDF: not a standard or embedded font" in let pdf = - Cpdftexttopdf.typeset ~pdf:pdf ~papersize:args.createpdf_pagesize ~font ~fontsize:args.fontsize text + Cpdftexttopdf.typeset ?embedinfo ~papersize:args.createpdf_pagesize ~font ~fontsize:args.fontsize text in write_pdf false pdf diff --git a/cpdftexttopdf.ml b/cpdftexttopdf.ml index 4ff7664..cc45a23 100644 --- a/cpdftexttopdf.ml +++ b/cpdftexttopdf.ml @@ -30,21 +30,26 @@ let rec of_utf8_with_newlines used charcode_extractor t = (* The optional pdf argument is for providing a pre-embedded font - this will be removed when we re-embed subsetted? *) -let typeset ?pdf ~papersize ~font ~fontsize text = +let typeset ?embedinfo ~papersize ~font ~fontsize text = let charcode_extractor = Pdftext.charcode_extractor_of_font_real font in - let pdf = match pdf with None -> Pdf.empty () | Some pdf -> pdf in + let pdf = match embedinfo with None -> Pdf.empty () | Some (pdf, _, _, _) -> pdf in let margin = Pdfunits.convert 72. (Pdfpaper.unit papersize) (Pdfunits.PdfPoint) (Pdfpaper.width papersize) /. 15. in let used = null_hash () in + let instrs = of_utf8_with_newlines used charcode_extractor (Pdfio.string_of_bytes text) in + let codepoints = map fst (list_of_hashtbl used) in + let font = + match embedinfo with + | None -> font + | Some (pdf, fontfile, fontname, encoding) -> + Cpdfembed.embed_truetype pdf ~fontfile ~fontname ~codepoints ~encoding + in let pages = Cpdftype.typeset margin margin margin margin papersize pdf - ([Cpdftype.Font (font, fontsize); Cpdftype.BeginDocument] @ - of_utf8_with_newlines used charcode_extractor (Pdfio.string_of_bytes text)) + ([Cpdftype.Font (font, fontsize); Cpdftype.BeginDocument] @ instrs) in - let codes = map fst (list_of_hashtbl used) in - Printf.printf "%i codes used\n" (length codes); let pdf, pageroot = Pdfpage.add_pagetree pages pdf in Pdfpage.add_root pageroot [] pdf diff --git a/cpdftexttopdf.mli b/cpdftexttopdf.mli index 4522929..b0855a8 100644 --- a/cpdftexttopdf.mli +++ b/cpdftexttopdf.mli @@ -1,4 +1,4 @@ (** Text to PDF *) (** Typeset a text file as a PDF. *) -val typeset : ?pdf:Pdf.t -> papersize:Pdfpaper.t -> font:Pdftext.font -> fontsize:float -> Pdfio.bytes -> Pdf.t +val typeset : ?embedinfo:(Pdf.t * Pdfio.bytes * string * Pdftext.encoding) -> papersize:Pdfpaper.t -> font:Pdftext.font -> fontsize:float -> Pdfio.bytes -> Pdf.t diff --git a/cpdftoc.ml b/cpdftoc.ml index 63d7665..76b2050 100644 --- a/cpdftoc.ml +++ b/cpdftoc.ml @@ -39,11 +39,11 @@ let shorten_text widths l t = (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 = +let typeset_table_of_contents ?embedinfo ~font ~fontsize ~title ~bookmark 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, fs = (font, fontsize) in - let big = (font, fontsize *. 2.) in + let _, bfs as big = (font, fontsize *. 2.) in let firstpage = hd (Pdfpage.pages_of_pagetree pdf) in let width, firstpage_papersize, pmaxx, pmaxy, margin = let width, height, xmax, ymax = @@ -106,10 +106,17 @@ let typeset_table_of_contents ~font ~fontsize ~title ~bookmark pdf = | None -> (margin, margin, margin, margin) | Some (cminx, cminy, cmaxx, cmaxy) -> (cminx +. margin, (pmaxx -. cmaxx) +. margin, cminy +. margin, (pmaxy -. cmaxy) +. margin) + in + let codepoints = [] in + let font = + match embedinfo with + | None -> font + | Some (pdf, fontfile, fontname, encoding) -> + Cpdfembed.embed_truetype pdf ~fontfile ~fontname ~codepoints ~encoding in Cpdftype.typeset lm rm tm bm firstpage_papersize pdf - ([Cpdftype.Font big; Cpdftype.BeginDocument] @ title @ - [Cpdftype.Font (f, fs)] @ flatten lines) + ([Cpdftype.Font (font, bfs); Cpdftype.BeginDocument] @ title @ + [Cpdftype.Font (font, fs)] @ flatten lines) in let toc_pages = match firstpage_cropbox with diff --git a/cpdftoc.mli b/cpdftoc.mli index f549ccb..49b449e 100644 --- a/cpdftoc.mli +++ b/cpdftoc.mli @@ -1,4 +1,4 @@ (** Table of contents *) (** Typeset a table of contents and prepend to the document. *) -val typeset_table_of_contents : font:Pdftext.font -> fontsize:float -> title:string -> bookmark:bool -> Pdf.t -> Pdf.t +val typeset_table_of_contents : ?embedinfo:(Pdf.t * Pdfio.bytes * string * Pdftext.encoding) -> font:Pdftext.font -> fontsize:float -> title:string -> bookmark:bool -> Pdf.t -> Pdf.t