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 () =
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 =
args.fontencoding <-
@ -2046,9 +2042,10 @@ let addopacity f =
let addsopacity f =
addop (Cpdfdraw.SOpacity f)
let embed_font () =
match args.font with
let embed_font_inner font =
match font with
| StandardFont f ->
Printf.printf "embed_font: StandardFont\n";
begin match args.embedstd14 with
| Some dirname ->
begin try
@ -2067,6 +2064,7 @@ let embed_font () =
| OtherFont f ->
ExistingNamedFont
| EmbeddedFont name ->
Printf.printf "embed_font: TTF\n";
try
let fontname, font = Hashtbl.find ttfs name in
args.fontname <- fontname;
@ -2074,24 +2072,32 @@ let embed_font () =
with
Not_found -> error (Printf.sprintf "Font %s not found" name)
let embed_font () = embed_font_inner args.font
let setfont f =
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
in
args.font <-
begin match Pdftext.standard_font_of_name ("/" ^ f) with
| Some x -> StandardFont x
| None ->
if f <> "" && hd (explode f) <> '/' then error "Custom font names must begin with /";
OtherFont (convert f)
end;
args.fontname <-
begin match Pdftext.standard_font_of_name ("/" ^ f) with
| Some x -> f
| None -> convert f
end;
(* If drawing, add the font pack as an op. *)
begin match args.op with Some Draw -> addop (Cpdfdraw.FontPack (f, embed_font (), null_hash ())) | _ -> () end
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 *)
match Pdfread.lex_name (Pdfio.input_of_string f) with Pdfgenlex.LexName s -> s | _ -> assert false
in
args.font <-
begin match Pdftext.standard_font_of_name ("/" ^ f) with
| Some x -> StandardFont x
| None ->
if f <> "" && hd (explode f) <> '/' then error "Custom font names must begin with /";
OtherFont (convert f)
end;
args.fontname <-
begin match Pdftext.standard_font_of_name ("/" ^ f) with
| Some x -> f
| None -> convert f
end;
(* If drawing, add the font pack as an op. *)
begin match args.op with Some Draw -> addop (Cpdfdraw.FontPack (f, embed_font (), null_hash ())) | _ -> () end
let loadttf n =
Printf.printf "loadttf: %s\n" n;
@ -2108,7 +2114,8 @@ let loadttf n =
name
(fontname, Cpdfembed.EmbedInfo {fontfile; fontname; encoding = args.fontencoding});
(* 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
_ -> error "addjpeg: could not load JPEG"
@ -2447,9 +2454,6 @@ and specs =
("-font-encoding",
Arg.String setfontttfencoding,
" Set the encoding for the TrueType font");
("-font-ttf",
Arg.String setfontttf,
" Use a TrueType font");
("-embed-std14",
Arg.String setembedstd14,
" Embed standard 14 fonts");

View File

@ -1,8 +1,6 @@
open Pdfutil
open Cpdferror
(* FIXME Use hashtbl.replace everywhere? *)
type colspec =
NoCol
| RGB of float * float * float
@ -84,7 +82,7 @@ type res =
form_xobjects : (string, (string * int)) Hashtbl.t; (* (name, (pdf name, objnum)) *)
mutable page_names : string list;
mutable time : Cpdfstrftime.t;
mutable current_fontpack : Cpdfembed.t;
mutable current_fontpack : string * Cpdfembed.t;
mutable current_fontpack_codepoints : (int, unit) Hashtbl.t;
mutable font_size : float;
mutable num : int}
@ -102,7 +100,7 @@ let empty_res () =
form_xobjects = null_hash ();
page_names = [];
time = Cpdfstrftime.dummy;
current_fontpack = default_fontpack;
current_fontpack = ("Times-Roman", default_fontpack);
current_fontpack_codepoints = null_hash ();
font_size = 12.;
num = 0}
@ -147,13 +145,14 @@ let process_specials pdf endpage filename bates batespad num page s =
Cpdfaddtext.process_text (res ()).time s pairs
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
(*Printf.printf "%i codepoints\n" (length codepoints);*)
Printf.printf "%i codepoints\n" (length codepoints);
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
(*Printf.printf "Collated of length %i\n" (length collated);*)
Printf.printf "Collated of length %i\n" (length collated);
flatten
(map
(fun l ->
@ -169,7 +168,7 @@ let extgstate kind v =
try Hashtbl.find (res ()).extgstates (kind, v) with
Not_found ->
let n = fresh_name "/G" in
Hashtbl.add (res ()).extgstates (kind, v) n;
Hashtbl.replace (res ()).extgstates (kind, v) n;
n
let read_resource pdf n res =
@ -247,46 +246,54 @@ let rec ops_of_drawop dryrun pdf endpage filename bates batespad num page = func
(res ()).page_names <- pdfname::(res ()).page_names;
[Pdfops.Op_Do pdfname]
| 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
| Opacity v -> [Pdfops.Op_gs (extgstate "/ca" v)]
| SOpacity v -> [Pdfops.Op_gs (extgstate "/CA" v)]
| FontPack (identifier, cpdffont, codepoints) ->
begin match Hashtbl.find fontpacks identifier with
| fontpack -> ()
(*Printf.printf "Cpdfdraw: using existing fontpack %s\n" identifier*)
| exception Not_found ->
(*Printf.printf "Cpdfdraw: storing new fontpack %s\n" identifier;*)
let fontpack =
match cpdffont with
| PreMadeFontPack fp -> fp
| EmbedInfo {fontfile; fontname; encoding} ->
let codepoints = map fst (list_of_hashtbl codepoints) in
if codepoints = [] then default_fontpack else
Cpdfembed.embed_truetype pdf ~fontfile ~fontname ~codepoints ~encoding
| ExistingNamedFont ->
error "-draw does not support using an existing named font"
in
Hashtbl.add fontpacks identifier (fontpack, codepoints);
let ns =
map
(fun font ->
try fst (Hashtbl.find (res ()).fonts font) with
Not_found ->
let o = if dryrun then 0 else Pdftext.write_font pdf font in
let n = fresh_name "/F" in
Hashtbl.add (res ()).fonts font (n, o);
n)
(fst fontpack)
Printf.printf "FontPack op: %s\n" identifier;
let fontpack =
match Hashtbl.find fontpacks identifier with
| (fontpack, _) ->
Printf.printf "Cpdfdraw FontPack op: using existing fontpack %s\n" identifier;
fontpack
| exception Not_found ->
Printf.printf "Cpdfdraw FontPack op: storing new fontpack %s\n" identifier;
let fontpack =
match cpdffont with
| PreMadeFontPack fp ->
Printf.printf "it's a pre-made font pack\n";
fp
| EmbedInfo {fontfile; fontname; encoding} ->
let codepoints = map fst (list_of_hashtbl codepoints) in
Printf.printf "%i codepoints to embed\n" (length codepoints);
if codepoints = [] then default_fontpack else
Cpdfembed.embed_truetype pdf ~fontfile ~fontname ~codepoints ~encoding
| ExistingNamedFont ->
error "-draw does not support using an existing named font"
in
(res ()).page_names <- ns @ (res ()).page_names
end;
[]
Hashtbl.replace fontpacks identifier (fontpack, codepoints);
fontpack
in
let ns =
map
(fun font ->
try fst (Hashtbl.find (res ()).fonts font) with
Not_found ->
let o = if dryrun then 0 else Pdftext.write_font pdf font in
let n = fresh_name "/F" in
Printf.printf "Adding font %s as %s\n" identifier n;
Hashtbl.replace (res ()).fonts font (n, o);
n)
(fst fontpack)
in
(res ()).page_names <- ns @ (res ()).page_names;
[]
| 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
(res ()).current_fontpack <- fontpack;
(res ()).current_fontpack <- (identifier, fontpack);
if dryrun then (res ()).current_fontpack_codepoints <- codepoints;
(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)}
in
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 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);
restore_whole_stack r;
Hashtbl.clear fontpacks;
Printf.printf "--------------------------\n";
Some (ops_of_drawops false pdf endpage filename bates batespad 0 (hd pages) drawops)
end
in