mixed ttf fonts in -draw

This commit is contained in:
John Whitington 2023-07-17 13:38:35 +01:00
parent 8ded8853f2
commit 951a947f43
2 changed files with 81 additions and 69 deletions

View File

@ -1728,10 +1728,6 @@ let setidironlypdfs () =
let setnowarnrotate () = let setnowarnrotate () =
args.no_warn_rotate <- true args.no_warn_rotate <- true
let setfontttf s =
let fontname, _ = Hashtbl.find ttfs s in
args.font <- EmbeddedFont s;
args.fontname <- fontname
let setfontttfencoding s = let setfontttfencoding s =
args.fontencoding <- args.fontencoding <-
@ -2046,9 +2042,10 @@ let addopacity f =
let addsopacity f = let addsopacity f =
addop (Cpdfdraw.SOpacity f) addop (Cpdfdraw.SOpacity f)
let embed_font () = let embed_font_inner font =
match args.font with match font with
| StandardFont f -> | StandardFont f ->
Printf.printf "embed_font: StandardFont\n";
begin match args.embedstd14 with begin match args.embedstd14 with
| Some dirname -> | Some dirname ->
begin try begin try
@ -2067,6 +2064,7 @@ let embed_font () =
| OtherFont f -> | OtherFont f ->
ExistingNamedFont ExistingNamedFont
| EmbeddedFont name -> | EmbeddedFont name ->
Printf.printf "embed_font: TTF\n";
try try
let fontname, font = Hashtbl.find ttfs name in let fontname, font = Hashtbl.find ttfs name in
args.fontname <- fontname; args.fontname <- fontname;
@ -2074,7 +2072,15 @@ let embed_font () =
with with
Not_found -> error (Printf.sprintf "Font %s not found" name) Not_found -> error (Printf.sprintf "Font %s not found" name)
let embed_font () = embed_font_inner args.font
let setfont f = let setfont f =
try
let fontname, _ = Hashtbl.find ttfs f in
args.font <- EmbeddedFont f;
args.fontname <- fontname
with
Not_found ->
let convert f = (* convert from written PDF representation to internal PDF string e.g # sequences *) let convert f = (* convert from written PDF representation to internal PDF string e.g # sequences *)
match Pdfread.lex_name (Pdfio.input_of_string f) with Pdfgenlex.LexName s -> s | _ -> assert false match Pdfread.lex_name (Pdfio.input_of_string f) with Pdfgenlex.LexName s -> s | _ -> assert false
in in
@ -2108,7 +2114,8 @@ let loadttf n =
name name
(fontname, Cpdfembed.EmbedInfo {fontfile; fontname; encoding = args.fontencoding}); (fontname, Cpdfembed.EmbedInfo {fontfile; fontname; encoding = args.fontencoding});
(* If drawing, add the font pack as an op. *) (* If drawing, add the font pack as an op. *)
begin match args.op with Some Draw -> addop (Cpdfdraw.FontPack (fontname, embed_font (), null_hash ())) | _ -> () end begin match args.op with
Some Draw -> addop (Cpdfdraw.FontPack (fontname, embed_font_inner (EmbeddedFont name), null_hash ())) | _ -> () end
with with
_ -> error "addjpeg: could not load JPEG" _ -> error "addjpeg: could not load JPEG"
@ -2447,9 +2454,6 @@ and specs =
("-font-encoding", ("-font-encoding",
Arg.String setfontttfencoding, Arg.String setfontttfencoding,
" Set the encoding for the TrueType font"); " Set the encoding for the TrueType font");
("-font-ttf",
Arg.String setfontttf,
" Use a TrueType font");
("-embed-std14", ("-embed-std14",
Arg.String setembedstd14, Arg.String setembedstd14,
" Embed standard 14 fonts"); " Embed standard 14 fonts");

View File

@ -1,8 +1,6 @@
open Pdfutil open Pdfutil
open Cpdferror open Cpdferror
(* FIXME Use hashtbl.replace everywhere? *)
type colspec = type colspec =
NoCol NoCol
| RGB of float * float * float | RGB of float * float * float
@ -84,7 +82,7 @@ type res =
form_xobjects : (string, (string * int)) Hashtbl.t; (* (name, (pdf name, objnum)) *) form_xobjects : (string, (string * int)) Hashtbl.t; (* (name, (pdf name, objnum)) *)
mutable page_names : string list; mutable page_names : string list;
mutable time : Cpdfstrftime.t; mutable time : Cpdfstrftime.t;
mutable current_fontpack : Cpdfembed.t; mutable current_fontpack : string * Cpdfembed.t;
mutable current_fontpack_codepoints : (int, unit) Hashtbl.t; mutable current_fontpack_codepoints : (int, unit) Hashtbl.t;
mutable font_size : float; mutable font_size : float;
mutable num : int} mutable num : int}
@ -102,7 +100,7 @@ let empty_res () =
form_xobjects = null_hash (); form_xobjects = null_hash ();
page_names = []; page_names = [];
time = Cpdfstrftime.dummy; time = Cpdfstrftime.dummy;
current_fontpack = default_fontpack; current_fontpack = ("Times-Roman", default_fontpack);
current_fontpack_codepoints = null_hash (); current_fontpack_codepoints = null_hash ();
font_size = 12.; font_size = 12.;
num = 0} num = 0}
@ -147,13 +145,14 @@ let process_specials pdf endpage filename bates batespad num page s =
Cpdfaddtext.process_text (res ()).time s pairs Cpdfaddtext.process_text (res ()).time s pairs
let runs_of_utf8 s = let runs_of_utf8 s =
let fontpack = (res ()).current_fontpack in let identifier, fontpack = (res ()).current_fontpack in
Printf.printf "runs_of_utf8: %s\n" identifier;
let codepoints = Pdftext.codepoints_of_utf8 s in let codepoints = Pdftext.codepoints_of_utf8 s in
(*Printf.printf "%i codepoints\n" (length codepoints);*) Printf.printf "%i codepoints\n" (length codepoints);
let triples = option_map (Cpdfembed.get_char fontpack) codepoints in let triples = option_map (Cpdfembed.get_char fontpack) codepoints in
(*Printf.printf "%i triples\n" (length triples);*) Printf.printf "%i triples\n" (length triples);
let collated = Cpdfembed.collate_runs triples in let collated = Cpdfembed.collate_runs triples in
(*Printf.printf "Collated of length %i\n" (length collated);*) Printf.printf "Collated of length %i\n" (length collated);
flatten flatten
(map (map
(fun l -> (fun l ->
@ -169,7 +168,7 @@ let extgstate kind v =
try Hashtbl.find (res ()).extgstates (kind, v) with try Hashtbl.find (res ()).extgstates (kind, v) with
Not_found -> Not_found ->
let n = fresh_name "/G" in let n = fresh_name "/G" in
Hashtbl.add (res ()).extgstates (kind, v) n; Hashtbl.replace (res ()).extgstates (kind, v) n;
n n
let read_resource pdf n res = let read_resource pdf n res =
@ -247,28 +246,36 @@ let rec ops_of_drawop dryrun pdf endpage filename bates batespad num page = func
(res ()).page_names <- pdfname::(res ()).page_names; (res ()).page_names <- pdfname::(res ()).page_names;
[Pdfops.Op_Do pdfname] [Pdfops.Op_Do pdfname]
| ImageXObject (s, obj) -> | ImageXObject (s, obj) ->
Hashtbl.add (res ()).images s (fresh_name "/I", Pdf.addobj pdf obj); Hashtbl.replace (res ()).images s (fresh_name "/I", Pdf.addobj pdf obj);
[] []
| NewPage -> Pdfe.log ("NewPage remaining in graphic stream"); assert false | NewPage -> Pdfe.log ("NewPage remaining in graphic stream"); assert false
| Opacity v -> [Pdfops.Op_gs (extgstate "/ca" v)] | Opacity v -> [Pdfops.Op_gs (extgstate "/ca" v)]
| SOpacity v -> [Pdfops.Op_gs (extgstate "/CA" v)] | SOpacity v -> [Pdfops.Op_gs (extgstate "/CA" v)]
| FontPack (identifier, cpdffont, codepoints) -> | FontPack (identifier, cpdffont, codepoints) ->
begin match Hashtbl.find fontpacks identifier with Printf.printf "FontPack op: %s\n" identifier;
| fontpack -> () let fontpack =
(*Printf.printf "Cpdfdraw: using existing fontpack %s\n" identifier*) match Hashtbl.find fontpacks identifier with
| (fontpack, _) ->
Printf.printf "Cpdfdraw FontPack op: using existing fontpack %s\n" identifier;
fontpack
| exception Not_found -> | exception Not_found ->
(*Printf.printf "Cpdfdraw: storing new fontpack %s\n" identifier;*) Printf.printf "Cpdfdraw FontPack op: storing new fontpack %s\n" identifier;
let fontpack = let fontpack =
match cpdffont with match cpdffont with
| PreMadeFontPack fp -> fp | PreMadeFontPack fp ->
Printf.printf "it's a pre-made font pack\n";
fp
| EmbedInfo {fontfile; fontname; encoding} -> | EmbedInfo {fontfile; fontname; encoding} ->
let codepoints = map fst (list_of_hashtbl codepoints) in let codepoints = map fst (list_of_hashtbl codepoints) in
Printf.printf "%i codepoints to embed\n" (length codepoints);
if codepoints = [] then default_fontpack else if codepoints = [] then default_fontpack else
Cpdfembed.embed_truetype pdf ~fontfile ~fontname ~codepoints ~encoding Cpdfembed.embed_truetype pdf ~fontfile ~fontname ~codepoints ~encoding
| ExistingNamedFont -> | ExistingNamedFont ->
error "-draw does not support using an existing named font" error "-draw does not support using an existing named font"
in in
Hashtbl.add fontpacks identifier (fontpack, codepoints); Hashtbl.replace fontpacks identifier (fontpack, codepoints);
fontpack
in
let ns = let ns =
map map
(fun font -> (fun font ->
@ -276,17 +283,17 @@ let rec ops_of_drawop dryrun pdf endpage filename bates batespad num page = func
Not_found -> Not_found ->
let o = if dryrun then 0 else Pdftext.write_font pdf font in let o = if dryrun then 0 else Pdftext.write_font pdf font in
let n = fresh_name "/F" in let n = fresh_name "/F" in
Hashtbl.add (res ()).fonts font (n, o); Printf.printf "Adding font %s as %s\n" identifier n;
Hashtbl.replace (res ()).fonts font (n, o);
n) n)
(fst fontpack) (fst fontpack)
in in
(res ()).page_names <- ns @ (res ()).page_names (res ()).page_names <- ns @ (res ()).page_names;
end;
[] []
| Font (identifier, size) -> | Font (identifier, size) ->
(*Printf.printf "Changing to stored font %s\n" identifier;*) Printf.printf "Cpdfdraw Font op: Changing to stored font %s\n" identifier;
let fontpack, codepoints = Hashtbl.find fontpacks identifier in let fontpack, codepoints = Hashtbl.find fontpacks identifier in
(res ()).current_fontpack <- fontpack; (res ()).current_fontpack <- (identifier, fontpack);
if dryrun then (res ()).current_fontpack_codepoints <- codepoints; if dryrun then (res ()).current_fontpack_codepoints <- codepoints;
(res ()).font_size <- size; (res ()).font_size <- size;
[] []
@ -327,7 +334,7 @@ and create_form_xobject dryrun a b c d pdf endpage filename bates batespad num p
Pdf.Got data)} Pdf.Got data)}
in in
respop (); respop ();
Hashtbl.add (res ()).form_xobjects n (fresh_name "/X", (if dryrun then 0 else Pdf.addobj pdf obj)) Hashtbl.replace (res ()).form_xobjects n (fresh_name "/X", (if dryrun then 0 else Pdf.addobj pdf obj))
let minimum_resource_number pdf range = let minimum_resource_number pdf range =
let pages = Pdfpage.pages_of_pagetree pdf in let pages = Pdfpage.pages_of_pagetree pdf in
@ -381,6 +388,7 @@ let draw_single ~fast ~underneath ~filename ~bates ~batespad fast range pdf draw
ignore (ops_of_drawops true pdf endpage filename bates batespad 0 (hd pages) drawops); ignore (ops_of_drawops true pdf endpage filename bates batespad 0 (hd pages) drawops);
restore_whole_stack r; restore_whole_stack r;
Hashtbl.clear fontpacks; Hashtbl.clear fontpacks;
Printf.printf "--------------------------\n";
Some (ops_of_drawops false pdf endpage filename bates batespad 0 (hd pages) drawops) Some (ops_of_drawops false pdf endpage filename bates batespad 0 (hd pages) drawops)
end end
in in